Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/db-mongodb/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {
import mongoose from 'mongoose'
import { createDatabaseAdapter, defaultBeginTransaction, findMigrationDir } from 'payload'

import type { MongooseIDType } from './models/buildSchema.js'
import type {
CollectionModel,
GlobalModel,
Expand Down Expand Up @@ -146,6 +147,10 @@ export interface Args {
* NOTE: not recommended for production. This can slow down the initialization of Payload.
*/
ensureIndexes?: boolean
/**
* The type to use for IDs in MongoDB. Can be `String`, `Number`, `mongoose.Schema.Types.ObjectId`, or `mongoose.Schema.Types.BigInt`. Defaults to `String`.
*/
idType?: MongooseIDType
migrationDir?: string
/**
* typed as any to avoid dependency
Expand Down Expand Up @@ -262,6 +267,7 @@ export function mongooseAdapter({
disableFallbackSort = false,
disableIndexHints = false,
ensureIndexes = false,
idType: mongooseIDType,
migrationDir: migrationDirArg,
mongoMemoryServer,
prodMigrations,
Expand Down Expand Up @@ -328,6 +334,7 @@ export function mongooseAdapter({
findGlobalVersions,
findOne,
findVersions,
idType: mongooseIDType,
init,
migrateFresh,
migrationDir,
Expand Down
4 changes: 3 additions & 1 deletion packages/db-mongodb/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const init: Init = async function init(this: MongooseAdapter) {
this.payload.config.collections.forEach((collection: SanitizedCollectionConfig) => {
const schemaOptions = this.collectionsSchemaOptions?.[collection.slug]

const schema = buildCollectionSchema(collection, this.payload, schemaOptions)
const schema = buildCollectionSchema(collection, this.payload, schemaOptions, this.idType)
if (collection.versions) {
const versionModelName = getDBName({ config: collection, versions: true })

Expand All @@ -40,6 +40,7 @@ export const init: Init = async function init(this: MongooseAdapter) {
buildSchemaOptions: {
disableUnique: true,
draftsEnabled: true,
idType: this.idType,
indexSortableFields: this.payload.config.indexSortableFields,
options: {
minimize: false,
Expand Down Expand Up @@ -92,6 +93,7 @@ export const init: Init = async function init(this: MongooseAdapter) {
buildSchemaOptions: {
disableUnique: true,
draftsEnabled: true,
idType: this.idType,
indexSortableFields: this.payload.config.indexSortableFields,
options: {
minimize: false,
Expand Down
4 changes: 4 additions & 0 deletions packages/db-mongodb/src/models/buildCollectionSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ import type { Payload, SanitizedCollectionConfig } from 'payload'

import paginate from 'mongoose-paginate-v2'

import type { MongooseIDType } from './buildSchema.js'

import { getBuildQueryPlugin } from '../queries/getBuildQueryPlugin.js'
import { buildSchema } from './buildSchema.js'

export const buildCollectionSchema = (
collection: SanitizedCollectionConfig,
payload: Payload,
schemaOptions = {},
idType?: MongooseIDType,
): Schema => {
const schema = buildSchema({
buildSchemaOptions: {
draftsEnabled: Boolean(
typeof collection?.versions === 'object' && collection.versions.drafts,
),
idType,
indexSortableFields: payload.config.indexSortableFields,
options: {
minimize: false,
Expand Down
41 changes: 35 additions & 6 deletions packages/db-mongodb/src/models/buildSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,18 @@ import {
tabHasName,
} from 'payload/shared'

export type MongooseIDType =
| typeof mongoose.Schema.Types.BigInt
| typeof mongoose.Schema.Types.ObjectId
| typeof mongoose.Schema.Types.UUID
| typeof Number
| typeof String

export type BuildSchemaOptions = {
allowIDField?: boolean
disableUnique?: boolean
draftsEnabled?: boolean
idType?: MongooseIDType
indexSortableFields?: boolean
options?: SchemaOptions
}
Expand All @@ -64,6 +72,20 @@ const formatDefaultValue = (field: FieldAffectingData) =>
? field.defaultValue
: undefined

const getIdFieldSchema = (idType: MongooseIDType): SchemaTypeOptions<unknown> => {
const baseSchema: SchemaTypeOptions<unknown> = {
type: idType,
required: true,
}

// UUID types need a default generator
if (idType === mongoose.Schema.Types.UUID) {
baseSchema.default = () => new mongoose.Types.UUID()
}

return baseSchema
}

const formatBaseSchema = ({
buildSchemaOptions,
field,
Expand Down Expand Up @@ -152,17 +174,24 @@ export const buildSchema = (args: {
const fieldsToSearch = flattenedFields || schemaFields
const idField = fieldsToSearch.find((field) => fieldAffectsData(field) && field.name === 'id')
if (idField) {
const idType =
idField.type === 'number'
? payload.db.useBigIntForNumberIDs
? mongoose.Schema.Types.BigInt
: Number
: buildSchemaOptions.idType
? buildSchemaOptions.idType
: String
fields = {
_id:
idField.type === 'number'
? payload.db.useBigIntForNumberIDs
? mongoose.Schema.Types.BigInt
: Number
: String,
_id: getIdFieldSchema(idType),
}
schemaFields = schemaFields.filter(
(field) => !(fieldAffectsData(field) && field.name === 'id'),
)
} else if (buildSchemaOptions.idType) {
fields = {
_id: getIdFieldSchema(buildSchemaOptions.idType),
}
}
}

Expand Down