,
siblingData: Partial,
- { user }: { user: User },
+ {
+ user,
+ }: {
+ user: User
+ },
) => boolean
export type FilterOptionsProps = {
@@ -443,6 +448,14 @@ export type SelectField = FieldBase & {
isClearable?: boolean
isSortable?: boolean
}
+ /**
+ * Customize the SQL table name
+ */
+ dbName?: DBIdentifierName
+ /**
+ * Customize the DB enum name
+ */
+ enumName?: DBIdentifierName
hasMany?: boolean
options: Option[]
type: 'select'
@@ -492,7 +505,9 @@ type RelationshipAdmin = Admin & {
}
export type PolymorphicRelationshipField = SharedRelationshipProperties & {
admin?: RelationshipAdmin & {
- sortOptions?: { [collectionSlug: string]: string }
+ sortOptions?: {
+ [collectionSlug: string]: string
+ }
}
relationTo: string[]
}
@@ -541,6 +556,10 @@ export type ArrayField = FieldBase & {
} & Admin['components']
initCollapsed?: boolean | false
}
+ /**
+ * Customize the SQL table name
+ */
+ dbName?: DBIdentifierName
fields: Field[]
/** Customize generated GraphQL and Typescript schema names.
* By default it is bound to the collection.
@@ -563,6 +582,14 @@ export type RadioField = FieldBase & {
}
layout?: 'horizontal' | 'vertical'
}
+ /**
+ * Customize the SQL table name
+ */
+ dbName?: DBIdentifierName
+ /**
+ * Customize the DB enum name
+ */
+ enumName?: DBIdentifierName
options: Option[]
type: 'radio'
}
diff --git a/packages/payload/src/globals/config/schema.ts b/packages/payload/src/globals/config/schema.ts
index 4754b0b4e9..6eb09f4b23 100644
--- a/packages/payload/src/globals/config/schema.ts
+++ b/packages/payload/src/globals/config/schema.ts
@@ -10,6 +10,7 @@ import {
const globalSchema = joi
.object()
.keys({
+ slug: joi.string().required(),
access: joi.object({
read: joi.func(),
readVersions: joi.func(),
@@ -48,6 +49,7 @@ const globalSchema = joi
preview: joi.func(),
}),
custom: joi.object().pattern(joi.string(), joi.any()),
+ dbName: joi.alternatives().try(joi.string(), joi.func()),
endpoints: endpointsSchema,
fields: joi.array(),
graphQL: joi.alternatives().try(
@@ -64,7 +66,6 @@ const globalSchema = joi
beforeValidate: joi.array().items(joi.func()),
}),
label: joi.alternatives().try(joi.string(), joi.object().pattern(joi.string(), [joi.string()])),
- slug: joi.string().required(),
typescript: joi.object().keys({
interface: joi.string(),
}),
diff --git a/packages/payload/src/globals/config/types.ts b/packages/payload/src/globals/config/types.ts
index 29a00aee5b..af41c11575 100644
--- a/packages/payload/src/globals/config/types.ts
+++ b/packages/payload/src/globals/config/types.ts
@@ -17,8 +17,8 @@ import type {
GeneratePreviewURL,
LivePreviewConfig,
} from '../../config/types'
-import type { PayloadRequest } from '../../express/types'
-import type { RequestContext } from '../../express/types'
+import type { DBIdentifierName } from '../../database/types'
+import type { PayloadRequest, RequestContext } from '../../express/types'
import type { Field } from '../../fields/config/types'
import type { Where } from '../../types'
import type { IncomingGlobalVersions, SanitizedGlobalVersions } from '../../versions/types'
@@ -170,6 +170,10 @@ export type GlobalConfig = {
admin?: GlobalAdminOptions
/** Extension point to add your custom data. */
custom?: Record
+ /**
+ * Customize the SQL table name
+ */
+ dbName?: DBIdentifierName
endpoints?: Omit[] | false
fields: Field[]
graphQL?:
diff --git a/packages/payload/src/versions/getVersionsModelName.ts b/packages/payload/src/versions/getVersionsModelName.ts
index 73db669901..fd286511e4 100644
--- a/packages/payload/src/versions/getVersionsModelName.ts
+++ b/packages/payload/src/versions/getVersionsModelName.ts
@@ -1,6 +1,11 @@
import type { SanitizedCollectionConfig } from '../collections/config/types'
import type { SanitizedGlobalConfig } from '../globals/config/types'
+/**
+ * This function is not being used and will no longer be exported in the future
+ * @deprecated
+ * @param entity
+ */
export const getVersionsModelName = (
entity: SanitizedCollectionConfig | SanitizedGlobalConfig,
): string => `_${entity.slug}_versions`
diff --git a/test/database/config.ts b/test/database/config.ts
index 68431a8855..573079b2e5 100644
--- a/test/database/config.ts
+++ b/test/database/config.ts
@@ -63,7 +63,98 @@ export default buildConfigWithDefaults({
singular: 'Relation B',
},
},
+ {
+ slug: 'custom-schema',
+ dbName: 'customs',
+ fields: [
+ {
+ name: 'text',
+ type: 'text',
+ },
+ {
+ name: 'localizedText',
+ type: 'text',
+ localized: true,
+ },
+ {
+ name: 'relationship',
+ type: 'relationship',
+ hasMany: true,
+ relationTo: 'relation-a',
+ },
+ {
+ name: 'select',
+ type: 'select',
+ dbName: ({ tableName }) => `${tableName}_customSelect`,
+ enumName: 'selectEnum',
+ hasMany: true,
+ options: ['a', 'b', 'c'],
+ },
+ {
+ name: 'radio',
+ type: 'select',
+ enumName: 'radioEnum',
+ options: ['a', 'b', 'c'],
+ },
+ {
+ name: 'array',
+ type: 'array',
+ dbName: 'customArrays',
+ fields: [
+ {
+ name: 'text',
+ type: 'text',
+ },
+ {
+ name: 'localizedText',
+ type: 'text',
+ localized: true,
+ },
+ ],
+ },
+ {
+ name: 'blocks',
+ type: 'blocks',
+ blocks: [
+ {
+ slug: 'block',
+ dbName: 'customBlocks',
+ fields: [
+ {
+ name: 'text',
+ type: 'text',
+ },
+ {
+ name: 'localizedText',
+ type: 'text',
+ localized: true,
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ versions: true,
+ },
],
+ globals: [
+ {
+ slug: 'global',
+ // @ts-expect-error
+ dbName: 'customGlobal',
+ fields: [
+ {
+ name: 'text',
+ type: 'text',
+ },
+ ],
+ versions: true,
+ },
+ ],
+ localization: {
+ defaultLocale: 'en',
+ locales: ['en', 'es'],
+ },
onInit: async (payload) => {
await payload.create({
collection: 'users',
diff --git a/test/database/int.spec.ts b/test/database/int.spec.ts
index d0bf40435c..5938fc6122 100644
--- a/test/database/int.spec.ts
+++ b/test/database/int.spec.ts
@@ -3,6 +3,7 @@ import fs from 'fs'
import { GraphQLClient } from 'graphql-request'
import path from 'path'
+import type { PostgresAdapter } from '../../packages/db-postgres/src/types'
import type { PostgresAdapter } from '../../packages/db-postgres/src/types'
import type { TypeWithID } from '../../packages/payload/src/collections/config/types'
import type { PayloadRequest } from '../../packages/payload/src/express/types'
@@ -14,6 +15,7 @@ import { initTransaction } from '../../packages/payload/src/utilities/initTransa
import { devUser } from '../credentials'
import { initPayloadTest } from '../helpers/configHelpers'
import removeFiles from '../helpers/removeFiles'
+import { MongooseAdapter } from '../../packages/db-mongodb/src'
describe('database', () => {
let serverURL
@@ -140,6 +142,59 @@ describe('database', () => {
})
})
+ describe('schema', () => {
+ it('should use custom dbNames', () => {
+ expect(payload.db).toBeDefined()
+
+ if (payload.db.name === 'mongoose') {
+ // @ts-expect-error
+ const db: MongooseAdapter = payload.db
+
+ expect(db.collections['custom-schema'].modelName).toStrictEqual('customs')
+ expect(db.versions['custom-schema'].modelName).toStrictEqual('_customs_versions')
+ expect(db.versions.global.modelName).toStrictEqual('_customGlobal_versions')
+ } else {
+ // @ts-expect-error
+ const db: PostgresAdapter = payload.db
+
+ // collection
+ expect(db.tables.customs).toBeDefined()
+
+ // collection versions
+ expect(db.tables._customs_v).toBeDefined()
+
+ // collection relationships
+ expect(db.tables.customs_rels).toBeDefined()
+
+ // collection localized
+ expect(db.tables.customs_locales).toBeDefined()
+
+ // global
+ expect(db.tables.customGlobal).toBeDefined()
+ expect(db.tables._customGlobal_v).toBeDefined()
+
+ // select
+ expect(db.tables.customs_customSelect).toBeDefined()
+
+ // array
+ expect(db.tables.customArrays).toBeDefined()
+
+ // array localized
+ expect(db.tables.customArrays_locales).toBeDefined()
+
+ // blocks
+ expect(db.tables.customBlocks).toBeDefined()
+
+ // localized blocks
+ expect(db.tables.customBlocks_locales).toBeDefined()
+
+ // enum names
+ expect(db.enums.selectEnum).toBeDefined()
+ expect(db.enums.radioEnum).toBeDefined()
+ }
+ })
+ })
+
describe('transactions', () => {
describe('local api', () => {
it('should commit multiple operations in isolation', async () => {