@payloadcms/db-mongodb 3.25.0-canary.f62445f → 3.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create.js +15 -15
- package/dist/create.js.map +1 -1
- package/dist/createGlobal.d.ts.map +1 -1
- package/dist/createGlobal.js +15 -14
- package/dist/createGlobal.js.map +1 -1
- package/dist/createGlobalVersion.d.ts.map +1 -1
- package/dist/createGlobalVersion.js +26 -23
- package/dist/createGlobalVersion.js.map +1 -1
- package/dist/createVersion.d.ts.map +1 -1
- package/dist/createVersion.js +26 -31
- package/dist/createVersion.js.map +1 -1
- package/dist/deleteOne.d.ts.map +1 -1
- package/dist/deleteOne.js +8 -6
- package/dist/deleteOne.js.map +1 -1
- package/dist/find.d.ts.map +1 -1
- package/dist/find.js +8 -9
- package/dist/find.js.map +1 -1
- package/dist/findGlobal.d.ts.map +1 -1
- package/dist/findGlobal.js +10 -9
- package/dist/findGlobal.js.map +1 -1
- package/dist/findGlobalVersions.d.ts.map +1 -1
- package/dist/findGlobalVersions.js +10 -10
- package/dist/findGlobalVersions.js.map +1 -1
- package/dist/findOne.d.ts.map +1 -1
- package/dist/findOne.js +8 -6
- package/dist/findOne.js.map +1 -1
- package/dist/findVersions.js +8 -9
- package/dist/findVersions.js.map +1 -1
- package/dist/models/buildSchema.js +2 -0
- package/dist/models/buildSchema.js.map +1 -1
- package/dist/predefinedMigrations/migrateRelationshipsV2_V3.d.ts.map +1 -1
- package/dist/predefinedMigrations/migrateRelationshipsV2_V3.js +12 -7
- package/dist/predefinedMigrations/migrateRelationshipsV2_V3.js.map +1 -1
- package/dist/queries/buildSearchParams.d.ts.map +1 -1
- package/dist/queries/buildSearchParams.js +16 -0
- package/dist/queries/buildSearchParams.js.map +1 -1
- package/dist/queryDrafts.js +13 -13
- package/dist/queryDrafts.js.map +1 -1
- package/dist/updateGlobal.d.ts.map +1 -1
- package/dist/updateGlobal.js +15 -15
- package/dist/updateGlobal.js.map +1 -1
- package/dist/updateGlobalVersion.d.ts.map +1 -1
- package/dist/updateGlobalVersion.js +13 -13
- package/dist/updateGlobalVersion.js.map +1 -1
- package/dist/updateOne.d.ts.map +1 -1
- package/dist/updateOne.js +12 -9
- package/dist/updateOne.js.map +1 -1
- package/dist/updateVersion.d.ts.map +1 -1
- package/dist/updateVersion.js +13 -13
- package/dist/updateVersion.js.map +1 -1
- package/dist/utilities/buildJoinAggregation.d.ts.map +1 -1
- package/dist/utilities/buildJoinAggregation.js +103 -34
- package/dist/utilities/buildJoinAggregation.js.map +1 -1
- package/dist/utilities/transform.d.ts +27 -0
- package/dist/utilities/transform.d.ts.map +1 -0
- package/dist/utilities/transform.js +224 -0
- package/dist/utilities/transform.js.map +1 -0
- package/dist/utilities/{sanitizeRelationshipIDs.spec.js → transform.spec.js} +11 -5
- package/dist/utilities/transform.spec.js.map +1 -0
- package/package.json +3 -3
- package/dist/utilities/sanitizeInternalFields.d.ts +0 -2
- package/dist/utilities/sanitizeInternalFields.d.ts.map +0 -1
- package/dist/utilities/sanitizeInternalFields.js +0 -20
- package/dist/utilities/sanitizeInternalFields.js.map +0 -1
- package/dist/utilities/sanitizeRelationshipIDs.d.ts +0 -10
- package/dist/utilities/sanitizeRelationshipIDs.d.ts.map +0 -1
- package/dist/utilities/sanitizeRelationshipIDs.js +0 -130
- package/dist/utilities/sanitizeRelationshipIDs.js.map +0 -1
- package/dist/utilities/sanitizeRelationshipIDs.spec.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/buildJoinAggregation.ts"],"sourcesContent":["import type { PipelineStage } from 'mongoose'\nimport type {\n CollectionSlug,\n FlattenedField,\n JoinQuery,\n SanitizedCollectionConfig,\n Where,\n} from 'payload'\n\nimport { fieldShouldBeLocalized } from 'payload/shared'\n\nimport type { MongooseAdapter } from '../index.js'\n\nimport { buildQuery } from '../queries/buildQuery.js'\nimport { buildSortParam } from '../queries/buildSortParam.js'\n\ntype BuildJoinAggregationArgs = {\n adapter: MongooseAdapter\n collection: CollectionSlug\n collectionConfig: SanitizedCollectionConfig\n joins: JoinQuery\n // the number of docs to get at the top collection level\n limit?: number\n locale: string\n projection?: Record<string, true>\n // the where clause for the top collection\n query?: Where\n /** whether the query is from drafts */\n versions?: boolean\n}\n\nexport const buildJoinAggregation = async ({\n adapter,\n collection,\n collectionConfig,\n joins,\n limit,\n locale,\n projection,\n query,\n versions,\n}: BuildJoinAggregationArgs): Promise<PipelineStage[] | undefined> => {\n if (\n (Object.keys(collectionConfig.joins).length === 0 &&\n collectionConfig.polymorphicJoins.length == 0) ||\n joins === false\n ) {\n return\n }\n\n const joinConfig = adapter.payload.collections[collection].config.joins\n const polymorphicJoinsConfig = adapter.payload.collections[collection].config.polymorphicJoins\n const aggregate: PipelineStage[] = [\n {\n $sort: { createdAt: -1 },\n },\n ]\n\n if (query) {\n aggregate.push({\n $match: query,\n })\n }\n\n if (limit) {\n aggregate.push({\n $limit: limit,\n })\n }\n\n for (const join of polymorphicJoinsConfig) {\n if (projection && !projection[join.joinPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const {\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin,\n } = joins?.[join.joinPath] || {}\n\n const aggregatedFields: FlattenedField[] = []\n for (const collectionSlug of join.field.collection) {\n for (const field of adapter.payload.collections[collectionSlug].config.flattenedFields) {\n if (!aggregatedFields.some((eachField) => eachField.name === field.name)) {\n aggregatedFields.push(field)\n }\n }\n }\n\n const sort = buildSortParam({\n config: adapter.payload.config,\n fields: aggregatedFields,\n locale,\n sort: sortJoin,\n timestamps: true,\n })\n\n const $match = await buildQuery({\n adapter,\n fields: aggregatedFields,\n locale,\n where: whereJoin,\n })\n\n const sortProperty = Object.keys(sort)[0]\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n const projectSort = sortProperty !== '_id' && sortProperty !== 'relationTo'\n\n const aliases: string[] = []\n\n const as = join.joinPath\n\n for (const collectionSlug of join.field.collection) {\n const alias = `${as}.docs.${collectionSlug}`\n aliases.push(alias)\n\n aggregate.push({\n $lookup: {\n as: alias,\n from: adapter.collections[collectionSlug].collection.name,\n let: {\n root_id_: '$_id',\n },\n pipeline: [\n {\n $addFields: {\n relationTo: {\n $literal: collectionSlug,\n },\n },\n },\n {\n $match: {\n $and: [\n {\n $expr: {\n $eq: [`$${join.field.on}`, '$$root_id_'],\n },\n },\n $match,\n ],\n },\n },\n {\n $sort: {\n [sortProperty]: sortDirection,\n },\n },\n {\n // Unfortunately, we can't use $skip here because we can lose data, instead we do $slice then\n $limit: page ? page * limitJoin : limitJoin,\n },\n {\n $project: {\n value: '$_id',\n ...(projectSort && {\n [sortProperty]: 1,\n }),\n relationTo: 1,\n },\n },\n ],\n },\n })\n }\n\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $concatArrays: aliases.map((alias) => `$${alias}`),\n },\n },\n })\n\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $sortArray: {\n input: `$${as}.docs`,\n sortBy: {\n [sortProperty]: sortDirection,\n },\n },\n },\n },\n })\n\n const sliceValue = page ? [(page - 1) * limitJoin, limitJoin] : [limitJoin]\n\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, ...sliceValue],\n },\n },\n })\n\n aggregate.push({\n $addFields: {\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n },\n },\n })\n }\n\n for (const slug of Object.keys(joinConfig)) {\n for (const join of joinConfig[slug]) {\n if (projection && !projection[join.joinPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const {\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin,\n } = joins?.[join.joinPath] || {}\n\n if (Array.isArray(join.field.collection)) {\n throw new Error('Unreachable')\n }\n\n const joinModel = adapter.collections[join.field.collection]\n\n const sort = buildSortParam({\n config: adapter.payload.config,\n fields: adapter.payload.collections[slug].config.flattenedFields,\n locale,\n sort: sortJoin,\n timestamps: true,\n })\n const sortProperty = Object.keys(sort)[0]\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n const $match = await joinModel.buildQuery({\n locale,\n payload: adapter.payload,\n where: whereJoin,\n })\n\n const pipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [\n { $match },\n {\n $sort: { [sortProperty]: sortDirection },\n },\n ]\n\n if (page) {\n pipeline.push({\n $skip: (page - 1) * limitJoin,\n })\n }\n\n if (limitJoin > 0) {\n pipeline.push({\n $limit: limitJoin + 1,\n })\n }\n\n let polymorphicSuffix = ''\n if (Array.isArray(join.targetField.relationTo)) {\n polymorphicSuffix = '.value'\n }\n\n if (adapter.payload.config.localization && locale === 'all') {\n adapter.payload.config.localization.localeCodes.forEach((code) => {\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${code}`\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField: `${join.field.on}${code}${polymorphicSuffix}`,\n from: adapter.collections[slug].collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: limitJoin\n ? { $gt: [{ $size: `$${as}.docs` }, limitJoin] }\n : false,\n // Boolean indicating if more docs than limit\n },\n },\n )\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n })\n } else {\n const localeSuffix =\n fieldShouldBeLocalized({\n field: join.field,\n parentIsLocalized: join.parentIsLocalized,\n }) &&\n adapter.payload.config.localization &&\n locale\n ? `.${locale}`\n : ''\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${localeSuffix}`\n\n let foreignField: string\n\n if (join.getForeignPath) {\n foreignField = `${join.getForeignPath({ locale })}${polymorphicSuffix}`\n } else {\n foreignField = `${join.field.on}${polymorphicSuffix}`\n }\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField,\n from: adapter.collections[slug].collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n }, // Boolean indicating if more docs than limit\n },\n },\n )\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n }\n }\n }\n\n if (projection) {\n aggregate.push({ $project: projection })\n }\n\n return aggregate\n}\n"],"names":["fieldShouldBeLocalized","buildQuery","buildSortParam","buildJoinAggregation","adapter","collection","collectionConfig","joins","limit","locale","projection","query","versions","Object","keys","length","polymorphicJoins","joinConfig","payload","collections","config","polymorphicJoinsConfig","aggregate","$sort","createdAt","push","$match","$limit","join","joinPath","limitJoin","field","defaultLimit","page","sort","sortJoin","defaultSort","where","whereJoin","aggregatedFields","collectionSlug","flattenedFields","some","eachField","name","fields","timestamps","sortProperty","sortDirection","projectSort","aliases","as","alias","$lookup","from","let","root_id_","pipeline","$addFields","relationTo","$literal","$and","$expr","$eq","on","$project","value","$concatArrays","map","$set","$sortArray","input","sortBy","sliceValue","$slice","$gt","$size","Number","MAX_VALUE","slug","Array","isArray","Error","joinModel","$skip","polymorphicSuffix","targetField","localization","localeCodes","forEach","code","foreignField","localField","$map","in","localeSuffix","parentIsLocalized","getForeignPath"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/buildJoinAggregation.ts"],"sourcesContent":["import type { PipelineStage } from 'mongoose'\nimport type {\n CollectionSlug,\n FlattenedField,\n JoinQuery,\n SanitizedCollectionConfig,\n Where,\n} from 'payload'\n\nimport { fieldShouldBeLocalized } from 'payload/shared'\n\nimport type { MongooseAdapter } from '../index.js'\n\nimport { buildQuery } from '../queries/buildQuery.js'\nimport { buildSortParam } from '../queries/buildSortParam.js'\n\ntype BuildJoinAggregationArgs = {\n adapter: MongooseAdapter\n collection: CollectionSlug\n collectionConfig: SanitizedCollectionConfig\n joins: JoinQuery\n // the number of docs to get at the top collection level\n limit?: number\n locale: string\n projection?: Record<string, true>\n // the where clause for the top collection\n query?: Where\n /** whether the query is from drafts */\n versions?: boolean\n}\n\nexport const buildJoinAggregation = async ({\n adapter,\n collection,\n collectionConfig,\n joins,\n limit,\n locale,\n projection,\n query,\n versions,\n}: BuildJoinAggregationArgs): Promise<PipelineStage[] | undefined> => {\n if (\n (Object.keys(collectionConfig.joins).length === 0 &&\n collectionConfig.polymorphicJoins.length == 0) ||\n joins === false\n ) {\n return\n }\n\n const joinConfig = adapter.payload.collections[collection].config.joins\n const polymorphicJoinsConfig = adapter.payload.collections[collection].config.polymorphicJoins\n const aggregate: PipelineStage[] = [\n {\n $sort: { createdAt: -1 },\n },\n ]\n\n if (query) {\n aggregate.push({\n $match: query,\n })\n }\n\n if (limit) {\n aggregate.push({\n $limit: limit,\n })\n }\n\n for (const join of polymorphicJoinsConfig) {\n if (projection && !projection[join.joinPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const {\n count = false,\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin,\n } = joins?.[join.joinPath] || {}\n\n const aggregatedFields: FlattenedField[] = []\n for (const collectionSlug of join.field.collection) {\n for (const field of adapter.payload.collections[collectionSlug].config.flattenedFields) {\n if (!aggregatedFields.some((eachField) => eachField.name === field.name)) {\n aggregatedFields.push(field)\n }\n }\n }\n\n const sort = buildSortParam({\n config: adapter.payload.config,\n fields: aggregatedFields,\n locale,\n sort: sortJoin,\n timestamps: true,\n })\n\n const $match = await buildQuery({\n adapter,\n fields: aggregatedFields,\n locale,\n where: whereJoin,\n })\n\n const sortProperty = Object.keys(sort)[0]\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n const projectSort = sortProperty !== '_id' && sortProperty !== 'relationTo'\n\n const aliases: string[] = []\n\n const as = join.joinPath\n\n for (const collectionSlug of join.field.collection) {\n const alias = `${as}.docs.${collectionSlug}`\n aliases.push(alias)\n\n const basePipeline = [\n {\n $addFields: {\n relationTo: {\n $literal: collectionSlug,\n },\n },\n },\n {\n $match: {\n $and: [\n {\n $expr: {\n $eq: [`$${join.field.on}`, '$$root_id_'],\n },\n },\n $match,\n ],\n },\n },\n ]\n\n aggregate.push({\n $lookup: {\n as: alias,\n from: adapter.collections[collectionSlug].collection.name,\n let: {\n root_id_: '$_id',\n },\n pipeline: [\n ...basePipeline,\n {\n $sort: {\n [sortProperty]: sortDirection,\n },\n },\n {\n // Unfortunately, we can't use $skip here because we can lose data, instead we do $slice then\n $limit: page ? page * limitJoin : limitJoin,\n },\n {\n $project: {\n value: '$_id',\n ...(projectSort && {\n [sortProperty]: 1,\n }),\n relationTo: 1,\n },\n },\n ],\n },\n })\n\n if (count) {\n aggregate.push({\n $lookup: {\n as: `${as}.totalDocs.${alias}`,\n from: adapter.collections[collectionSlug].collection.name,\n let: {\n root_id_: '$_id',\n },\n pipeline: [\n ...basePipeline,\n {\n $count: 'result',\n },\n ],\n },\n })\n }\n }\n\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $concatArrays: aliases.map((alias) => `$${alias}`),\n },\n },\n })\n\n if (count) {\n aggregate.push({\n $addFields: {\n [`${as}.totalDocs`]: {\n $add: aliases.map((alias) => ({\n $ifNull: [\n {\n $first: `$${as}.totalDocs.${alias}.result`,\n },\n 0,\n ],\n })),\n },\n },\n })\n }\n\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $sortArray: {\n input: `$${as}.docs`,\n sortBy: {\n [sortProperty]: sortDirection,\n },\n },\n },\n },\n })\n\n const sliceValue = page ? [(page - 1) * limitJoin, limitJoin] : [limitJoin]\n\n aggregate.push({\n $addFields: {\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n },\n },\n })\n\n aggregate.push({\n $set: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, ...sliceValue],\n },\n },\n })\n }\n\n for (const slug of Object.keys(joinConfig)) {\n for (const join of joinConfig[slug]) {\n if (projection && !projection[join.joinPath]) {\n continue\n }\n\n if (joins?.[join.joinPath] === false) {\n continue\n }\n\n const {\n count,\n limit: limitJoin = join.field.defaultLimit ?? 10,\n page,\n sort: sortJoin = join.field.defaultSort || collectionConfig.defaultSort,\n where: whereJoin,\n } = joins?.[join.joinPath] || {}\n\n if (Array.isArray(join.field.collection)) {\n throw new Error('Unreachable')\n }\n\n const joinModel = adapter.collections[join.field.collection]\n\n const sort = buildSortParam({\n config: adapter.payload.config,\n fields: adapter.payload.collections[slug].config.flattenedFields,\n locale,\n sort: sortJoin,\n timestamps: true,\n })\n const sortProperty = Object.keys(sort)[0]\n const sortDirection = sort[sortProperty] === 'asc' ? 1 : -1\n\n const $match = await joinModel.buildQuery({\n locale,\n payload: adapter.payload,\n where: whereJoin,\n })\n\n const pipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [\n { $match },\n {\n $sort: { [sortProperty]: sortDirection },\n },\n ]\n\n if (page) {\n pipeline.push({\n $skip: (page - 1) * limitJoin,\n })\n }\n\n if (limitJoin > 0) {\n pipeline.push({\n $limit: limitJoin + 1,\n })\n }\n\n let polymorphicSuffix = ''\n if (Array.isArray(join.targetField.relationTo)) {\n polymorphicSuffix = '.value'\n }\n\n const addTotalDocsAggregation = (as: string, foreignField: string) =>\n aggregate.push(\n {\n $lookup: {\n as: `${as}.totalDocs`,\n foreignField,\n from: adapter.collections[slug].collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline: [\n {\n $match,\n },\n {\n $count: 'result',\n },\n ],\n },\n },\n {\n $addFields: {\n [`${as}.totalDocs`]: { $ifNull: [{ $first: `$${as}.totalDocs.result` }, 0] },\n },\n },\n )\n\n if (adapter.payload.config.localization && locale === 'all') {\n adapter.payload.config.localization.localeCodes.forEach((code) => {\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${code}`\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField: `${join.field.on}${code}${polymorphicSuffix}`,\n from: adapter.collections[slug].collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: limitJoin\n ? { $gt: [{ $size: `$${as}.docs` }, limitJoin] }\n : false,\n // Boolean indicating if more docs than limit\n },\n },\n )\n\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n\n if (count) {\n addTotalDocsAggregation(as, `${join.field.on}${code}${polymorphicSuffix}`)\n }\n })\n } else {\n const localeSuffix =\n fieldShouldBeLocalized({\n field: join.field,\n parentIsLocalized: join.parentIsLocalized,\n }) &&\n adapter.payload.config.localization &&\n locale\n ? `.${locale}`\n : ''\n const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${localeSuffix}`\n\n let foreignField: string\n\n if (join.getForeignPath) {\n foreignField = `${join.getForeignPath({ locale })}${polymorphicSuffix}`\n } else {\n foreignField = `${join.field.on}${polymorphicSuffix}`\n }\n\n aggregate.push(\n {\n $lookup: {\n as: `${as}.docs`,\n foreignField,\n from: adapter.collections[slug].collection.name,\n localField: versions ? 'parent' : '_id',\n pipeline,\n },\n },\n {\n $addFields: {\n [`${as}.docs`]: {\n $map: {\n as: 'doc',\n in: '$$doc._id',\n input: `$${as}.docs`,\n },\n }, // Slicing the docs to match the limit\n [`${as}.hasNextPage`]: {\n $gt: [{ $size: `$${as}.docs` }, limitJoin || Number.MAX_VALUE],\n }, // Boolean indicating if more docs than limit\n },\n },\n )\n\n if (count) {\n addTotalDocsAggregation(as, foreignField)\n }\n\n if (limitJoin > 0) {\n aggregate.push({\n $addFields: {\n [`${as}.docs`]: {\n $slice: [`$${as}.docs`, limitJoin],\n },\n },\n })\n }\n }\n }\n }\n\n if (projection) {\n aggregate.push({ $project: projection })\n }\n\n return aggregate\n}\n"],"names":["fieldShouldBeLocalized","buildQuery","buildSortParam","buildJoinAggregation","adapter","collection","collectionConfig","joins","limit","locale","projection","query","versions","Object","keys","length","polymorphicJoins","joinConfig","payload","collections","config","polymorphicJoinsConfig","aggregate","$sort","createdAt","push","$match","$limit","join","joinPath","count","limitJoin","field","defaultLimit","page","sort","sortJoin","defaultSort","where","whereJoin","aggregatedFields","collectionSlug","flattenedFields","some","eachField","name","fields","timestamps","sortProperty","sortDirection","projectSort","aliases","as","alias","basePipeline","$addFields","relationTo","$literal","$and","$expr","$eq","on","$lookup","from","let","root_id_","pipeline","$project","value","$count","$concatArrays","map","$add","$ifNull","$first","$set","$sortArray","input","sortBy","sliceValue","$gt","$size","Number","MAX_VALUE","$slice","slug","Array","isArray","Error","joinModel","$skip","polymorphicSuffix","targetField","addTotalDocsAggregation","foreignField","localField","localization","localeCodes","forEach","code","$map","in","localeSuffix","parentIsLocalized","getForeignPath"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Field } from 'payload';
|
|
2
|
+
import type { MongooseAdapter } from '../index.js';
|
|
3
|
+
type Args = {
|
|
4
|
+
/** instance of the adapter */
|
|
5
|
+
adapter: MongooseAdapter;
|
|
6
|
+
/** data to transform, can be an array of documents or a single document */
|
|
7
|
+
data: Record<string, unknown> | Record<string, unknown>[];
|
|
8
|
+
/** fields accossiated with the data */
|
|
9
|
+
fields: Field[];
|
|
10
|
+
/** slug of the global, pass only when the operation is `write` */
|
|
11
|
+
globalSlug?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Type of the operation
|
|
14
|
+
* read - sanitizes ObjectIDs, Date to strings.
|
|
15
|
+
* write - sanitizes string relationships to ObjectIDs.
|
|
16
|
+
*/
|
|
17
|
+
operation: 'read' | 'write';
|
|
18
|
+
parentIsLocalized?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Throw errors on invalid relationships
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
validateRelationships?: boolean;
|
|
24
|
+
};
|
|
25
|
+
export declare const transform: ({ adapter, data, fields, globalSlug, operation, parentIsLocalized, validateRelationships, }: Args) => void;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/utilities/transform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,KAAK,EAMN,MAAM,SAAS,CAAA;AAMhB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAgMlD,KAAK,IAAI,GAAG;IACV,8BAA8B;IAC9B,OAAO,EAAE,eAAe,CAAA;IACxB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IACzD,uCAAuC;IACvC,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC,CAAA;AAED,eAAO,MAAM,SAAS,gGAQnB,IAAI,SA4GN,CAAA"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { Types } from 'mongoose';
|
|
2
|
+
import { traverseFields } from 'payload';
|
|
3
|
+
import { fieldAffectsData, fieldShouldBeLocalized } from 'payload/shared';
|
|
4
|
+
function isValidRelationObject(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null && 'relationTo' in value && 'value' in value;
|
|
6
|
+
}
|
|
7
|
+
const convertRelationshipValue = ({ operation, relatedCollection, validateRelationships, value })=>{
|
|
8
|
+
const customIDField = relatedCollection.fields.find((field)=>fieldAffectsData(field) && field.name === 'id');
|
|
9
|
+
if (operation === 'read') {
|
|
10
|
+
if (value instanceof Types.ObjectId) {
|
|
11
|
+
return value.toHexString();
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
if (customIDField) {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
if (typeof value === 'string') {
|
|
19
|
+
try {
|
|
20
|
+
return new Types.ObjectId(value);
|
|
21
|
+
} catch (e) {
|
|
22
|
+
if (validateRelationships) {
|
|
23
|
+
throw e;
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
};
|
|
30
|
+
const sanitizeRelationship = ({ config, field, locale, operation, ref, validateRelationships, value })=>{
|
|
31
|
+
if (field.type === 'join') {
|
|
32
|
+
if (operation === 'read' && value && typeof value === 'object' && 'docs' in value && Array.isArray(value.docs)) {
|
|
33
|
+
for(let i = 0; i < value.docs.length; i++){
|
|
34
|
+
const item = value.docs[i];
|
|
35
|
+
if (item instanceof Types.ObjectId) {
|
|
36
|
+
value.docs[i] = item.toHexString();
|
|
37
|
+
} else if (Array.isArray(field.collection) && item) {
|
|
38
|
+
// Fields here for polymorphic joins cannot be determinted, JSON.parse needed
|
|
39
|
+
value.docs[i] = JSON.parse(JSON.stringify(value.docs[i]));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
let relatedCollection;
|
|
46
|
+
let result = value;
|
|
47
|
+
const hasManyRelations = typeof field.relationTo !== 'string';
|
|
48
|
+
if (!hasManyRelations) {
|
|
49
|
+
relatedCollection = config.collections?.find(({ slug })=>slug === field.relationTo);
|
|
50
|
+
}
|
|
51
|
+
if (Array.isArray(value)) {
|
|
52
|
+
result = value.map((val)=>{
|
|
53
|
+
// Handle has many - polymorphic
|
|
54
|
+
if (isValidRelationObject(val)) {
|
|
55
|
+
const relatedCollectionForSingleValue = config.collections?.find(({ slug })=>slug === val.relationTo);
|
|
56
|
+
if (relatedCollectionForSingleValue) {
|
|
57
|
+
return {
|
|
58
|
+
relationTo: val.relationTo,
|
|
59
|
+
value: convertRelationshipValue({
|
|
60
|
+
operation,
|
|
61
|
+
relatedCollection: relatedCollectionForSingleValue,
|
|
62
|
+
validateRelationships,
|
|
63
|
+
value: val.value
|
|
64
|
+
})
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (relatedCollection) {
|
|
69
|
+
return convertRelationshipValue({
|
|
70
|
+
operation,
|
|
71
|
+
relatedCollection,
|
|
72
|
+
validateRelationships,
|
|
73
|
+
value: val
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return val;
|
|
77
|
+
});
|
|
78
|
+
} else if (isValidRelationObject(value)) {
|
|
79
|
+
relatedCollection = config.collections?.find(({ slug })=>slug === value.relationTo);
|
|
80
|
+
if (relatedCollection) {
|
|
81
|
+
result = {
|
|
82
|
+
relationTo: value.relationTo,
|
|
83
|
+
value: convertRelationshipValue({
|
|
84
|
+
operation,
|
|
85
|
+
relatedCollection,
|
|
86
|
+
validateRelationships,
|
|
87
|
+
value: value.value
|
|
88
|
+
})
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
} else if (relatedCollection) {
|
|
92
|
+
result = convertRelationshipValue({
|
|
93
|
+
operation,
|
|
94
|
+
relatedCollection,
|
|
95
|
+
validateRelationships,
|
|
96
|
+
value
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (locale) {
|
|
100
|
+
ref[locale] = result;
|
|
101
|
+
} else {
|
|
102
|
+
ref[field.name] = result;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const sanitizeDate = ({ field, locale, ref, value })=>{
|
|
106
|
+
if (!value) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (value instanceof Date) {
|
|
110
|
+
value = value.toISOString();
|
|
111
|
+
}
|
|
112
|
+
if (locale) {
|
|
113
|
+
ref[locale] = value;
|
|
114
|
+
} else {
|
|
115
|
+
ref[field.name] = value;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
export const transform = ({ adapter, data, fields, globalSlug, operation, parentIsLocalized, validateRelationships = true })=>{
|
|
119
|
+
if (Array.isArray(data)) {
|
|
120
|
+
for(let i = 0; i < data.length; i++){
|
|
121
|
+
transform({
|
|
122
|
+
adapter,
|
|
123
|
+
data: data[i],
|
|
124
|
+
fields,
|
|
125
|
+
globalSlug,
|
|
126
|
+
operation,
|
|
127
|
+
validateRelationships
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const { payload: { config } } = adapter;
|
|
133
|
+
if (operation === 'read') {
|
|
134
|
+
delete data['__v'];
|
|
135
|
+
data.id = data._id;
|
|
136
|
+
delete data['_id'];
|
|
137
|
+
if (data.id instanceof Types.ObjectId) {
|
|
138
|
+
data.id = data.id.toHexString();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (operation === 'write' && globalSlug) {
|
|
142
|
+
data.globalType = globalSlug;
|
|
143
|
+
}
|
|
144
|
+
const sanitize = ({ field, ref })=>{
|
|
145
|
+
if (!ref || typeof ref !== 'object') {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (field.type === 'date' && operation === 'read' && ref[field.name]) {
|
|
149
|
+
if (config.localization && fieldShouldBeLocalized({
|
|
150
|
+
field,
|
|
151
|
+
parentIsLocalized
|
|
152
|
+
})) {
|
|
153
|
+
const fieldRef = ref[field.name];
|
|
154
|
+
if (!fieldRef || typeof fieldRef !== 'object') {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
for (const locale of config.localization.localeCodes){
|
|
158
|
+
sanitizeDate({
|
|
159
|
+
field,
|
|
160
|
+
ref: fieldRef,
|
|
161
|
+
value: fieldRef[locale]
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
sanitizeDate({
|
|
166
|
+
field,
|
|
167
|
+
ref: ref,
|
|
168
|
+
value: ref[field.name]
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (field.type === 'relationship' || field.type === 'upload' || operation === 'read' && field.type === 'join') {
|
|
173
|
+
if (!ref[field.name]) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// handle localized relationships
|
|
177
|
+
if (config.localization && fieldShouldBeLocalized({
|
|
178
|
+
field,
|
|
179
|
+
parentIsLocalized
|
|
180
|
+
})) {
|
|
181
|
+
const locales = config.localization.locales;
|
|
182
|
+
const fieldRef = ref[field.name];
|
|
183
|
+
if (typeof fieldRef !== 'object') {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
for (const { code } of locales){
|
|
187
|
+
const value = ref[field.name][code];
|
|
188
|
+
if (value) {
|
|
189
|
+
sanitizeRelationship({
|
|
190
|
+
config,
|
|
191
|
+
field,
|
|
192
|
+
locale: code,
|
|
193
|
+
operation,
|
|
194
|
+
ref: fieldRef,
|
|
195
|
+
validateRelationships,
|
|
196
|
+
value
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} else {
|
|
201
|
+
// handle non-localized relationships
|
|
202
|
+
sanitizeRelationship({
|
|
203
|
+
config,
|
|
204
|
+
field,
|
|
205
|
+
locale: undefined,
|
|
206
|
+
operation,
|
|
207
|
+
ref: ref,
|
|
208
|
+
validateRelationships,
|
|
209
|
+
value: ref[field.name]
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
traverseFields({
|
|
215
|
+
callback: sanitize,
|
|
216
|
+
config,
|
|
217
|
+
fields,
|
|
218
|
+
fillEmpty: false,
|
|
219
|
+
parentIsLocalized,
|
|
220
|
+
ref: data
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
//# sourceMappingURL=transform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/transform.ts"],"sourcesContent":["import type {\n CollectionConfig,\n DateField,\n Field,\n JoinField,\n RelationshipField,\n SanitizedConfig,\n TraverseFieldsCallback,\n UploadField,\n} from 'payload'\n\nimport { Types } from 'mongoose'\nimport { traverseFields } from 'payload'\nimport { fieldAffectsData, fieldShouldBeLocalized } from 'payload/shared'\n\nimport type { MongooseAdapter } from '../index.js'\n\ninterface RelationObject {\n relationTo: string\n value: number | string\n}\n\nfunction isValidRelationObject(value: unknown): value is RelationObject {\n return typeof value === 'object' && value !== null && 'relationTo' in value && 'value' in value\n}\n\nconst convertRelationshipValue = ({\n operation,\n relatedCollection,\n validateRelationships,\n value,\n}: {\n operation: Args['operation']\n relatedCollection: CollectionConfig\n validateRelationships?: boolean\n value: unknown\n}) => {\n const customIDField = relatedCollection.fields.find(\n (field) => fieldAffectsData(field) && field.name === 'id',\n )\n\n if (operation === 'read') {\n if (value instanceof Types.ObjectId) {\n return value.toHexString()\n }\n\n return value\n }\n\n if (customIDField) {\n return value\n }\n\n if (typeof value === 'string') {\n try {\n return new Types.ObjectId(value)\n } catch (e) {\n if (validateRelationships) {\n throw e\n }\n return value\n }\n }\n\n return value\n}\n\nconst sanitizeRelationship = ({\n config,\n field,\n locale,\n operation,\n ref,\n validateRelationships,\n value,\n}: {\n config: SanitizedConfig\n field: JoinField | RelationshipField | UploadField\n locale?: string\n operation: Args['operation']\n ref: Record<string, unknown>\n validateRelationships?: boolean\n value?: unknown\n}) => {\n if (field.type === 'join') {\n if (\n operation === 'read' &&\n value &&\n typeof value === 'object' &&\n 'docs' in value &&\n Array.isArray(value.docs)\n ) {\n for (let i = 0; i < value.docs.length; i++) {\n const item = value.docs[i]\n\n if (item instanceof Types.ObjectId) {\n value.docs[i] = item.toHexString()\n } else if (Array.isArray(field.collection) && item) {\n // Fields here for polymorphic joins cannot be determinted, JSON.parse needed\n value.docs[i] = JSON.parse(JSON.stringify(value.docs[i]))\n }\n }\n }\n\n return value\n }\n let relatedCollection: CollectionConfig | undefined\n let result = value\n\n const hasManyRelations = typeof field.relationTo !== 'string'\n\n if (!hasManyRelations) {\n relatedCollection = config.collections?.find(({ slug }) => slug === field.relationTo)\n }\n\n if (Array.isArray(value)) {\n result = value.map((val) => {\n // Handle has many - polymorphic\n if (isValidRelationObject(val)) {\n const relatedCollectionForSingleValue = config.collections?.find(\n ({ slug }) => slug === val.relationTo,\n )\n\n if (relatedCollectionForSingleValue) {\n return {\n relationTo: val.relationTo,\n value: convertRelationshipValue({\n operation,\n relatedCollection: relatedCollectionForSingleValue,\n validateRelationships,\n value: val.value,\n }),\n }\n }\n }\n\n if (relatedCollection) {\n return convertRelationshipValue({\n operation,\n relatedCollection,\n validateRelationships,\n value: val,\n })\n }\n\n return val\n })\n }\n // Handle has one - polymorphic\n else if (isValidRelationObject(value)) {\n relatedCollection = config.collections?.find(({ slug }) => slug === value.relationTo)\n\n if (relatedCollection) {\n result = {\n relationTo: value.relationTo,\n value: convertRelationshipValue({\n operation,\n relatedCollection,\n validateRelationships,\n value: value.value,\n }),\n }\n }\n }\n // Handle has one\n else if (relatedCollection) {\n result = convertRelationshipValue({\n operation,\n relatedCollection,\n validateRelationships,\n value,\n })\n }\n\n if (locale) {\n ref[locale] = result\n } else {\n ref[field.name] = result\n }\n}\n\nconst sanitizeDate = ({\n field,\n locale,\n ref,\n value,\n}: {\n field: DateField\n locale?: string\n ref: Record<string, unknown>\n value: unknown\n}) => {\n if (!value) {\n return\n }\n\n if (value instanceof Date) {\n value = value.toISOString()\n }\n\n if (locale) {\n ref[locale] = value\n } else {\n ref[field.name] = value\n }\n}\n\ntype Args = {\n /** instance of the adapter */\n adapter: MongooseAdapter\n /** data to transform, can be an array of documents or a single document */\n data: Record<string, unknown> | Record<string, unknown>[]\n /** fields accossiated with the data */\n fields: Field[]\n /** slug of the global, pass only when the operation is `write` */\n globalSlug?: string\n /**\n * Type of the operation\n * read - sanitizes ObjectIDs, Date to strings.\n * write - sanitizes string relationships to ObjectIDs.\n */\n operation: 'read' | 'write'\n parentIsLocalized?: boolean\n /**\n * Throw errors on invalid relationships\n * @default true\n */\n validateRelationships?: boolean\n}\n\nexport const transform = ({\n adapter,\n data,\n fields,\n globalSlug,\n operation,\n parentIsLocalized,\n validateRelationships = true,\n}: Args) => {\n if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n transform({ adapter, data: data[i], fields, globalSlug, operation, validateRelationships })\n }\n return\n }\n\n const {\n payload: { config },\n } = adapter\n\n if (operation === 'read') {\n delete data['__v']\n data.id = data._id\n delete data['_id']\n\n if (data.id instanceof Types.ObjectId) {\n data.id = data.id.toHexString()\n }\n }\n\n if (operation === 'write' && globalSlug) {\n data.globalType = globalSlug\n }\n\n const sanitize: TraverseFieldsCallback = ({ field, ref }) => {\n if (!ref || typeof ref !== 'object') {\n return\n }\n\n if (field.type === 'date' && operation === 'read' && ref[field.name]) {\n if (config.localization && fieldShouldBeLocalized({ field, parentIsLocalized })) {\n const fieldRef = ref[field.name]\n if (!fieldRef || typeof fieldRef !== 'object') {\n return\n }\n\n for (const locale of config.localization.localeCodes) {\n sanitizeDate({\n field,\n ref: fieldRef,\n value: fieldRef[locale],\n })\n }\n } else {\n sanitizeDate({\n field,\n ref: ref as Record<string, unknown>,\n value: ref[field.name],\n })\n }\n }\n\n if (\n field.type === 'relationship' ||\n field.type === 'upload' ||\n (operation === 'read' && field.type === 'join')\n ) {\n if (!ref[field.name]) {\n return\n }\n\n // handle localized relationships\n if (config.localization && fieldShouldBeLocalized({ field, parentIsLocalized })) {\n const locales = config.localization.locales\n const fieldRef = ref[field.name]\n if (typeof fieldRef !== 'object') {\n return\n }\n\n for (const { code } of locales) {\n const value = ref[field.name][code]\n if (value) {\n sanitizeRelationship({\n config,\n field,\n locale: code,\n operation,\n ref: fieldRef,\n validateRelationships,\n value,\n })\n }\n }\n } else {\n // handle non-localized relationships\n sanitizeRelationship({\n config,\n field,\n locale: undefined,\n operation,\n ref: ref as Record<string, unknown>,\n validateRelationships,\n value: ref[field.name],\n })\n }\n }\n }\n\n traverseFields({\n callback: sanitize,\n config,\n fields,\n fillEmpty: false,\n parentIsLocalized,\n ref: data,\n })\n}\n"],"names":["Types","traverseFields","fieldAffectsData","fieldShouldBeLocalized","isValidRelationObject","value","convertRelationshipValue","operation","relatedCollection","validateRelationships","customIDField","fields","find","field","name","ObjectId","toHexString","e","sanitizeRelationship","config","locale","ref","type","Array","isArray","docs","i","length","item","collection","JSON","parse","stringify","result","hasManyRelations","relationTo","collections","slug","map","val","relatedCollectionForSingleValue","sanitizeDate","Date","toISOString","transform","adapter","data","globalSlug","parentIsLocalized","payload","id","_id","globalType","sanitize","localization","fieldRef","localeCodes","locales","code","undefined","callback","fillEmpty"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { flattenAllFields } from 'payload';
|
|
2
2
|
import { Types } from 'mongoose';
|
|
3
|
-
import {
|
|
3
|
+
import { transform } from './transform.js';
|
|
4
4
|
const flattenRelationshipValues = (obj, prefix = '')=>{
|
|
5
5
|
return Object.keys(obj).reduce((acc, key)=>{
|
|
6
6
|
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
@@ -321,7 +321,7 @@ const relsData = {
|
|
|
321
321
|
]
|
|
322
322
|
}
|
|
323
323
|
};
|
|
324
|
-
describe('
|
|
324
|
+
describe('transform', ()=>{
|
|
325
325
|
it('should sanitize relationships', ()=>{
|
|
326
326
|
const data = {
|
|
327
327
|
...relsData,
|
|
@@ -453,8 +453,14 @@ describe('sanitizeRelationshipIDs', ()=>{
|
|
|
453
453
|
}
|
|
454
454
|
};
|
|
455
455
|
const flattenValuesBefore = Object.values(flattenRelationshipValues(data));
|
|
456
|
-
|
|
457
|
-
|
|
456
|
+
const mockAdapter = {
|
|
457
|
+
payload: {
|
|
458
|
+
config
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
transform({
|
|
462
|
+
adapter: mockAdapter,
|
|
463
|
+
operation: 'write',
|
|
458
464
|
data,
|
|
459
465
|
fields: config.collections[0].fields
|
|
460
466
|
});
|
|
@@ -466,4 +472,4 @@ describe('sanitizeRelationshipIDs', ()=>{
|
|
|
466
472
|
});
|
|
467
473
|
});
|
|
468
474
|
|
|
469
|
-
//# sourceMappingURL=
|
|
475
|
+
//# sourceMappingURL=transform.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/transform.spec.ts"],"sourcesContent":["import { flattenAllFields, type Field, type SanitizedConfig } from 'payload'\n\nimport { Types } from 'mongoose'\n\nimport { transform } from './transform.js'\nimport type { MongooseAdapter } from '../index.js'\n\nconst flattenRelationshipValues = (obj: Record<string, any>, prefix = ''): Record<string, any> => {\n return Object.keys(obj).reduce(\n (acc, key) => {\n const fullKey = prefix ? `${prefix}.${key}` : key\n const value = obj[key]\n\n if (value && typeof value === 'object' && !(value instanceof Types.ObjectId)) {\n Object.assign(acc, flattenRelationshipValues(value, fullKey))\n // skip relationTo and blockType\n } else if (!fullKey.endsWith('relationTo') && !fullKey.endsWith('blockType')) {\n acc[fullKey] = value\n }\n\n return acc\n },\n {} as Record<string, any>,\n )\n}\n\nconst relsFields: Field[] = [\n {\n name: 'rel_1',\n type: 'relationship',\n relationTo: 'rels',\n },\n {\n name: 'rel_1_l',\n type: 'relationship',\n localized: true,\n relationTo: 'rels',\n },\n {\n name: 'rel_2',\n type: 'relationship',\n hasMany: true,\n relationTo: 'rels',\n },\n {\n name: 'rel_2_l',\n type: 'relationship',\n hasMany: true,\n localized: true,\n relationTo: 'rels',\n },\n {\n name: 'rel_3',\n type: 'relationship',\n relationTo: ['rels'],\n },\n {\n name: 'rel_3_l',\n type: 'relationship',\n localized: true,\n relationTo: ['rels'],\n },\n {\n name: 'rel_4',\n type: 'relationship',\n hasMany: true,\n relationTo: ['rels'],\n },\n {\n name: 'rel_4_l',\n type: 'relationship',\n hasMany: true,\n localized: true,\n relationTo: ['rels'],\n },\n]\n\nconst referenceBlockFields: Field[] = [\n ...relsFields,\n {\n name: 'group',\n type: 'group',\n fields: relsFields,\n },\n {\n name: 'array',\n type: 'array',\n fields: relsFields,\n },\n]\n\nconst config = {\n blocks: [\n {\n slug: 'reference-block',\n fields: referenceBlockFields,\n flattenedFields: flattenAllFields({ fields: referenceBlockFields }),\n },\n ],\n collections: [\n {\n slug: 'docs',\n fields: [\n ...relsFields,\n {\n name: 'array',\n type: 'array',\n fields: [\n {\n name: 'array',\n type: 'array',\n fields: relsFields,\n },\n {\n name: 'blocks',\n type: 'blocks',\n blocks: [{ slug: 'block', fields: relsFields }],\n },\n ...relsFields,\n ],\n },\n {\n name: 'arrayLocalized',\n type: 'array',\n fields: [\n {\n name: 'array',\n type: 'array',\n fields: relsFields,\n },\n {\n name: 'blocks',\n type: 'blocks',\n blocks: [{ slug: 'block', fields: relsFields }],\n },\n ...relsFields,\n ],\n localized: true,\n },\n {\n name: 'blocks',\n type: 'blocks',\n blocks: [\n {\n slug: 'block',\n fields: [\n ...relsFields,\n {\n name: 'group',\n type: 'group',\n fields: relsFields,\n },\n {\n name: 'array',\n type: 'array',\n fields: relsFields,\n },\n ],\n },\n ],\n },\n {\n name: 'blockReferences',\n type: 'blocks',\n blockReferences: ['reference-block'],\n },\n {\n name: 'group',\n type: 'group',\n fields: [\n ...relsFields,\n {\n name: 'array',\n type: 'array',\n fields: relsFields,\n },\n ],\n },\n {\n name: 'groupLocalized',\n type: 'group',\n fields: [\n ...relsFields,\n {\n name: 'array',\n type: 'array',\n fields: relsFields,\n },\n ],\n localized: true,\n },\n {\n name: 'groupAndRow',\n type: 'group',\n fields: [\n {\n type: 'row',\n fields: [\n ...relsFields,\n {\n type: 'array',\n name: 'array',\n fields: relsFields,\n },\n ],\n },\n ],\n },\n {\n type: 'tabs',\n tabs: [\n {\n name: 'tab',\n fields: relsFields,\n },\n {\n name: 'tabLocalized',\n fields: relsFields,\n localized: true,\n },\n {\n label: 'another',\n fields: [\n {\n type: 'tabs',\n tabs: [\n {\n name: 'nestedTab',\n fields: relsFields,\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n {\n slug: 'rels',\n fields: [],\n },\n ],\n localization: {\n defaultLocale: 'en',\n localeCodes: ['en', 'es'],\n locales: [\n { code: 'en', label: 'EN' },\n { code: 'es', label: 'ES' },\n ],\n },\n} as SanitizedConfig\n\nconst relsData = {\n rel_1: new Types.ObjectId().toHexString(),\n rel_1_l: {\n en: new Types.ObjectId().toHexString(),\n es: new Types.ObjectId().toHexString(),\n },\n rel_2: [new Types.ObjectId().toHexString()],\n rel_2_l: {\n en: [new Types.ObjectId().toHexString()],\n es: [new Types.ObjectId().toHexString()],\n },\n rel_3: {\n relationTo: 'rels',\n value: new Types.ObjectId().toHexString(),\n },\n rel_3_l: {\n en: {\n relationTo: 'rels',\n value: new Types.ObjectId().toHexString(),\n },\n es: {\n relationTo: 'rels',\n value: new Types.ObjectId().toHexString(),\n },\n },\n rel_4: [\n {\n relationTo: 'rels',\n value: new Types.ObjectId().toHexString(),\n },\n ],\n rel_4_l: {\n en: [\n {\n relationTo: 'rels',\n value: new Types.ObjectId().toHexString(),\n },\n ],\n es: [\n {\n relationTo: 'rels',\n value: new Types.ObjectId().toHexString(),\n },\n ],\n },\n}\n\ndescribe('transform', () => {\n it('should sanitize relationships', () => {\n const data = {\n ...relsData,\n array: [\n {\n ...relsData,\n array: [{ ...relsData }],\n blocks: [\n {\n blockType: 'block',\n ...relsData,\n },\n ],\n },\n ],\n arrayLocalized: {\n en: [\n {\n ...relsData,\n array: [{ ...relsData }],\n blocks: [\n {\n blockType: 'block',\n ...relsData,\n },\n ],\n },\n ],\n es: [\n {\n ...relsData,\n array: [{ ...relsData }],\n blocks: [\n {\n blockType: 'block',\n ...relsData,\n },\n ],\n },\n ],\n },\n blocks: [\n {\n blockType: 'block',\n ...relsData,\n array: [{ ...relsData }],\n group: { ...relsData },\n },\n ],\n blockReferences: [\n {\n blockType: 'reference-block',\n array: [{ ...relsData }],\n group: { ...relsData },\n ...relsData,\n },\n ],\n group: {\n ...relsData,\n array: [{ ...relsData }],\n },\n groupAndRow: {\n ...relsData,\n array: [{ ...relsData }],\n },\n groupLocalized: {\n en: {\n ...relsData,\n array: [{ ...relsData }],\n },\n es: {\n ...relsData,\n array: [{ ...relsData }],\n },\n },\n tab: { ...relsData },\n tabLocalized: {\n en: { ...relsData },\n es: { ...relsData },\n },\n nestedTab: { ...relsData },\n }\n const flattenValuesBefore = Object.values(flattenRelationshipValues(data))\n\n const mockAdapter = {\n payload: {\n config,\n },\n } as MongooseAdapter\n\n transform({\n adapter: mockAdapter,\n operation: 'write',\n data,\n fields: config.collections[0].fields,\n })\n const flattenValuesAfter = Object.values(flattenRelationshipValues(data))\n\n flattenValuesAfter.forEach((value, i) => {\n expect(value).toBeInstanceOf(Types.ObjectId)\n expect(flattenValuesBefore[i]).toBe(value.toHexString())\n })\n })\n})\n"],"names":["flattenAllFields","Types","transform","flattenRelationshipValues","obj","prefix","Object","keys","reduce","acc","key","fullKey","value","ObjectId","assign","endsWith","relsFields","name","type","relationTo","localized","hasMany","referenceBlockFields","fields","config","blocks","slug","flattenedFields","collections","blockReferences","tabs","label","localization","defaultLocale","localeCodes","locales","code","relsData","rel_1","toHexString","rel_1_l","en","es","rel_2","rel_2_l","rel_3","rel_3_l","rel_4","rel_4_l","describe","it","data","array","blockType","arrayLocalized","group","groupAndRow","groupLocalized","tab","tabLocalized","nestedTab","flattenValuesBefore","values","mockAdapter","payload","adapter","operation","flattenValuesAfter","forEach","i","expect","toBeInstanceOf","toBe"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/db-mongodb",
|
|
3
|
-
"version": "3.25.0
|
|
3
|
+
"version": "3.25.0",
|
|
4
4
|
"description": "The officially supported MongoDB database adapter for Payload",
|
|
5
5
|
"homepage": "https://payloadcms.com",
|
|
6
6
|
"repository": {
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"mongodb": "6.12.0",
|
|
49
49
|
"mongodb-memory-server": "^10",
|
|
50
50
|
"@payloadcms/eslint-config": "3.9.0",
|
|
51
|
-
"payload": "3.25.0
|
|
51
|
+
"payload": "3.25.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"payload": "3.25.0
|
|
54
|
+
"payload": "3.25.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "pnpm build:types && pnpm build:swc",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeInternalFields.d.ts","sourceRoot":"","sources":["../../src/utilities/sanitizeInternalFields.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,KAAG,CAiB9E,CAAA"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
const internalFields = [
|
|
2
|
-
'__v'
|
|
3
|
-
];
|
|
4
|
-
export const sanitizeInternalFields = (incomingDoc)=>Object.entries(incomingDoc).reduce((newDoc, [key, val])=>{
|
|
5
|
-
if (key === '_id') {
|
|
6
|
-
return {
|
|
7
|
-
...newDoc,
|
|
8
|
-
id: val
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
if (internalFields.indexOf(key) > -1) {
|
|
12
|
-
return newDoc;
|
|
13
|
-
}
|
|
14
|
-
return {
|
|
15
|
-
...newDoc,
|
|
16
|
-
[key]: val
|
|
17
|
-
};
|
|
18
|
-
}, {});
|
|
19
|
-
|
|
20
|
-
//# sourceMappingURL=sanitizeInternalFields.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/sanitizeInternalFields.ts"],"sourcesContent":["const internalFields = ['__v']\n\nexport const sanitizeInternalFields = <T extends Record<string, unknown>>(incomingDoc: T): T =>\n Object.entries(incomingDoc).reduce((newDoc, [key, val]): T => {\n if (key === '_id') {\n return {\n ...newDoc,\n id: val,\n }\n }\n\n if (internalFields.indexOf(key) > -1) {\n return newDoc\n }\n\n return {\n ...newDoc,\n [key]: val,\n }\n }, {} as T)\n"],"names":["internalFields","sanitizeInternalFields","incomingDoc","Object","entries","reduce","newDoc","key","val","id","indexOf"],"mappings":"AAAA,MAAMA,iBAAiB;IAAC;CAAM;AAE9B,OAAO,MAAMC,yBAAyB,CAAoCC,cACxEC,OAAOC,OAAO,CAACF,aAAaG,MAAM,CAAC,CAACC,QAAQ,CAACC,KAAKC,IAAI;QACpD,IAAID,QAAQ,OAAO;YACjB,OAAO;gBACL,GAAGD,MAAM;gBACTG,IAAID;YACN;QACF;QAEA,IAAIR,eAAeU,OAAO,CAACH,OAAO,CAAC,GAAG;YACpC,OAAOD;QACT;QAEA,OAAO;YACL,GAAGA,MAAM;YACT,CAACC,IAAI,EAAEC;QACT;IACF,GAAG,CAAC,GAAO"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Field, SanitizedConfig } from 'payload';
|
|
2
|
-
type Args = {
|
|
3
|
-
config: SanitizedConfig;
|
|
4
|
-
data: Record<string, unknown>;
|
|
5
|
-
fields: Field[];
|
|
6
|
-
parentIsLocalized?: boolean;
|
|
7
|
-
};
|
|
8
|
-
export declare const sanitizeRelationshipIDs: ({ config, data, fields, parentIsLocalized, }: Args) => Record<string, unknown>;
|
|
9
|
-
export {};
|
|
10
|
-
//# sourceMappingURL=sanitizeRelationshipIDs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeRelationshipIDs.d.ts","sourceRoot":"","sources":["../../src/utilities/sanitizeRelationshipIDs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,KAAK,EAAE,eAAe,EAA0B,MAAM,SAAS,CAAA;AAM/F,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,eAAe,CAAA;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,CAAA;AAoGD,eAAO,MAAM,uBAAuB,iDAKjC,IAAI,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAgD/B,CAAA"}
|