Compare commits

...

9 Commits

Author SHA1 Message Date
Sasha
cbee9c4c4a forgot upsertRow/insertArrays 2025-06-03 01:21:13 +03:00
Sasha
ba011b8933 even more (upsertRow/*) 2025-06-03 01:19:33 +03:00
Sasha
193c051c67 Merge branch 'main' of github.com:payloadcms/payload into chore/strict-drizzle 2025-06-03 01:11:44 +03:00
Sasha
e7749468c2 even even more 2025-06-03 01:09:59 +03:00
Sasha
115af04406 even more 2025-06-03 00:59:53 +03:00
Sasha
ec115c6eca more 2025-06-03 00:23:38 +03:00
Sasha
4b3f1b9c92 Merge branch 'main' of github.com:payloadcms/payload into chore/strict-drizzle 2025-06-02 17:40:24 +03:00
Sasha
180ef3a49d more 2025-03-11 19:08:24 +02:00
Sasha
1066b434c3 chore(drizzle): enable strict true 2025-03-11 18:12:47 +02:00
74 changed files with 449 additions and 321 deletions

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",
@@ -64,6 +64,7 @@
"@libsql/client": "0.14.0",
"@payloadcms/eslint-config": "workspace:*",
"@types/pg": "8.10.2",
"@types/prompts": "^2.4.5",
"@types/to-snake-case": "1.0.0",
"payload": "workspace:*"
},

View File

@@ -1,19 +1,16 @@
import type { Count, SanitizedCollectionConfig } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { Count } from 'payload'
import type { DrizzleAdapter } from './types.js'
import { buildQuery } from './queries/buildQuery.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const count: Count = async function count(
this: DrizzleAdapter,
{ collection, locale, req, where: whereArg },
{ collection: collectionSlug, locale, req, where: whereArg = {} },
) {
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const tableName = this.tableNameMap.get(toSnakeCase(collectionConfig.slug))
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
const db = await getTransaction(this, req)

View File

@@ -1,24 +1,18 @@
import type { CountGlobalVersions, SanitizedGlobalConfig } from 'payload'
import type { CountGlobalVersions } from 'payload'
import { buildVersionGlobalFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { buildQuery } from './queries/buildQuery.js'
import { getGlobal } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const countGlobalVersions: CountGlobalVersions = async function countGlobalVersions(
this: DrizzleAdapter,
{ global, locale, req, where: whereArg },
{ global: globalSlug, locale, req, where: whereArg = {} },
) {
const globalConfig: SanitizedGlobalConfig = this.payload.globals.config.find(
({ slug }) => slug === global,
)
const tableName = this.tableNameMap.get(
`_${toSnakeCase(globalConfig.slug)}${this.versionsSuffix}`,
)
const { globalConfig, tableName } = getGlobal({ adapter: this, globalSlug, versions: true })
const db = await getTransaction(this, req)

View File

@@ -1,22 +1,22 @@
import type { CountVersions, SanitizedCollectionConfig } from 'payload'
import type { CountVersions } from 'payload'
import { buildVersionCollectionFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { buildQuery } from './queries/buildQuery.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const countVersions: CountVersions = async function countVersions(
this: DrizzleAdapter,
{ collection, locale, req, where: whereArg },
{ collection: collectionSlug, locale, req, where: whereArg = {} },
) {
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const tableName = this.tableNameMap.get(
`_${toSnakeCase(collectionConfig.slug)}${this.versionsSuffix}`,
)
const { collectionConfig, tableName } = getCollection({
adapter: this,
collectionSlug,
versions: true,
})
const db = await getTransaction(this, req)

View File

@@ -1,10 +1,9 @@
import type { Create } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { upsertRow } from './upsertRow/index.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const create: Create = async function create(
@@ -12,15 +11,13 @@ export const create: Create = async function create(
{ collection: collectionSlug, data, req, returning, select },
) {
const db = await getTransaction(this, req)
const collection = this.payload.collections[collectionSlug].config
const tableName = this.tableNameMap.get(toSnakeCase(collection.slug))
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
const result = await upsertRow({
adapter: this,
data,
db,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
ignoreResult: returning === false,
operation: 'create',
req,

View File

@@ -1,20 +1,17 @@
import type { CreateGlobalArgs } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { upsertRow } from './upsertRow/index.js'
import { getGlobal } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export async function createGlobal<T extends Record<string, unknown>>(
this: DrizzleAdapter,
{ slug, data, req, returning }: CreateGlobalArgs,
{ slug: globalSlug, data, req, returning }: CreateGlobalArgs,
): Promise<T> {
const db = await getTransaction(this, req)
const globalConfig = this.payload.globals.config.find((config) => config.slug === slug)
const tableName = this.tableNameMap.get(toSnakeCase(globalConfig.slug))
const { globalConfig, tableName } = getGlobal({ adapter: this, globalSlug })
data.createdAt = new Date().toISOString()
@@ -30,10 +27,10 @@ export async function createGlobal<T extends Record<string, unknown>>(
})
if (returning === false) {
return null
return null as unknown as T
}
result.globalType = slug
result.globalType = globalSlug
return result
}

View File

@@ -2,11 +2,11 @@ import type { CreateGlobalVersionArgs, TypeWithID, TypeWithVersion } from 'paylo
import { sql } from 'drizzle-orm'
import { buildVersionGlobalFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { upsertRow } from './upsertRow/index.js'
import { getGlobal } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export async function createGlobalVersion<T extends TypeWithID>(
@@ -25,9 +25,7 @@ export async function createGlobalVersion<T extends TypeWithID>(
}: CreateGlobalVersionArgs,
) {
const db = await getTransaction(this, req)
const global = this.payload.globals.config.find(({ slug }) => slug === globalSlug)
const tableName = this.tableNameMap.get(`_${toSnakeCase(global.slug)}${this.versionsSuffix}`)
const { globalConfig, tableName } = getGlobal({ adapter: this, globalSlug, versions: true })
const result = await upsertRow<TypeWithVersion<T>>({
adapter: this,
@@ -41,7 +39,7 @@ export async function createGlobalVersion<T extends TypeWithID>(
version: versionData,
},
db,
fields: buildVersionGlobalFields(this.payload.config, global, true),
fields: buildVersionGlobalFields(this.payload.config, globalConfig, true),
ignoreResult: returning === false ? 'idOnly' : false,
operation: 'create',
req,
@@ -50,7 +48,7 @@ export async function createGlobalVersion<T extends TypeWithID>(
})
const table = this.tables[tableName]
if (global.versions.drafts) {
if (globalConfig.versions.drafts) {
await this.execute({
db,
sql: sql`

View File

@@ -2,11 +2,11 @@ import type { CreateVersionArgs, TypeWithID, TypeWithVersion } from 'payload'
import { sql } from 'drizzle-orm'
import { buildVersionCollectionFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { upsertRow } from './upsertRow/index.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export async function createVersion<T extends TypeWithID>(
@@ -26,12 +26,13 @@ export async function createVersion<T extends TypeWithID>(
}: CreateVersionArgs<T>,
) {
const db = await getTransaction(this, req)
const collection = this.payload.collections[collectionSlug].config
const defaultTableName = toSnakeCase(collection.slug)
const { collectionConfig, tableName } = getCollection({
adapter: this,
collectionSlug,
versions: true,
})
const tableName = this.tableNameMap.get(`_${defaultTableName}${this.versionsSuffix}`)
const version = { ...versionData }
const version: Partial<TypeWithID> = { ...versionData }
if (version.id) {
delete version.id
}
@@ -51,7 +52,7 @@ export async function createVersion<T extends TypeWithID>(
adapter: this,
data,
db,
fields: buildVersionCollectionFields(this.payload.config, collection, true),
fields: buildVersionCollectionFields(this.payload.config, collectionConfig, true),
operation: 'create',
req,
select,
@@ -60,7 +61,7 @@ export async function createVersion<T extends TypeWithID>(
const table = this.tables[tableName]
if (collection.versions.drafts) {
if (collectionConfig.versions.drafts) {
await this.execute({
db,
sql: sql`

View File

@@ -1,28 +1,26 @@
import type { DeleteMany } from 'payload'
import { inArray } from 'drizzle-orm'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const deleteMany: DeleteMany = async function deleteMany(
this: DrizzleAdapter,
{ collection, req, where },
{ collection: collectionSlug, req, where },
) {
const db = await getTransaction(this, req)
const collectionConfig = this.payload.collections[collection].config
const tableName = this.tableNameMap.get(toSnakeCase(collectionConfig.slug))
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
const result = await findMany({
adapter: this,
fields: collectionConfig.flattenedFields,
joins: false,
limit: 0,
locale: req?.locale,
locale: req?.locale ?? undefined,
page: 1,
pagination: false,
req,
@@ -30,9 +28,9 @@ export const deleteMany: DeleteMany = async function deleteMany(
where,
})
const ids = []
const ids: (number | string)[] = []
result.docs.forEach((data) => {
result.docs.forEach((data: any) => {
ids.push(data.id)
})

View File

@@ -1,7 +1,6 @@
import type { DeleteOne } from 'payload'
import { eq } from 'drizzle-orm'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
@@ -9,6 +8,7 @@ import { buildFindManyArgs } from './find/buildFindManyArgs.js'
import { buildQuery } from './queries/buildQuery.js'
import { selectDistinct } from './queries/selectDistinct.js'
import { transform } from './transform/read/index.js'
import { getCollection, getTableQuery } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const deleteOne: DeleteOne = async function deleteOne(
@@ -16,16 +16,14 @@ export const deleteOne: DeleteOne = async function deleteOne(
{ collection: collectionSlug, req, returning, select, where: whereArg },
) {
const db = await getTransaction(this, req)
const collection = this.payload.collections[collectionSlug].config
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
const tableName = this.tableNameMap.get(toSnakeCase(collection.slug))
let docToDelete: Record<string, unknown>
let docToDelete: Record<string, unknown> | undefined = undefined
const { joins, selectFields, where } = buildQuery({
adapter: this,
fields: collection.flattenedFields,
locale: req?.locale,
fields: collectionConfig.flattenedFields,
locale: req?.locale ?? undefined,
tableName,
where: whereArg,
})
@@ -40,15 +38,17 @@ export const deleteOne: DeleteOne = async function deleteOne(
where,
})
const queryTable = getTableQuery({ adapter: this, tableName })
if (selectDistinctResult?.[0]?.id) {
docToDelete = await db.query[tableName].findFirst({
docToDelete = await queryTable.findFirst({
where: eq(this.tables[tableName].id, selectDistinctResult[0].id),
})
} else {
const findManyArgs = buildFindManyArgs({
adapter: this,
depth: 0,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
joinQuery: false,
select,
tableName,
@@ -56,7 +56,7 @@ export const deleteOne: DeleteOne = async function deleteOne(
findManyArgs.where = where
docToDelete = await db.query[tableName].findFirst(findManyArgs)
docToDelete = await queryTable.findFirst(findManyArgs)
}
if (!docToDelete) {
@@ -70,7 +70,7 @@ export const deleteOne: DeleteOne = async function deleteOne(
adapter: this,
config: this.payload.config,
data: docToDelete,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
joinQuery: false,
tableName,
})

View File

@@ -1,24 +1,24 @@
import type { DeleteVersions, SanitizedCollectionConfig } from 'payload'
import type { DeleteVersions } from 'payload'
import { inArray } from 'drizzle-orm'
import { buildVersionCollectionFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const deleteVersions: DeleteVersions = async function deleteVersion(
this: DrizzleAdapter,
{ collection, locale, req, where: where },
{ collection: collectionSlug, locale, req, where: where },
) {
const db = await getTransaction(this, req)
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const tableName = this.tableNameMap.get(
`_${toSnakeCase(collectionConfig.slug)}${this.versionsSuffix}`,
)
const { collectionConfig, tableName } = getCollection({
adapter: this,
collectionSlug,
versions: true,
})
const fields = buildVersionCollectionFields(this.payload.config, collectionConfig, true)
@@ -35,9 +35,9 @@ export const deleteVersions: DeleteVersions = async function deleteVersion(
where,
})
const ids = []
const ids: (number | string)[] = []
docs.forEach((doc) => {
docs.forEach((doc: any) => {
ids.push(doc.id)
})

View File

@@ -1,15 +1,14 @@
import type { Find, SanitizedCollectionConfig } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { Find } from 'payload'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getCollection } from './utilities/getEntity.js'
export const find: Find = async function find(
this: DrizzleAdapter,
{
collection,
collection: collectionSlug,
draftsEnabled,
joins,
limit,
@@ -22,11 +21,9 @@ export const find: Find = async function find(
where,
},
) {
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collectionConfig.defaultSort
const tableName = this.tableNameMap.get(toSnakeCase(collectionConfig.slug))
return findMany({
adapter: this,
collectionSlug: collectionConfig.slug,

View File

@@ -44,7 +44,7 @@ export const buildFindManyArgs = ({
select,
tableName,
versions,
}: BuildFindQueryArgs): Record<string, unknown> => {
}: BuildFindQueryArgs): any => {
const result: Result = {
extras: {},
with: {},

View File

@@ -1,18 +1,15 @@
import type { FindGlobal } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getGlobal } from './utilities/getEntity.js'
export const findGlobal: FindGlobal = async function findGlobal(
this: DrizzleAdapter,
{ slug, locale, req, select, where },
{ slug: globalSlug, locale, req, select, where },
) {
const globalConfig = this.payload.globals.config.find((config) => config.slug === slug)
const tableName = this.tableNameMap.get(toSnakeCase(globalConfig.slug))
const { globalConfig, tableName } = getGlobal({ adapter: this, globalSlug })
const {
docs: [doc],
@@ -29,7 +26,7 @@ export const findGlobal: FindGlobal = async function findGlobal(
})
if (doc) {
doc.globalType = slug
doc.globalType = globalSlug
return doc
}

View File

@@ -1,25 +1,19 @@
import type { FindGlobalVersions, SanitizedGlobalConfig } from 'payload'
import type { FindGlobalVersions } from 'payload'
import { buildVersionGlobalFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getGlobal } from './utilities/getEntity.js'
export const findGlobalVersions: FindGlobalVersions = async function findGlobalVersions(
this: DrizzleAdapter,
{ global, limit, locale, page, pagination, req, select, skip, sort: sortArg, where },
{ global: globalSlug, limit, locale, page, pagination, req, select, skip, sort: sortArg, where },
) {
const globalConfig: SanitizedGlobalConfig = this.payload.globals.config.find(
({ slug }) => slug === global,
)
const { globalConfig, tableName } = getGlobal({ adapter: this, globalSlug, versions: true })
const sort = sortArg !== undefined && sortArg !== null ? sortArg : '-createdAt'
const tableName = this.tableNameMap.get(
`_${toSnakeCase(globalConfig.slug)}${this.versionsSuffix}`,
)
const fields = buildVersionGlobalFields(this.payload.config, globalConfig, true)
return findMany({

View File

@@ -1,22 +1,19 @@
import type { FindOneArgs, SanitizedCollectionConfig, TypeWithID } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { FindOneArgs, TypeWithID } from 'payload'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getCollection } from './utilities/getEntity.js'
export async function findOne<T extends TypeWithID>(
this: DrizzleAdapter,
{ collection, draftsEnabled, joins, locale, req, select, where }: FindOneArgs,
{ collection: collectionSlug, draftsEnabled, joins, locale, req, select, where }: FindOneArgs,
): Promise<T> {
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const tableName = this.tableNameMap.get(toSnakeCase(collectionConfig.slug))
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
const { docs } = await findMany({
adapter: this,
collectionSlug: collection,
collectionSlug,
draftsEnabled,
fields: collectionConfig.flattenedFields,
joins,

View File

@@ -1,23 +1,34 @@
import type { FindVersions, SanitizedCollectionConfig } from 'payload'
import type { FindVersions } from 'payload'
import { buildVersionCollectionFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getCollection } from './utilities/getEntity.js'
export const findVersions: FindVersions = async function findVersions(
this: DrizzleAdapter,
{ collection, limit, locale, page, pagination, req, select, skip, sort: sortArg, where },
{
collection: collectionSlug,
limit,
locale,
page,
pagination,
req,
select,
skip,
sort: sortArg,
where,
},
) {
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const { collectionConfig, tableName } = getCollection({
adapter: this,
collectionSlug,
versions: true,
})
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collectionConfig.defaultSort
const tableName = this.tableNameMap.get(
`_${toSnakeCase(collectionConfig.slug)}${this.versionsSuffix}`,
)
const fields = buildVersionCollectionFields(this.payload.config, collectionConfig, true)
return findMany({

View File

@@ -1,4 +1,4 @@
import type { Payload } from 'payload'
import type { JsonObject, Payload, TypeWithID } from 'payload'
import {
commitTransaction,
@@ -32,7 +32,7 @@ export const migrate: DrizzleAdapter['migrate'] = async function migrate(
}
let latestBatch = 0
let migrationsInDB = []
let migrationsInDB: (JsonObject & TypeWithID)[] = []
const hasMigrationTable = await migrationTableExists(this)

View File

@@ -52,7 +52,7 @@ export async function migrateDown(this: DrizzleAdapter): Promise<void> {
const tableExists = await migrationTableExists(this, db)
if (tableExists) {
if (tableExists && migration.id) {
await payload.delete({
id: migration.id,
collection: 'payload-migrations',

View File

@@ -48,7 +48,7 @@ export async function migrateReset(this: DrizzleAdapter): Promise<void> {
})
const tableExists = await migrationTableExists(this, db)
if (tableExists) {
if (tableExists && migration.id) {
await payload.delete({
id: migration.id,
collection: 'payload-migrations',
@@ -58,7 +58,10 @@ export async function migrateReset(this: DrizzleAdapter): Promise<void> {
await commitTransaction(req)
} catch (err: unknown) {
let msg = `Error running migration ${migrationFile.name}.`
let msg = `Error running migration`
if (migrationFile) {
msg += ` ${migrationFile.name}.`
}
if (err instanceof Error) {
msg += ` ${err.message}`

View File

@@ -1,3 +1,5 @@
import type { MigrationData } from 'payload'
import { Table } from 'console-table-printer'
import { getMigrations, readMigrationFiles } from 'payload'
@@ -13,7 +15,7 @@ export async function migrateStatus(this: DrizzleAdapter): Promise<void> {
msg: `Found ${migrationFiles.length} migration files.`,
})
let existingMigrations = []
let existingMigrations: MigrationData[] = []
const hasMigrationTable = await migrationTableExists(this)
if (hasMigrationTable) {

View File

@@ -1,27 +1,39 @@
import type { QueryDrafts, SanitizedCollectionConfig } from 'payload'
import type { QueryDrafts } from 'payload'
import { buildVersionCollectionFields, combineQueries } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { getCollection } from './utilities/getEntity.js'
export const queryDrafts: QueryDrafts = async function queryDrafts(
this: DrizzleAdapter,
{ collection, joins, limit, locale, page = 1, pagination, req, select, sort, where },
{
collection: collectionSlug,
joins,
limit,
locale,
page = 1,
pagination,
req,
select,
sort,
where,
},
) {
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const tableName = this.tableNameMap.get(
`_${toSnakeCase(collectionConfig.slug)}${this.versionsSuffix}`,
)
const { collectionConfig, tableName } = getCollection({
adapter: this,
collectionSlug,
versions: true,
})
const fields = buildVersionCollectionFields(this.payload.config, collectionConfig, true)
const combinedWhere = combineQueries({ latest: { equals: true } }, where)
const combinedWhere = combineQueries({ latest: { equals: true } }, where ?? {})
const result = await findMany({
adapter: this,
collectionSlug: collection,
collectionSlug,
fields,
joins,
limit,
@@ -38,7 +50,7 @@ export const queryDrafts: QueryDrafts = async function queryDrafts(
return {
...result,
docs: result.docs.map((doc) => {
docs: result.docs.map((doc: any) => {
doc = {
id: doc.parent,
...doc.version,

View File

@@ -1,21 +1,19 @@
import type { UpdateGlobalArgs } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { upsertRow } from './upsertRow/index.js'
import { getGlobal, getTableQuery } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export async function updateGlobal<T extends Record<string, unknown>>(
this: DrizzleAdapter,
{ slug, data, req, returning, select }: UpdateGlobalArgs,
{ slug: globalSlug, data, req, returning, select }: UpdateGlobalArgs,
): Promise<T> {
const db = await getTransaction(this, req)
const globalConfig = this.payload.globals.config.find((config) => config.slug === slug)
const tableName = this.tableNameMap.get(toSnakeCase(globalConfig.slug))
const existingGlobal = await db.query[tableName].findFirst({})
const { globalConfig, tableName } = getGlobal({ adapter: this, globalSlug })
const queryTable = getTableQuery({ adapter: this, tableName })
const existingGlobal = await queryTable.findFirst({})
const result = await upsertRow<{ globalType: string } & T>({
...(existingGlobal ? { id: existingGlobal.id, operation: 'update' } : { operation: 'create' }),
@@ -30,10 +28,11 @@ export async function updateGlobal<T extends Record<string, unknown>>(
})
if (returning === false) {
// @ts-expect-error dont want to change public api response type
return null
}
result.globalType = slug
result.globalType = globalSlug
return result
}

View File

@@ -6,19 +6,19 @@ import type {
} from 'payload'
import { buildVersionGlobalFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { buildQuery } from './queries/buildQuery.js'
import { upsertRow } from './upsertRow/index.js'
import { getGlobal } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export async function updateGlobalVersion<T extends TypeWithID>(
this: DrizzleAdapter,
{
id,
global,
global: globalSlug,
locale,
req,
returning,
@@ -28,15 +28,9 @@ export async function updateGlobalVersion<T extends TypeWithID>(
}: UpdateGlobalVersionArgs<T>,
) {
const db = await getTransaction(this, req)
const globalConfig: SanitizedGlobalConfig = this.payload.globals.config.find(
({ slug }) => slug === global,
)
const { globalConfig, tableName } = getGlobal({ adapter: this, globalSlug, versions: true })
const whereToUse = whereArg || { id: { equals: id } }
const tableName = this.tableNameMap.get(
`_${toSnakeCase(globalConfig.slug)}${this.versionsSuffix}`,
)
const fields = buildVersionGlobalFields(this.payload.config, globalConfig, true)
const { where } = buildQuery({

View File

@@ -1,11 +1,10 @@
import type { UpdateJobs, Where } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { findMany } from './find/findMany.js'
import { upsertRow } from './upsertRow/index.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const updateJobs: UpdateJobs = async function updateMany(
@@ -15,18 +14,20 @@ export const updateJobs: UpdateJobs = async function updateMany(
if (!(data?.log as object[])?.length) {
delete data.log
}
const whereToUse: Where = id ? { id: { equals: id } } : whereArg
const whereToUse: Where = id ? { id: { equals: id } } : (whereArg ?? {})
const limit = id ? 1 : limitArg
const db = await getTransaction(this, req)
const collection = this.payload.collections['payload-jobs'].config
const tableName = this.tableNameMap.get(toSnakeCase(collection.slug))
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collection.defaultSort
const { collectionConfig, tableName } = getCollection({
adapter: this,
collectionSlug: 'payload-jobs',
})
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collectionConfig.defaultSort
const jobs = await findMany({
adapter: this,
collectionSlug: 'payload-jobs',
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
limit: id ? 1 : limit,
pagination: false,
req,
@@ -52,7 +53,7 @@ export const updateJobs: UpdateJobs = async function updateMany(
adapter: this,
data: updateData,
db,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
ignoreResult: returning === false,
operation: 'update',
req,

View File

@@ -8,6 +8,7 @@ import type { DrizzleAdapter } from './types.js'
import { buildQuery } from './queries/buildQuery.js'
import { selectDistinct } from './queries/selectDistinct.js'
import { upsertRow } from './upsertRow/index.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const updateMany: UpdateMany = async function updateMany(
@@ -26,14 +27,13 @@ export const updateMany: UpdateMany = async function updateMany(
},
) {
const db = await getTransaction(this, req)
const collection = this.payload.collections[collectionSlug].config
const tableName = this.tableNameMap.get(toSnakeCase(collection.slug))
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collection.defaultSort
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collectionConfig.defaultSort
const { joins, orderBy, selectFields, where } = buildQuery({
adapter: this,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
locale,
sort,
tableName,
@@ -90,7 +90,7 @@ export const updateMany: UpdateMany = async function updateMany(
adapter: this,
data,
db,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
ignoreResult: returning === false,
joinQuery,
operation: 'update',

View File

@@ -8,6 +8,7 @@ import type { DrizzleAdapter } from './types.js'
import { buildQuery } from './queries/buildQuery.js'
import { selectDistinct } from './queries/selectDistinct.js'
import { upsertRow } from './upsertRow/index.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export const updateOne: UpdateOne = async function updateOne(
@@ -25,17 +26,16 @@ export const updateOne: UpdateOne = async function updateOne(
},
) {
const db = await getTransaction(this, req)
const collection = this.payload.collections[collectionSlug].config
const tableName = this.tableNameMap.get(toSnakeCase(collection.slug))
const { collectionConfig, tableName } = getCollection({ adapter: this, collectionSlug })
let idToUpdate = id
if (!idToUpdate) {
const { joins, selectFields, where } = buildQuery({
adapter: this,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
locale,
tableName,
where: whereArg,
where: whereArg ?? {},
})
// selectDistinct will only return if there are joins
@@ -71,7 +71,7 @@ export const updateOne: UpdateOne = async function updateOne(
adapter: this,
data,
db,
fields: collection.flattenedFields,
fields: collectionConfig.flattenedFields,
ignoreResult: returning === false,
joinQuery,
operation: 'update',

View File

@@ -1,24 +1,19 @@
import type {
SanitizedCollectionConfig,
TypeWithID,
TypeWithVersion,
UpdateVersionArgs,
} from 'payload'
import type { TypeWithID, TypeWithVersion, UpdateVersionArgs } from 'payload'
import { buildVersionCollectionFields } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from './types.js'
import { buildQuery } from './queries/buildQuery.js'
import { upsertRow } from './upsertRow/index.js'
import { getCollection } from './utilities/getEntity.js'
import { getTransaction } from './utilities/getTransaction.js'
export async function updateVersion<T extends TypeWithID>(
this: DrizzleAdapter,
{
id,
collection,
collection: collectionSlug,
locale,
req,
returning,
@@ -28,11 +23,12 @@ export async function updateVersion<T extends TypeWithID>(
}: UpdateVersionArgs<T>,
) {
const db = await getTransaction(this, req)
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
const { collectionConfig, tableName } = getCollection({
adapter: this,
collectionSlug,
versions: true,
})
const whereToUse = whereArg || { id: { equals: id } }
const tableName = this.tableNameMap.get(
`_${toSnakeCase(collectionConfig.slug)}${this.versionsSuffix}`,
)
const fields = buildVersionCollectionFields(this.payload.config, collectionConfig, true)

View File

@@ -22,6 +22,6 @@ export const deleteExistingArrayRows = async ({
await adapter.deleteWhere({
db,
tableName,
where: and(...whereConstraints),
where: and(...whereConstraints)!,
})
}

View File

@@ -49,7 +49,7 @@ export const deleteExistingRowsByPath = async ({
await adapter.deleteWhere({
db,
tableName,
where: and(...whereConstraints),
where: and(...whereConstraints)!,
})
}
@@ -63,7 +63,7 @@ export const deleteExistingRowsByPath = async ({
await adapter.deleteWhere({
db,
tableName,
where: and(...whereConstraints),
where: and(...whereConstraints)!,
})
}
}

View File

@@ -9,6 +9,7 @@ import type { Args } from './types.js'
import { buildFindManyArgs } from '../find/buildFindManyArgs.js'
import { transform } from '../transform/read/index.js'
import { transformForWrite } from '../transform/write/index.js'
import { getTableQuery } from '../utilities/getEntity.js'
import { deleteExistingArrayRows } from './deleteExistingArrayRows.js'
import { deleteExistingRowsByPath } from './deleteExistingRowsByPath.js'
import { insertArrays } from './insertArrays.js'
@@ -43,7 +44,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
})
// First, we insert the main row
let insertedRow: Record<string, unknown>
let insertedRow: Record<string, unknown> | undefined
try {
if (operation === 'update') {
@@ -86,7 +87,9 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// If there are locale rows with data, add the parent and locale to each
if (Object.keys(rowToInsert.locales).length > 0) {
Object.entries(rowToInsert.locales).forEach(([locale, localeRow]) => {
localeRow._parentID = insertedRow.id
if (insertedRow) {
localeRow._parentID = insertedRow.id
}
localeRow._locale = locale
localesToInsert.push(localeRow)
})
@@ -95,7 +98,9 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// If there are relationships, add parent to each
if (rowToInsert.relationships.length > 0) {
rowToInsert.relationships.forEach((relation) => {
relation.parent = insertedRow.id
if (insertedRow) {
relation.parent = insertedRow.id
}
relationsToInsert.push(relation)
})
}
@@ -103,7 +108,9 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// If there are texts, add parent to each
if (rowToInsert.texts.length > 0) {
rowToInsert.texts.forEach((textRow) => {
textRow.parent = insertedRow.id
if (insertedRow) {
textRow.parent = insertedRow.id
}
textsToInsert.push(textRow)
})
}
@@ -111,7 +118,9 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// If there are numbers, add parent to each
if (rowToInsert.numbers.length > 0) {
rowToInsert.numbers.forEach((numberRow) => {
numberRow.parent = insertedRow.id
if (insertedRow) {
numberRow.parent = insertedRow.id
}
numbersToInsert.push(numberRow)
})
}
@@ -124,10 +133,12 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
selectRows.forEach((row) => {
if (typeof row.parent === 'undefined') {
row.parent = insertedRow.id
if (insertedRow) {
row.parent = insertedRow.id
}
}
selectsToInsert[selectTableName].push(row)
selectsToInsert[selectTableName]?.push(row)
})
})
}
@@ -135,8 +146,10 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// If there are blocks, add parent to each, and then
// store by table name and rows
Object.keys(rowToInsert.blocks).forEach((tableName) => {
rowToInsert.blocks[tableName].forEach((blockRow) => {
blockRow.row._parentID = insertedRow.id
rowToInsert.blocks[tableName]?.forEach((blockRow) => {
if (insertedRow) {
blockRow.row._parentID = insertedRow.id
}
if (!blocksToInsert[tableName]) {
blocksToInsert[tableName] = []
}
@@ -155,7 +168,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
const localeTableName = `${tableName}${adapter.localesSuffix}`
const localeTable = adapter.tables[`${tableName}${adapter.localesSuffix}`]
if (operation === 'update') {
if (operation === 'update' && insertedRow) {
await adapter.deleteWhere({
db,
tableName: localeTableName,
@@ -176,7 +189,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
const relationshipsTableName = `${tableName}${adapter.relationshipsSuffix}`
if (operation === 'update') {
if (operation === 'update' && insertedRow) {
await deleteExistingRowsByPath({
adapter,
db,
@@ -203,7 +216,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
const textsTableName = `${tableName}_texts`
if (operation === 'update') {
if (operation === 'update' && insertedRow) {
await deleteExistingRowsByPath({
adapter,
db,
@@ -230,7 +243,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
const numbersTableName = `${tableName}_numbers`
if (operation === 'update') {
if (operation === 'update' && insertedRow) {
await deleteExistingRowsByPath({
adapter,
db,
@@ -257,7 +270,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
const insertedBlockRows: Record<string, Record<string, unknown>[]> = {}
if (operation === 'update') {
if (operation === 'update' && insertedRow) {
for (const tableName of rowToInsert.blocksToDelete) {
const blockTable = adapter.tables[tableName]
await adapter.deleteWhere({
@@ -279,7 +292,9 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
})
insertedBlockRows[tableName].forEach((row, i) => {
blockRows[i].row = row
if (blockRows[i]) {
blockRows[i].row = row
}
if (
typeof row._uuid === 'string' &&
(typeof row.id === 'string' || typeof row.id === 'number')
@@ -290,20 +305,23 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
const blockLocaleIndexMap: number[] = []
const blockLocaleRowsToInsert = blockRows.reduce((acc, blockRow, i) => {
if (Object.entries(blockRow.locales).length > 0) {
Object.entries(blockRow.locales).forEach(([blockLocale, blockLocaleData]) => {
if (Object.keys(blockLocaleData).length > 0) {
blockLocaleData._parentID = blockRow.row.id
blockLocaleData._locale = blockLocale
acc.push(blockLocaleData)
blockLocaleIndexMap.push(i)
}
})
}
const blockLocaleRowsToInsert = blockRows.reduce<Record<string, unknown>[]>(
(acc, blockRow, i) => {
if (Object.entries(blockRow.locales).length > 0) {
Object.entries(blockRow.locales).forEach(([blockLocale, blockLocaleData]) => {
if (Object.keys(blockLocaleData).length > 0) {
blockLocaleData._parentID = blockRow.row.id
blockLocaleData._locale = blockLocale
acc.push(blockLocaleData)
blockLocaleIndexMap.push(i)
}
})
}
return acc
}, [])
return acc
},
[],
)
if (blockLocaleRowsToInsert.length > 0) {
await adapter.insert({
@@ -326,7 +344,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// INSERT ARRAYS RECURSIVELY
// //////////////////////////////////
if (operation === 'update') {
if (operation === 'update' && insertedRow) {
for (const arrayTableName of Object.keys(rowToInsert.arrays)) {
await deleteExistingArrayRows({
adapter,
@@ -337,13 +355,15 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
}
}
await insertArrays({
adapter,
arrays: [rowToInsert.arrays],
db,
parentRows: [insertedRow],
uuidMap: arraysBlocksUUIDMap,
})
if (insertedRow) {
await insertArrays({
adapter,
arrays: [rowToInsert.arrays],
db,
parentRows: [insertedRow],
uuidMap: arraysBlocksUUIDMap,
})
}
// //////////////////////////////////
// INSERT hasMany SELECTS
@@ -351,7 +371,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
for (const [selectTableName, tableRows] of Object.entries(selectsToInsert)) {
const selectTable = adapter.tables[selectTableName]
if (operation === 'update') {
if (operation === 'update' && insertedRow) {
await adapter.deleteWhere({
db,
tableName: selectTableName,
@@ -379,18 +399,20 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
// //////////////////////////////////
// Error Handling
// //////////////////////////////////
} catch (error) {
if (error.code === '23505') {
} catch (error: unknown) {
if (error && typeof error === 'object' && 'code' in error && error.code === '23505') {
const constraint =
('constraint' in error && typeof error.constraint === 'string' && error.constraint) || ''
let fieldName: null | string = null
// We need to try and find the right constraint for the field but if we can't we fallback to a generic message
if (adapter.fieldConstraints?.[tableName]) {
if (adapter.fieldConstraints[tableName]?.[error.constraint]) {
fieldName = adapter.fieldConstraints[tableName]?.[error.constraint]
if (adapter.fieldConstraints[tableName]?.[constraint]) {
fieldName = adapter.fieldConstraints[tableName]?.[constraint]
} else {
const replacement = `${tableName}_`
if (error.constraint.includes(replacement)) {
const replacedConstraint = error.constraint.replace(replacement, '')
if (constraint.includes(replacement)) {
const replacedConstraint = constraint.replace(replacement, '')
if (replacedConstraint && adapter.fieldConstraints[tableName]?.[replacedConstraint]) {
fieldName = adapter.fieldConstraints[tableName][replacedConstraint]
@@ -401,14 +423,15 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
if (!fieldName) {
// Last case scenario we extract the key and value from the detail on the error
const detail = error.detail
const detail = ('detail' in error && typeof error.detail === 'string' && error.detail) || ''
// eslint-disable-next-line regexp/no-unused-capturing-group
const regex = /Key \(([^)]+)\)=\(([^)]+)\)/
const match = detail.match(regex)
if (match) {
const key = match[1]
fieldName = key
fieldName = key ?? null
}
}
@@ -418,7 +441,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
errors: [
{
message: req?.t ? req.t('error:valueMustBeUnique') : 'Value must be unique',
path: fieldName,
path: fieldName ?? '',
},
],
req,
@@ -430,7 +453,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
}
}
if (ignoreResult === 'idOnly') {
if (ignoreResult === 'idOnly' && insertedRow) {
return { id: insertedRow.id } as T
}
@@ -451,9 +474,12 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
tableName,
})
findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)
if (insertedRow) {
findManyArgs.where = eq(adapter.tables[tableName].id, insertedRow.id)
}
const doc = await db.query[tableName].findFirst(findManyArgs)
const queryTable = getTableQuery({ adapter, tableName })
const doc = await queryTable.findFirst(findManyArgs)
// //////////////////////////////////
// TRANSFORM DATA
@@ -462,7 +488,7 @@ export const upsertRow = async <T extends Record<string, unknown> | TypeWithID>(
const result = transform<T>({
adapter,
config: adapter.payload.config,
data: doc,
data: doc ?? {},
fields,
joinQuery: false,
tableName,

View File

@@ -42,26 +42,26 @@ export const insertArrays = async ({
}
}
const parentID = parentRows[parentRowIndex].id
const parentID = parentRows[parentRowIndex]?.id
// Add any sub arrays that need to be created
// We will call this recursively below
arrayRows.forEach((arrayRow) => {
if (Object.keys(arrayRow.arrays).length > 0) {
rowsByTable[tableName].arrays.push(arrayRow.arrays)
rowsByTable[tableName]?.arrays.push(arrayRow.arrays)
}
// Set up parent IDs for both row and locale row
arrayRow.row._parentID = parentID
rowsByTable[tableName].rows.push(arrayRow.row)
rowsByTable[tableName]?.rows.push(arrayRow.row)
Object.entries(arrayRow.locales).forEach(([arrayRowLocale, arrayRowLocaleData]) => {
arrayRowLocaleData._parentID = arrayRow.row.id
arrayRowLocaleData._locale = arrayRowLocale
rowsByTable[tableName].locales.push(arrayRowLocaleData)
rowsByTable[tableName]?.locales.push(arrayRowLocaleData)
if (!arrayRow.row.id) {
arrayRowLocaleData._getParentID = (rows: { _uuid: string; id: number }[]) => {
const { id } = rows.find((each) => each._uuid === arrayRow.row._uuid)
const { id } = rows.find((each) => each._uuid === arrayRow.row._uuid) ?? {}
return id
}
}
@@ -74,7 +74,7 @@ export const insertArrays = async ({
// (one insert per array table)
for (const [tableName, row] of Object.entries(rowsByTable)) {
// the nested arrays need the ID for the parentID foreign key
let insertedRows: Args['parentRows']
let insertedRows: Args['parentRows'] | null = null
if (row.rows.length > 0) {
insertedRows = await adapter.insert({
db,
@@ -94,7 +94,7 @@ export const insertArrays = async ({
// Insert locale rows
if (adapter.tables[`${tableName}${adapter.localesSuffix}`] && row.locales.length > 0) {
if (!row.locales[0]._parentID) {
if (!row.locales[0]?._parentID) {
row.locales = row.locales.map((localeRow) => {
if (typeof localeRow._getParentID === 'function') {
localeRow._parentID = localeRow._getParentID(insertedRows)
@@ -111,7 +111,7 @@ export const insertArrays = async ({
}
// If there are sub arrays, call this function recursively
if (row.arrays.length > 0) {
if (row.arrays.length > 0 && insertedRows) {
await insertArrays({
adapter,
arrays: row.arrays,

View File

@@ -1,5 +1,5 @@
export const appendPrefixToObjectKeys = <T>(obj: Record<string, unknown>, prefix: string): T =>
Object.entries(obj).reduce((res, [key, val]) => {
Object.entries(obj).reduce((res: any, [key, val]) => {
res[`${prefix}_${key}`] = val
return res
}, {} as T)

View File

@@ -34,11 +34,11 @@ export const buildCreateMigration = ({
const drizzleJsonAfter = await generateDrizzleJson(this.schema)
const [yyymmdd, hhmmss] = new Date().toISOString().split('T')
const formattedDate = yyymmdd.replace(/\D/g, '')
const formattedTime = hhmmss.split('.')[0].replace(/\D/g, '')
let imports: string = ''
let downSQL: string
let upSQL: string
const formattedDate = yyymmdd?.replace(/\D/g, '')
const formattedTime = hhmmss?.split('.')[0]?.replace(/\D/g, '')
let imports: string | undefined = ''
let downSQL: string | undefined
let upSQL: string | undefined
;({ downSQL, imports, upSQL } = await getPredefinedMigration({
dirname,
file,

View File

@@ -9,7 +9,11 @@ export const createBlocksMap = (data: Record<string, unknown>): BlocksMap => {
if (key.startsWith('_blocks_') && Array.isArray(rows)) {
let blockType = key.replace('_blocks_', '')
const parsed = blockType.split('_')
if (parsed.length === 2 && Number.isInteger(Number(parsed[1]))) {
if (
parsed.length === 2 &&
Number.isInteger(Number(parsed[1])) &&
typeof parsed[0] === 'string'
) {
blockType = parsed[0]
}
@@ -20,7 +24,7 @@ export const createBlocksMap = (data: Record<string, unknown>): BlocksMap => {
}
row.blockType = blockType
blocksMap[row._path].push(row)
blocksMap[row._path]?.push(row)
delete row._path
}
@@ -30,7 +34,7 @@ export const createBlocksMap = (data: Record<string, unknown>): BlocksMap => {
}
})
Object.entries(blocksMap).reduce((sortedBlocksMap, [path, blocks]) => {
Object.entries(blocksMap).reduce((sortedBlocksMap: any, [path, blocks]) => {
sortedBlocksMap[path] = blocks.sort((a, b) => {
if (typeof a._order === 'number' && typeof b._order === 'number') {
return a._order - b._order

View File

@@ -75,7 +75,7 @@ export const createSchemaGenerator = ({
let schemaDeclaration: null | string = null
if (this.schemaName) {
if (this.schemaName && schemaImport) {
addImport(corePackage, schemaImport)
schemaDeclaration = `export const db_schema = ${schemaImport}('${this.schemaName}')`
}
@@ -113,11 +113,18 @@ export const createSchemaGenerator = ({
for (const tableName in this.rawTables) {
const table = this.rawTables[tableName]
if (!table) {
continue
}
const extrasDeclarations: string[] = []
if (table.indexes) {
for (const key in table.indexes) {
const index = table.indexes[key]
if (!index) {
continue
}
let indexDeclaration = `${sanitizeObjectKey(key)}: ${index.unique ? 'uniqueIndex' : 'index'}('${index.name}')`
indexDeclaration += `.on(${typeof index.on === 'string' ? `${accessProperty('columns', index.on)}` : `${index.on.map((on) => `${accessProperty('columns', on)}`).join(', ')}`}),`
extrasDeclarations.push(indexDeclaration)
@@ -127,7 +134,9 @@ export const createSchemaGenerator = ({
if (table.foreignKeys) {
for (const key in table.foreignKeys) {
const foreignKey = table.foreignKeys[key]
if (!foreignKey) {
continue
}
let foreignKeyDeclaration = `${sanitizeObjectKey(key)}: foreignKey({
columns: [${foreignKey.columns.map((col) => `columns['${col}']`).join(', ')}],
foreignColumns: [${foreignKey.foreignColumns.map((col) => `${accessProperty(col.table, col.name)}`).join(', ')}],
@@ -179,10 +188,16 @@ ${Object.entries(table.columns)
for (const tableName in this.rawRelations) {
const relations = this.rawRelations[tableName]
if (!relations) {
continue
}
const properties: string[] = []
for (const key in relations) {
const relation = relations[key]
if (!relation) {
continue
}
let declaration: string
if (relation.type === 'one') {
@@ -221,7 +236,7 @@ ${Object.entries(table.columns)
relationsDeclarations.push(declaration)
}
if (enumDeclarations.length && !this.schemaName) {
if (enumDeclarations.length && !this.schemaName && enumImport) {
addImport(corePackage, enumImport)
}
@@ -229,6 +244,9 @@ ${Object.entries(table.columns)
for (const moduleName in importDeclarations) {
const moduleImports = importDeclarations[moduleName]
if (!moduleImports) {
continue
}
importDeclarationsSanitized.push(
`import { ${Array.from(moduleImports).join(', ')} } from '${moduleName}'`,

View File

@@ -26,7 +26,9 @@ type Args = {
/**
* Extends the passed table with additional columns / extra config
*/
export const extendDrizzleTable = ({ columns, extraConfig, table }: Args): void => {
export const extendDrizzleTable = ({ columns, extraConfig, table: tableFromArgs }: Args): void => {
// hard drizzle types
const table: any = tableFromArgs
const InlineForeignKeys = Object.getOwnPropertySymbols(table).find((symbol) => {
return symbol.description?.includes('InlineForeignKeys')
})
@@ -53,7 +55,7 @@ export const extendDrizzleTable = ({ columns, extraConfig, table }: Args): void
if (extraConfig) {
const originalExtraConfigBuilder = table[DrizzleSymbol.ExtraConfigBuilder]
table[DrizzleSymbol.ExtraConfigBuilder] = (t) => {
table[DrizzleSymbol.ExtraConfigBuilder] = (t: any) => {
return {
...originalExtraConfigBuilder(t),
...extraConfig(t),

View File

@@ -0,0 +1,90 @@
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
import type { RelationalQueryBuilder } from 'drizzle-orm/sqlite-core/query-builders/query'
import type { CollectionSlug, GlobalSlug } from 'payload'
import { APIError } from 'payload'
import toSnakeCase from 'to-snake-case'
import type { DrizzleAdapter } from '../types.js'
export const getCollection = ({
adapter,
collectionSlug,
versions = false,
}: {
adapter: DrizzleAdapter
collectionSlug: CollectionSlug
versions?: boolean
}) => {
const collection = adapter.payload.collections[collectionSlug]
if (!collection) {
throw new APIError(`Collection with the slug ${collectionSlug} was not found in the config.`)
}
const tableNameKey = versions
? `_${toSnakeCase(collection.config.slug)}${adapter.versionsSuffix}`
: toSnakeCase(collection.config.slug)
const tableName = adapter.tableNameMap.get(tableNameKey)
if (!tableName) {
throw new APIError(
`Table for collection with the slug ${collectionSlug} ${tableName} was not found.`,
)
}
return {
collectionConfig: collection.config,
tableName,
}
}
export const getGlobal = ({
adapter,
globalSlug,
versions = false,
}: {
adapter: DrizzleAdapter
globalSlug: GlobalSlug
versions?: boolean
}) => {
const globalConfig = adapter.payload.config.globals.find((each) => each.slug === globalSlug)
if (!globalConfig) {
throw new APIError(`Global with the slug ${globalSlug} was not found in the config.`)
}
const tableNameKey = versions
? `_${toSnakeCase(globalConfig.slug)}${adapter.versionsSuffix}`
: toSnakeCase(globalConfig.slug)
const tableName = adapter.tableNameMap.get(tableNameKey)
if (!tableName) {
throw new APIError(`Table for global with the slug ${globalSlug} ${tableName} was not found.`)
}
return {
globalConfig,
tableName,
}
}
export const getTableQuery = ({
adapter,
tableName,
}: {
adapter: DrizzleAdapter
tableName: string
}) => {
const drizzle = adapter.drizzle
// @ts-expect-error we don't have drizzle schema types
const table = drizzle.query[tableName] as RelationalQueryBuilder<any, any, any, any> | undefined
if (!table) {
throw new APIError(`Table with the name ${tableName} was not found.`)
}
return table
}

View File

@@ -14,10 +14,10 @@ export const getMigrationTemplate = ({
}: MigrationTemplateArgs): string => `import { MigrateUpArgs, MigrateDownArgs, sql } from '${packageName}'
${imports ? `${imports}\n` : ''}
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
${indent(upSQL)}
${upSQL ? indent(upSQL) : ''}
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
${indent(downSQL)}
${downSQL ? indent(downSQL) : ''}
}
`

View File

@@ -1,9 +1,9 @@
import type { Table } from 'drizzle-orm'
export const getNameFromDrizzleTable = (table: Table): string => {
const symbol = Object.getOwnPropertySymbols(table).find((symb) =>
symb.description.includes('Name'),
const symbol = Object.getOwnPropertySymbols(table).find(
(symb) => symb && symb.description?.includes('Name'),
)
return table[symbol]
return (table as any)[symbol!]
}

View File

@@ -4,7 +4,7 @@ import { fieldAffectsData, fieldHasSubFields, fieldShouldBeLocalized } from 'pay
export const hasLocalesTable = ({
fields,
parentIsLocalized,
parentIsLocalized = false,
}: {
fields: Field[]
/**

View File

@@ -6,11 +6,11 @@ export const isPolymorphicRelationship = (
relationTo: CollectionSlug
value: number | string
} => {
return (
return Boolean(
value &&
typeof value === 'object' &&
'relationTo' in value &&
typeof value.relationTo === 'string' &&
'value' in value
typeof value === 'object' &&
'relationTo' in value &&
typeof value.relationTo === 'string' &&
'value' in value,
)
}

View File

@@ -31,5 +31,5 @@ export const migrationTableExists = async (
const [row] = result.rows
return row && typeof row === 'object' && 'exists' in row && !!row.exists
return Boolean(row && typeof row === 'object' && 'exists' in row && !!row.exists)
}

View File

@@ -35,14 +35,14 @@ export const pushDevSchema = async (adapter: DrizzleAdapter) => {
return
} else {
previousSchema.localeCodes = localeCodes
previousSchema.localeCodes = localeCodes || null
previousSchema.rawTables = adapter.rawTables
}
}
const { pushSchema } = adapter.requireDrizzleKit()
const { extensions = {}, tablesFilter } = adapter as BasePostgresAdapter
const { extensions = {}, tablesFilter } = adapter as unknown as BasePostgresAdapter
// This will prompt if clarifications are needed for Drizzle to push new schema
const { apply, hasDataLoss, warnings } = await pushSchema(

View File

@@ -9,5 +9,7 @@ export const rawConstraint = (value: unknown) => ({
})
export const isRawConstraint = (value: unknown): value is ReturnType<typeof rawConstraint> => {
return value && typeof value === 'object' && 'type' in value && value.type === RawConstraintSymbol
return Boolean(
value && typeof value === 'object' && 'type' in value && value.type === RawConstraintSymbol,
)
}

View File

@@ -27,7 +27,7 @@ const getFlattenedFieldNames = (args: {
prefix?: string
}): { localized?: boolean; name: string }[] => {
const { fields, parentIsLocalized, prefix = '' } = args
return fields.reduce((fieldsToUse, field) => {
return fields.reduce<{ localized?: boolean; name: string }[]>((fieldsToUse, field) => {
let fieldPrefix = prefix
if (
@@ -43,7 +43,8 @@ const getFlattenedFieldNames = (args: {
...fieldsToUse,
...getFlattenedFieldNames({
fields: field.fields,
parentIsLocalized: parentIsLocalized || ('localized' in field && field.localized),
parentIsLocalized:
(parentIsLocalized || ('localized' in field && field.localized)) ?? false,
prefix: fieldPrefix,
}),
]
@@ -52,7 +53,7 @@ const getFlattenedFieldNames = (args: {
if (field.type === 'tabs') {
return [
...fieldsToUse,
...field.tabs.reduce((tabFields, tab) => {
...field.tabs.reduce<{ localized?: boolean; name: string }[]>((tabFields, tab) => {
fieldPrefix = 'name' in tab ? `${prefix}_${tab.name}` : prefix
return [
...tabFields,
@@ -60,7 +61,7 @@ const getFlattenedFieldNames = (args: {
? [{ ...tab, type: 'tab' }]
: getFlattenedFieldNames({
fields: tab.fields,
parentIsLocalized: parentIsLocalized || tab.localized,
parentIsLocalized: (parentIsLocalized || tab.localized) ?? false,
prefix: fieldPrefix,
})),
]
@@ -119,13 +120,13 @@ export const validateExistingBlockIsIdentical = ({
export const InternalBlockTableNameIndex = Symbol('InternalBlockTableNameIndex')
export const setInternalBlockIndex = (block: FlattenedBlock, index: number) => {
block[InternalBlockTableNameIndex] = index
;(block as any)[InternalBlockTableNameIndex] = index
}
export const resolveBlockTableName = (block: FlattenedBlock, originalTableName: string) => {
if (!block[InternalBlockTableNameIndex]) {
if (!(block as any)[InternalBlockTableNameIndex]) {
return originalTableName
}
return `${originalTableName}_${block[InternalBlockTableNameIndex]}`
return `${originalTableName}_${(block as any)[InternalBlockTableNameIndex]}`
}

View File

@@ -1,9 +1,4 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
/* TODO: remove the following lines */
"strict": false,
"noUncheckedIndexedAccess": false,
},
"references": [{ "path": "../payload" }, { "path": "../translations" }]
}

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -16,8 +16,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -27,8 +27,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -11,10 +11,6 @@
"multi-tenant",
"nextjs"
],
"sideEffects": [
"*.scss",
"*.css"
],
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
@@ -29,6 +25,10 @@
"url": "https://payloadcms.com"
}
],
"sideEffects": [
"*.scss",
"*.css"
],
"type": "module",
"exports": {
".": {

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -25,8 +25,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -25,8 +25,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",

View File

@@ -24,8 +24,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -11,10 +11,6 @@
"seo",
"yoast"
],
"sideEffects": [
"*.scss",
"*.css"
],
"repository": {
"type": "git",
"url": "https://github.com/payloadcms/payload.git",
@@ -29,6 +25,10 @@
"url": "https://payloadcms.com"
}
],
"sideEffects": [
"*.scss",
"*.css"
],
"type": "module",
"exports": {
".": {

View File

@@ -27,8 +27,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,11 +17,11 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": [
"*.scss",
"*.css"
],
"type": "module",
"exports": {
".": {
"import": "./src/index.tsx",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -17,8 +17,8 @@
"url": "https://payloadcms.com"
}
],
"type": "module",
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./src/index.ts",

View File

@@ -101,7 +101,7 @@ export const RelationshipInput: React.FC<RelationshipInputProps> = (props) => {
const valueRef = useRef(value)
// the line below seems odd
// eslint-disable-next-line react-compiler/react-compiler -- TODO: fix this
valueRef.current = value
const [DocumentDrawer, , { isDrawerOpen, openDrawer }] = useDocumentDrawer({

View File

@@ -100,7 +100,7 @@ export const TableColumnsProvider: React.FC<TableColumnsProviderProps> = ({
resetColumnsState,
setActiveColumns,
toggleColumn,
// eslint-disable-next-line react-compiler/react-compiler -- TODO: fix
...contextRef.current,
}}
>

4
pnpm-lock.yaml generated
View File

@@ -466,6 +466,9 @@ importers:
'@types/pg':
specifier: 8.10.2
version: 8.10.2
'@types/prompts':
specifier: ^2.4.5
version: 2.4.9
'@types/to-snake-case':
specifier: 1.0.0
version: 1.0.0
@@ -8641,6 +8644,7 @@ packages:
node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
deprecated: Use your platform's native DOMException instead
node-fetch-native@1.6.4:
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}