payload 3.80.0-internal.cee0ccf → 3.80.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/auth/endpoints/forgotPassword.d.ts.map +1 -1
- package/dist/auth/endpoints/forgotPassword.js +0 -2
- package/dist/auth/endpoints/forgotPassword.js.map +1 -1
- package/dist/auth/extractJWT.d.ts.map +1 -1
- package/dist/auth/extractJWT.js +18 -4
- package/dist/auth/extractJWT.js.map +1 -1
- package/dist/auth/operations/forgotPassword.d.ts.map +1 -1
- package/dist/auth/operations/forgotPassword.js +5 -4
- package/dist/auth/operations/forgotPassword.js.map +1 -1
- package/dist/auth/operations/me.js +5 -5
- package/dist/auth/operations/me.js.map +1 -1
- package/dist/auth/sendVerificationEmail.d.ts.map +1 -1
- package/dist/auth/sendVerificationEmail.js +5 -4
- package/dist/auth/sendVerificationEmail.js.map +1 -1
- package/dist/collections/operations/update.js +1 -1
- package/dist/collections/operations/update.js.map +1 -1
- package/dist/collections/operations/utilities/update.d.ts.map +1 -1
- package/dist/collections/operations/utilities/update.js +2 -1
- package/dist/collections/operations/utilities/update.js.map +1 -1
- package/dist/config/orderable/index.d.ts +2 -2
- package/dist/config/orderable/index.d.ts.map +1 -1
- package/dist/config/orderable/index.js +60 -34
- package/dist/config/orderable/index.js.map +1 -1
- package/dist/config/orderable/utils/buildJoinScopeWhere.d.ts +10 -0
- package/dist/config/orderable/utils/buildJoinScopeWhere.d.ts.map +1 -0
- package/dist/config/orderable/utils/buildJoinScopeWhere.js +43 -0
- package/dist/config/orderable/utils/buildJoinScopeWhere.js.map +1 -0
- package/dist/config/orderable/utils/getJoinScopeContext.d.ts +16 -0
- package/dist/config/orderable/utils/getJoinScopeContext.d.ts.map +1 -0
- package/dist/config/orderable/utils/getJoinScopeContext.js +42 -0
- package/dist/config/orderable/utils/getJoinScopeContext.js.map +1 -0
- package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.d.ts +12 -0
- package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.d.ts.map +1 -0
- package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.js +18 -0
- package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.js.map +1 -0
- package/dist/config/orderable/utils/getValueAtPath.d.ts +5 -0
- package/dist/config/orderable/utils/getValueAtPath.d.ts.map +1 -0
- package/dist/config/orderable/utils/getValueAtPath.js +18 -0
- package/dist/config/orderable/utils/getValueAtPath.js.map +1 -0
- package/dist/config/orderable/utils/resolvePendingTargetKey.d.ts +13 -0
- package/dist/config/orderable/utils/resolvePendingTargetKey.d.ts.map +1 -0
- package/dist/config/orderable/utils/resolvePendingTargetKey.js +24 -0
- package/dist/config/orderable/utils/resolvePendingTargetKey.js.map +1 -0
- package/dist/config/types.d.ts +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/getLocalizedPaths.d.ts.map +1 -1
- package/dist/database/getLocalizedPaths.js +2 -1
- package/dist/database/getLocalizedPaths.js.map +1 -1
- package/dist/database/queryValidation/validateQueryPaths.js +1 -1
- package/dist/database/queryValidation/validateQueryPaths.js.map +1 -1
- package/dist/database/queryValidation/validateSearchParams.d.ts.map +1 -1
- package/dist/database/queryValidation/validateSearchParams.js +2 -1
- package/dist/database/queryValidation/validateSearchParams.js.map +1 -1
- package/dist/database/sanitizeJoinQuery.d.ts.map +1 -1
- package/dist/database/sanitizeJoinQuery.js +6 -0
- package/dist/database/sanitizeJoinQuery.js.map +1 -1
- package/dist/database/types.d.ts +0 -1
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/exports/shared.d.ts +1 -0
- package/dist/exports/shared.d.ts.map +1 -1
- package/dist/exports/shared.js +1 -0
- package/dist/exports/shared.js.map +1 -1
- package/dist/fields/baseFields/slug/index.d.ts +7 -0
- package/dist/fields/baseFields/slug/index.d.ts.map +1 -1
- package/dist/fields/baseFields/slug/index.js +2 -2
- package/dist/fields/baseFields/slug/index.js.map +1 -1
- package/dist/fields/validations.js +1 -1
- package/dist/fields/validations.js.map +1 -1
- package/dist/fields/validations.spec.js +25 -0
- package/dist/fields/validations.spec.js.map +1 -1
- package/dist/globals/operations/update.d.ts.map +1 -1
- package/dist/globals/operations/update.js +2 -1
- package/dist/globals/operations/update.js.map +1 -1
- package/dist/index.bundled.d.ts +16 -13
- package/dist/index.d.ts +1 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -10
- package/dist/index.js.map +1 -1
- package/dist/queues/localAPI.d.ts +0 -1
- package/dist/queues/localAPI.d.ts.map +1 -1
- package/dist/queues/localAPI.js +0 -4
- package/dist/queues/localAPI.js.map +1 -1
- package/dist/queues/operations/runJobs/index.d.ts +0 -1
- package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/index.js +1 -96
- package/dist/queues/operations/runJobs/index.js.map +1 -1
- package/dist/queues/utilities/updateJob.d.ts +1 -2
- package/dist/queues/utilities/updateJob.d.ts.map +1 -1
- package/dist/queues/utilities/updateJob.js +31 -92
- package/dist/queues/utilities/updateJob.js.map +1 -1
- package/dist/types/constants.d.ts +5 -0
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/constants.js +4 -0
- package/dist/types/constants.js.map +1 -1
- package/dist/uploads/endpoints/getFile.d.ts.map +1 -1
- package/dist/uploads/endpoints/getFile.js +7 -1
- package/dist/uploads/endpoints/getFile.js.map +1 -1
- package/dist/uploads/endpoints/getFileFromURL.d.ts.map +1 -1
- package/dist/uploads/endpoints/getFileFromURL.js +67 -28
- package/dist/uploads/endpoints/getFileFromURL.js.map +1 -1
- package/dist/uploads/getExternalFile.d.ts.map +1 -1
- package/dist/uploads/getExternalFile.js +3 -0
- package/dist/uploads/getExternalFile.js.map +1 -1
- package/dist/uploads/safeFetch.d.ts +1 -1
- package/dist/uploads/safeFetch.d.ts.map +1 -1
- package/dist/uploads/safeFetch.js.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.js +7 -1
- package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
- package/dist/utilities/configToJSONSchema.d.ts +7 -3
- package/dist/utilities/configToJSONSchema.d.ts.map +1 -1
- package/dist/utilities/configToJSONSchema.js +23 -33
- package/dist/utilities/configToJSONSchema.js.map +1 -1
- package/dist/utilities/configToJSONSchema.spec.js +75 -1
- package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
- package/dist/utilities/getRequestOrigin.d.ts +10 -0
- package/dist/utilities/getRequestOrigin.d.ts.map +1 -0
- package/dist/utilities/getRequestOrigin.js +50 -0
- package/dist/utilities/getRequestOrigin.js.map +1 -0
- package/dist/utilities/getRequestOrigin.spec.js +151 -0
- package/dist/utilities/getRequestOrigin.spec.js.map +1 -0
- package/dist/utilities/sanitizeUrl.d.ts +7 -0
- package/dist/utilities/sanitizeUrl.d.ts.map +1 -0
- package/dist/utilities/sanitizeUrl.js +28 -0
- package/dist/utilities/sanitizeUrl.js.map +1 -0
- package/dist/versions/saveVersion.d.ts +1 -0
- package/dist/versions/saveVersion.d.ts.map +1 -1
- package/dist/versions/saveVersion.js +16 -66
- package/dist/versions/saveVersion.js.map +1 -1
- package/dist/versions/updateLatestVersion.d.ts +24 -0
- package/dist/versions/updateLatestVersion.d.ts.map +1 -0
- package/dist/versions/updateLatestVersion.js +64 -0
- package/dist/versions/updateLatestVersion.js.map +1 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/collections/operations/utilities/update.ts"],"sourcesContent":["import type { DeepPartial } from 'ts-essentials'\n\nimport type { Args } from '../../../fields/hooks/beforeChange/index.js'\nimport type {\n CollectionSlug,\n FileToSave,\n SanitizedConfig,\n TypedFallbackLocale,\n} from '../../../index.js'\nimport type {\n JsonObject,\n Payload,\n PayloadRequest,\n PopulateType,\n SelectType,\n TransformCollectionWithSelect,\n} from '../../../types/index.js'\nimport type {\n DataFromCollectionSlug,\n SanitizedCollectionConfig,\n SelectFromCollectionSlug,\n TypeWithID,\n} from '../../config/types.js'\n\nimport { ensureUsernameOrEmail } from '../../../auth/ensureUsernameOrEmail.js'\nimport { generatePasswordSaltHash } from '../../../auth/strategies/local/generatePasswordSaltHash.js'\nimport { afterChange } from '../../../fields/hooks/afterChange/index.js'\nimport { afterRead } from '../../../fields/hooks/afterRead/index.js'\nimport { beforeChange } from '../../../fields/hooks/beforeChange/index.js'\nimport { beforeValidate } from '../../../fields/hooks/beforeValidate/index.js'\nimport { deepCopyObjectSimple, getLatestCollectionVersion, saveVersion } from '../../../index.js'\nimport { deleteAssociatedFiles } from '../../../uploads/deleteAssociatedFiles.js'\nimport { uploadFiles } from '../../../uploads/uploadFiles.js'\nimport { checkDocumentLockStatus } from '../../../utilities/checkDocumentLockStatus.js'\nimport {\n hasDraftsEnabled,\n hasDraftValidationEnabled,\n hasLocalizeStatusEnabled,\n} from '../../../utilities/getVersionsConfig.js'\nimport { mergeLocalizedData } from '../../../utilities/mergeLocalizedData.js'\nexport type SharedUpdateDocumentArgs<TSlug extends CollectionSlug> = {\n autosave: boolean\n collectionConfig: SanitizedCollectionConfig\n config: SanitizedConfig\n data: DeepPartial<DataFromCollectionSlug<TSlug>>\n depth: number\n docWithLocales: JsonObject & TypeWithID\n draftArg: boolean\n fallbackLocale: TypedFallbackLocale\n filesToUpload: FileToSave[]\n id: number | string\n locale: string\n overrideAccess: boolean\n overrideLock: boolean\n payload: Payload\n populate?: PopulateType\n publishAllLocales?: boolean\n publishSpecificLocale?: string\n req: PayloadRequest\n select: SelectType\n showHiddenFields: boolean\n unpublishAllLocales?: boolean\n}\n\n/**\n * This function is used to update a document in the DB and return the result.\n *\n * It runs the following hooks in order:\n * - beforeValidate - Fields\n * - beforeValidate - Collection\n * - beforeChange - Collection\n * - beforeChange - Fields\n * - afterRead - Fields\n * - afterRead - Collection\n * - afterChange - Fields\n * - afterChange - Collection\n */\nexport const updateDocument = async <\n TSlug extends CollectionSlug,\n TSelect extends SelectFromCollectionSlug<TSlug> = SelectType,\n>({\n id,\n autosave,\n collectionConfig,\n config,\n data,\n depth,\n docWithLocales,\n draftArg,\n fallbackLocale,\n filesToUpload,\n locale,\n overrideAccess,\n overrideLock,\n payload,\n populate,\n publishAllLocales: publishAllLocalesArg,\n publishSpecificLocale,\n req,\n select,\n showHiddenFields,\n unpublishAllLocales: unpublishAllLocalesArg,\n}: SharedUpdateDocumentArgs<TSlug>): Promise<TransformCollectionWithSelect<TSlug, TSelect>> => {\n const password = data?.password\n const publishAllLocales =\n !draftArg &&\n (publishAllLocalesArg ?? (hasLocalizeStatusEnabled(collectionConfig) ? false : true))\n const unpublishAllLocales =\n typeof unpublishAllLocalesArg === 'string'\n ? unpublishAllLocalesArg === 'true'\n : !!unpublishAllLocalesArg\n const isSavingDraft =\n Boolean(draftArg && hasDraftsEnabled(collectionConfig)) &&\n data._status !== 'published' &&\n !publishAllLocales\n const shouldSavePassword = Boolean(\n password &&\n collectionConfig.auth &&\n (!collectionConfig.auth.disableLocalStrategy ||\n (typeof collectionConfig.auth.disableLocalStrategy === 'object' &&\n collectionConfig.auth.disableLocalStrategy.enableFields)) &&\n !isSavingDraft,\n )\n\n if (isSavingDraft) {\n data._status = 'draft'\n }\n\n // /////////////////////////////////////\n // Handle potentially locked documents\n // /////////////////////////////////////\n\n await checkDocumentLockStatus({\n id,\n collectionSlug: collectionConfig.slug,\n lockErrorMessage: `Document with ID ${id} is currently locked by another user and cannot be updated.`,\n overrideLock,\n req,\n })\n\n const originalDoc = await afterRead({\n collection: collectionConfig,\n context: req.context,\n depth: 0,\n doc: deepCopyObjectSimple(docWithLocales),\n draft: draftArg,\n fallbackLocale: id ? null : fallbackLocale,\n global: null,\n locale,\n overrideAccess: true,\n req,\n showHiddenFields: true,\n })\n\n const isRestoringDraftFromTrash = Boolean(originalDoc?.deletedAt) && data?._status !== 'published'\n\n if (collectionConfig.auth) {\n ensureUsernameOrEmail<TSlug>({\n authOptions: collectionConfig.auth,\n collectionSlug: collectionConfig.slug,\n data,\n operation: 'update',\n originalDoc,\n req,\n })\n }\n\n // /////////////////////////////////////\n // Delete any associated files\n // /////////////////////////////////////\n\n await deleteAssociatedFiles({\n collectionConfig,\n config,\n doc: docWithLocales,\n files: filesToUpload,\n overrideDelete: false,\n req,\n })\n\n // /////////////////////////////////////\n // beforeValidate - Fields\n // /////////////////////////////////////\n\n data = await beforeValidate<DeepPartial<DataFromCollectionSlug<TSlug>>>({\n id,\n collection: collectionConfig,\n context: req.context,\n data,\n doc: originalDoc,\n global: null,\n operation: 'update',\n overrideAccess,\n req,\n })\n\n // /////////////////////////////////////\n // beforeValidate - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeValidate?.length) {\n for (const hook of collectionConfig.hooks.beforeValidate) {\n data =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n data,\n operation: 'update',\n originalDoc,\n req,\n })) || data\n }\n }\n\n // /////////////////////////////////////\n // Write files to local storage\n // /////////////////////////////////////\n\n if (!collectionConfig.upload.disableLocalStorage) {\n await uploadFiles(payload, filesToUpload, req)\n }\n\n // /////////////////////////////////////\n // beforeChange - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeChange?.length) {\n for (const hook of collectionConfig.hooks.beforeChange) {\n data =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n data,\n operation: 'update',\n originalDoc,\n req,\n })) || data\n }\n }\n\n // /////////////////////////////////////\n // beforeChange - Fields\n // /////////////////////////////////////\n\n const beforeChangeArgs: Args<DataFromCollectionSlug<TSlug>> = {\n id,\n collection: collectionConfig,\n context: req.context,\n data: { ...data, id },\n doc: originalDoc,\n docWithLocales,\n global: null,\n operation: 'update',\n overrideAccess,\n req,\n skipValidation:\n // only skip validation for drafts when draft validation is false\n (isSavingDraft && !hasDraftValidationEnabled(collectionConfig)) ||\n // Skip validation for trash operations since they're just metadata updates\n (collectionConfig.trash && (Boolean(data?.deletedAt) || isRestoringDraftFromTrash)),\n }\n\n // /////////////////////////////////////\n // Handle Localized Data Merging\n // /////////////////////////////////////\n\n let result: JsonObject = await beforeChange(beforeChangeArgs)\n let snapshotToSave: JsonObject | undefined\n\n if (config.localization && collectionConfig.versions) {\n let snapshotData: JsonObject | undefined\n let currentDoc\n\n if (collectionConfig.versions.drafts && collectionConfig.versions.drafts.localizeStatus) {\n if (publishAllLocales || unpublishAllLocales) {\n let accessibleLocaleCodes = config.localization.localeCodes\n\n if (config.localization.filterAvailableLocales) {\n const filteredLocales = await config.localization.filterAvailableLocales({\n locales: config.localization.locales,\n req,\n })\n accessibleLocaleCodes = filteredLocales.map((locale) =>\n typeof locale === 'string' ? locale : locale.code,\n )\n }\n\n if (typeof result._status !== 'object' || result._status === null) {\n result._status = {}\n }\n\n for (const localeCode of accessibleLocaleCodes) {\n result._status[localeCode] = unpublishAllLocales ? 'draft' : 'published'\n }\n } else if (!isSavingDraft) {\n // publishing a single locale\n currentDoc = await payload.db.findOne<DataFromCollectionSlug<TSlug>>({\n collection: collectionConfig.slug,\n req,\n where: { id: { equals: id } },\n })\n snapshotData = result\n }\n } else if (publishSpecificLocale) {\n // previous way of publishing a single locale\n currentDoc = await getLatestCollectionVersion({\n id,\n config: collectionConfig,\n payload,\n published: true,\n query: {\n collection: collectionConfig.slug,\n locale: 'all',\n req,\n where: { id: { equals: id } },\n },\n req,\n })\n snapshotData = {\n ...result,\n _status: 'draft',\n }\n }\n\n if (snapshotData) {\n snapshotToSave = deepCopyObjectSimple(snapshotData || {})\n\n result = mergeLocalizedData({\n configBlockReferences: config.blocks,\n dataWithLocales: result || {},\n docWithLocales: currentDoc || {},\n fields: collectionConfig.fields,\n selectedLocales: [locale],\n })\n }\n }\n\n const dataToUpdate: JsonObject = { ...result }\n\n // /////////////////////////////////////\n // Handle potential password update\n // /////////////////////////////////////\n\n if (shouldSavePassword && typeof password === 'string') {\n const { hash, salt } = await generatePasswordSaltHash({\n collection: collectionConfig,\n password,\n req,\n })\n dataToUpdate.salt = salt\n dataToUpdate.hash = hash\n delete dataToUpdate.password\n delete data.password\n }\n\n // /////////////////////////////////////\n // Update\n // /////////////////////////////////////\n\n if (!isSavingDraft) {\n // Ensure updatedAt date is always updated\n dataToUpdate.updatedAt = new Date().toISOString()\n result = await req.payload.db.updateOne({\n id,\n collection: collectionConfig.slug,\n data: dataToUpdate,\n locale,\n req,\n })\n }\n\n // /////////////////////////////////////\n // Create version\n // /////////////////////////////////////\n\n if (collectionConfig.versions) {\n result = await saveVersion({\n id,\n autosave,\n collection: collectionConfig,\n docWithLocales: result,\n draft: isSavingDraft,\n operation: 'update',\n payload,\n publishSpecificLocale,\n req,\n snapshot: snapshotToSave,\n })\n }\n\n // /////////////////////////////////////\n // afterRead - Fields\n // /////////////////////////////////////\n\n result = await afterRead({\n collection: collectionConfig,\n context: req.context,\n depth,\n doc: result,\n draft: draftArg,\n fallbackLocale,\n global: null,\n locale,\n overrideAccess,\n populate,\n req,\n select,\n showHiddenFields,\n })\n\n // /////////////////////////////////////\n // afterRead - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterRead?.length) {\n for (const hook of collectionConfig.hooks.afterRead) {\n result =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n doc: result,\n overrideAccess,\n req,\n })) || result\n }\n }\n\n // /////////////////////////////////////\n // afterChange - Fields\n // /////////////////////////////////////\n\n result = await afterChange({\n collection: collectionConfig,\n context: req.context,\n data,\n doc: result,\n global: null,\n operation: 'update',\n previousDoc: originalDoc,\n req,\n })\n\n // /////////////////////////////////////\n // afterChange - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterChange?.length) {\n for (const hook of collectionConfig.hooks.afterChange) {\n result =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n data,\n doc: result,\n operation: 'update',\n overrideAccess,\n previousDoc: originalDoc,\n req,\n })) || result\n }\n }\n\n return result as TransformCollectionWithSelect<TSlug, TSelect>\n}\n"],"names":["ensureUsernameOrEmail","generatePasswordSaltHash","afterChange","afterRead","beforeChange","beforeValidate","deepCopyObjectSimple","getLatestCollectionVersion","saveVersion","deleteAssociatedFiles","uploadFiles","checkDocumentLockStatus","hasDraftsEnabled","hasDraftValidationEnabled","hasLocalizeStatusEnabled","mergeLocalizedData","updateDocument","id","autosave","collectionConfig","config","data","depth","docWithLocales","draftArg","fallbackLocale","filesToUpload","locale","overrideAccess","overrideLock","payload","populate","publishAllLocales","publishAllLocalesArg","publishSpecificLocale","req","select","showHiddenFields","unpublishAllLocales","unpublishAllLocalesArg","password","isSavingDraft","Boolean","_status","shouldSavePassword","auth","disableLocalStrategy","enableFields","collectionSlug","slug","lockErrorMessage","originalDoc","collection","context","doc","draft","global","isRestoringDraftFromTrash","deletedAt","authOptions","operation","files","overrideDelete","hooks","length","hook","upload","disableLocalStorage","beforeChangeArgs","skipValidation","trash","result","snapshotToSave","localization","versions","snapshotData","currentDoc","drafts","localizeStatus","accessibleLocaleCodes","localeCodes","filterAvailableLocales","filteredLocales","locales","map","code","localeCode","db","findOne","where","equals","published","query","configBlockReferences","blocks","dataWithLocales","fields","selectedLocales","dataToUpdate","hash","salt","updatedAt","Date","toISOString","updateOne","snapshot","previousDoc"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/collections/operations/utilities/update.ts"],"sourcesContent":["import type { DeepPartial } from 'ts-essentials'\n\nimport type { Args } from '../../../fields/hooks/beforeChange/index.js'\nimport type {\n CollectionSlug,\n FileToSave,\n SanitizedConfig,\n TypedFallbackLocale,\n} from '../../../index.js'\nimport type {\n JsonObject,\n Payload,\n PayloadRequest,\n PopulateType,\n SelectType,\n TransformCollectionWithSelect,\n} from '../../../types/index.js'\nimport type {\n DataFromCollectionSlug,\n SanitizedCollectionConfig,\n SelectFromCollectionSlug,\n TypeWithID,\n} from '../../config/types.js'\n\nimport { ensureUsernameOrEmail } from '../../../auth/ensureUsernameOrEmail.js'\nimport { generatePasswordSaltHash } from '../../../auth/strategies/local/generatePasswordSaltHash.js'\nimport { afterChange } from '../../../fields/hooks/afterChange/index.js'\nimport { afterRead } from '../../../fields/hooks/afterRead/index.js'\nimport { beforeChange } from '../../../fields/hooks/beforeChange/index.js'\nimport { beforeValidate } from '../../../fields/hooks/beforeValidate/index.js'\nimport { deepCopyObjectSimple, getLatestCollectionVersion, saveVersion } from '../../../index.js'\nimport { deleteAssociatedFiles } from '../../../uploads/deleteAssociatedFiles.js'\nimport { uploadFiles } from '../../../uploads/uploadFiles.js'\nimport { checkDocumentLockStatus } from '../../../utilities/checkDocumentLockStatus.js'\nimport {\n hasDraftsEnabled,\n hasDraftValidationEnabled,\n hasLocalizeStatusEnabled,\n} from '../../../utilities/getVersionsConfig.js'\nimport { mergeLocalizedData } from '../../../utilities/mergeLocalizedData.js'\nexport type SharedUpdateDocumentArgs<TSlug extends CollectionSlug> = {\n autosave: boolean\n collectionConfig: SanitizedCollectionConfig\n config: SanitizedConfig\n data: DeepPartial<DataFromCollectionSlug<TSlug>>\n depth: number\n docWithLocales: JsonObject & TypeWithID\n draftArg: boolean\n fallbackLocale: TypedFallbackLocale\n filesToUpload: FileToSave[]\n id: number | string\n locale: string\n overrideAccess: boolean\n overrideLock: boolean\n payload: Payload\n populate?: PopulateType\n publishAllLocales?: boolean\n publishSpecificLocale?: string\n req: PayloadRequest\n select: SelectType\n showHiddenFields: boolean\n unpublishAllLocales?: boolean\n}\n\n/**\n * This function is used to update a document in the DB and return the result.\n *\n * It runs the following hooks in order:\n * - beforeValidate - Fields\n * - beforeValidate - Collection\n * - beforeChange - Collection\n * - beforeChange - Fields\n * - afterRead - Fields\n * - afterRead - Collection\n * - afterChange - Fields\n * - afterChange - Collection\n */\nexport const updateDocument = async <\n TSlug extends CollectionSlug,\n TSelect extends SelectFromCollectionSlug<TSlug> = SelectType,\n>({\n id,\n autosave,\n collectionConfig,\n config,\n data,\n depth,\n docWithLocales,\n draftArg,\n fallbackLocale,\n filesToUpload,\n locale,\n overrideAccess,\n overrideLock,\n payload,\n populate,\n publishAllLocales: publishAllLocalesArg,\n publishSpecificLocale,\n req,\n select,\n showHiddenFields,\n unpublishAllLocales: unpublishAllLocalesArg,\n}: SharedUpdateDocumentArgs<TSlug>): Promise<TransformCollectionWithSelect<TSlug, TSelect>> => {\n const password = data?.password\n const publishAllLocales =\n !draftArg &&\n (publishAllLocalesArg ?? (hasLocalizeStatusEnabled(collectionConfig) ? false : true))\n const unpublishAllLocales =\n typeof unpublishAllLocalesArg === 'string'\n ? unpublishAllLocalesArg === 'true'\n : !!unpublishAllLocalesArg\n const isSavingDraft =\n Boolean(draftArg && hasDraftsEnabled(collectionConfig)) &&\n data._status !== 'published' &&\n !publishAllLocales\n const shouldSavePassword = Boolean(\n password &&\n collectionConfig.auth &&\n (!collectionConfig.auth.disableLocalStrategy ||\n (typeof collectionConfig.auth.disableLocalStrategy === 'object' &&\n collectionConfig.auth.disableLocalStrategy.enableFields)) &&\n !isSavingDraft,\n )\n\n if (isSavingDraft) {\n data._status = 'draft'\n }\n\n // /////////////////////////////////////\n // Handle potentially locked documents\n // /////////////////////////////////////\n\n await checkDocumentLockStatus({\n id,\n collectionSlug: collectionConfig.slug,\n lockErrorMessage: `Document with ID ${id} is currently locked by another user and cannot be updated.`,\n overrideLock,\n req,\n })\n\n const originalDoc = await afterRead({\n collection: collectionConfig,\n context: req.context,\n depth: 0,\n doc: deepCopyObjectSimple(docWithLocales),\n draft: draftArg,\n fallbackLocale: id ? null : fallbackLocale,\n global: null,\n locale,\n overrideAccess: true,\n req,\n showHiddenFields: true,\n })\n\n const isRestoringDraftFromTrash = Boolean(originalDoc?.deletedAt) && data?._status !== 'published'\n\n if (collectionConfig.auth) {\n ensureUsernameOrEmail<TSlug>({\n authOptions: collectionConfig.auth,\n collectionSlug: collectionConfig.slug,\n data,\n operation: 'update',\n originalDoc,\n req,\n })\n }\n\n // /////////////////////////////////////\n // Delete any associated files\n // /////////////////////////////////////\n\n await deleteAssociatedFiles({\n collectionConfig,\n config,\n doc: docWithLocales,\n files: filesToUpload,\n overrideDelete: false,\n req,\n })\n\n // /////////////////////////////////////\n // beforeValidate - Fields\n // /////////////////////////////////////\n\n data = await beforeValidate<DeepPartial<DataFromCollectionSlug<TSlug>>>({\n id,\n collection: collectionConfig,\n context: req.context,\n data,\n doc: originalDoc,\n global: null,\n operation: 'update',\n overrideAccess,\n req,\n })\n\n // /////////////////////////////////////\n // beforeValidate - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeValidate?.length) {\n for (const hook of collectionConfig.hooks.beforeValidate) {\n data =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n data,\n operation: 'update',\n originalDoc,\n req,\n })) || data\n }\n }\n\n // /////////////////////////////////////\n // Write files to local storage\n // /////////////////////////////////////\n\n if (!collectionConfig.upload.disableLocalStorage) {\n await uploadFiles(payload, filesToUpload, req)\n }\n\n // /////////////////////////////////////\n // beforeChange - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.beforeChange?.length) {\n for (const hook of collectionConfig.hooks.beforeChange) {\n data =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n data,\n operation: 'update',\n originalDoc,\n req,\n })) || data\n }\n }\n\n // /////////////////////////////////////\n // beforeChange - Fields\n // /////////////////////////////////////\n\n const beforeChangeArgs: Args<DataFromCollectionSlug<TSlug>> = {\n id,\n collection: collectionConfig,\n context: req.context,\n data: { ...data, id },\n doc: originalDoc,\n docWithLocales,\n global: null,\n operation: 'update',\n overrideAccess,\n req,\n skipValidation:\n // only skip validation for drafts when draft validation is false\n (isSavingDraft && !hasDraftValidationEnabled(collectionConfig)) ||\n // Skip validation for trash operations since they're just metadata updates\n (collectionConfig.trash && (Boolean(data?.deletedAt) || isRestoringDraftFromTrash)),\n }\n\n // /////////////////////////////////////\n // Handle Localized Data Merging\n // /////////////////////////////////////\n\n let result: JsonObject = await beforeChange(beforeChangeArgs)\n let snapshotToSave: JsonObject | undefined\n\n if (config.localization && collectionConfig.versions) {\n let snapshotData: JsonObject | undefined\n let currentDoc\n\n if (collectionConfig.versions.drafts && collectionConfig.versions.drafts.localizeStatus) {\n if (publishAllLocales || unpublishAllLocales) {\n let accessibleLocaleCodes = config.localization.localeCodes\n\n if (config.localization.filterAvailableLocales) {\n const filteredLocales = await config.localization.filterAvailableLocales({\n locales: config.localization.locales,\n req,\n })\n accessibleLocaleCodes = filteredLocales.map((locale) =>\n typeof locale === 'string' ? locale : locale.code,\n )\n }\n\n if (typeof result._status !== 'object' || result._status === null) {\n result._status = {}\n }\n\n for (const localeCode of accessibleLocaleCodes) {\n result._status[localeCode] = unpublishAllLocales ? 'draft' : 'published'\n }\n } else if (!isSavingDraft) {\n // publishing a single locale\n currentDoc = await payload.db.findOne<DataFromCollectionSlug<TSlug>>({\n collection: collectionConfig.slug,\n req,\n where: { id: { equals: id } },\n })\n snapshotData = result\n }\n } else if (publishSpecificLocale) {\n // previous way of publishing a single locale\n currentDoc = await getLatestCollectionVersion({\n id,\n config: collectionConfig,\n payload,\n published: true,\n query: {\n collection: collectionConfig.slug,\n locale: 'all',\n req,\n where: { id: { equals: id } },\n },\n req,\n })\n snapshotData = {\n ...result,\n _status: 'draft',\n }\n }\n\n if (snapshotData) {\n snapshotToSave = deepCopyObjectSimple(snapshotData || {})\n\n result = mergeLocalizedData({\n configBlockReferences: config.blocks,\n dataWithLocales: result || {},\n docWithLocales: currentDoc || {},\n fields: collectionConfig.fields,\n selectedLocales: [locale],\n })\n }\n }\n\n const dataToUpdate: JsonObject = { ...result }\n\n // /////////////////////////////////////\n // Handle potential password update\n // /////////////////////////////////////\n\n if (shouldSavePassword && typeof password === 'string') {\n const { hash, salt } = await generatePasswordSaltHash({\n collection: collectionConfig,\n password,\n req,\n })\n dataToUpdate.salt = salt\n dataToUpdate.hash = hash\n delete dataToUpdate.password\n delete data.password\n }\n\n // /////////////////////////////////////\n // Update\n // /////////////////////////////////////\n\n if (!isSavingDraft) {\n // Ensure updatedAt date is always updated\n dataToUpdate.updatedAt = new Date().toISOString()\n result = await req.payload.db.updateOne({\n id,\n collection: collectionConfig.slug,\n data: dataToUpdate,\n locale,\n req,\n })\n }\n\n // /////////////////////////////////////\n // Create version\n // /////////////////////////////////////\n\n if (collectionConfig.versions) {\n result = await saveVersion({\n id,\n autosave,\n collection: collectionConfig,\n docWithLocales: result,\n draft: isSavingDraft,\n operation: 'update',\n payload,\n publishSpecificLocale,\n req,\n snapshot: snapshotToSave,\n unpublish: unpublishAllLocales,\n })\n }\n\n // /////////////////////////////////////\n // afterRead - Fields\n // /////////////////////////////////////\n\n result = await afterRead({\n collection: collectionConfig,\n context: req.context,\n depth,\n doc: result,\n draft: draftArg,\n fallbackLocale,\n global: null,\n locale,\n overrideAccess,\n populate,\n req,\n select,\n showHiddenFields,\n })\n\n // /////////////////////////////////////\n // afterRead - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterRead?.length) {\n for (const hook of collectionConfig.hooks.afterRead) {\n result =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n doc: result,\n overrideAccess,\n req,\n })) || result\n }\n }\n\n // /////////////////////////////////////\n // afterChange - Fields\n // /////////////////////////////////////\n\n result = await afterChange({\n collection: collectionConfig,\n context: req.context,\n data,\n doc: result,\n global: null,\n operation: 'update',\n previousDoc: originalDoc,\n req,\n })\n\n // /////////////////////////////////////\n // afterChange - Collection\n // /////////////////////////////////////\n\n if (collectionConfig.hooks?.afterChange?.length) {\n for (const hook of collectionConfig.hooks.afterChange) {\n result =\n (await hook({\n collection: collectionConfig,\n context: req.context,\n data,\n doc: result,\n operation: 'update',\n overrideAccess,\n previousDoc: originalDoc,\n req,\n })) || result\n }\n }\n\n return result as TransformCollectionWithSelect<TSlug, TSelect>\n}\n"],"names":["ensureUsernameOrEmail","generatePasswordSaltHash","afterChange","afterRead","beforeChange","beforeValidate","deepCopyObjectSimple","getLatestCollectionVersion","saveVersion","deleteAssociatedFiles","uploadFiles","checkDocumentLockStatus","hasDraftsEnabled","hasDraftValidationEnabled","hasLocalizeStatusEnabled","mergeLocalizedData","updateDocument","id","autosave","collectionConfig","config","data","depth","docWithLocales","draftArg","fallbackLocale","filesToUpload","locale","overrideAccess","overrideLock","payload","populate","publishAllLocales","publishAllLocalesArg","publishSpecificLocale","req","select","showHiddenFields","unpublishAllLocales","unpublishAllLocalesArg","password","isSavingDraft","Boolean","_status","shouldSavePassword","auth","disableLocalStrategy","enableFields","collectionSlug","slug","lockErrorMessage","originalDoc","collection","context","doc","draft","global","isRestoringDraftFromTrash","deletedAt","authOptions","operation","files","overrideDelete","hooks","length","hook","upload","disableLocalStorage","beforeChangeArgs","skipValidation","trash","result","snapshotToSave","localization","versions","snapshotData","currentDoc","drafts","localizeStatus","accessibleLocaleCodes","localeCodes","filterAvailableLocales","filteredLocales","locales","map","code","localeCode","db","findOne","where","equals","published","query","configBlockReferences","blocks","dataWithLocales","fields","selectedLocales","dataToUpdate","hash","salt","updatedAt","Date","toISOString","updateOne","snapshot","unpublish","previousDoc"],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ import type { SanitizedConfig } from '../types.js';
|
|
|
9
9
|
* Also, if collection.defaultSort or joinField.defaultSort is not set, it will be set to the orderable field.
|
|
10
10
|
*/
|
|
11
11
|
export declare const setupOrderable: (config: SanitizedConfig) => void;
|
|
12
|
-
export declare const addOrderableFieldsAndHook: (collection: CollectionConfig, orderableFieldNames: string[]) => void;
|
|
12
|
+
export declare const addOrderableFieldsAndHook: (collection: CollectionConfig, orderableFieldNames: string[], joinFieldPathsByCollection?: Map<string, Map<string, string>>) => void;
|
|
13
13
|
/**
|
|
14
14
|
* The body of the reorder endpoint.
|
|
15
15
|
* @internal
|
|
@@ -24,5 +24,5 @@ export type OrderableEndpointBody = {
|
|
|
24
24
|
key: string;
|
|
25
25
|
};
|
|
26
26
|
};
|
|
27
|
-
export declare const addOrderableEndpoint: (config: SanitizedConfig) => void;
|
|
27
|
+
export declare const addOrderableEndpoint: (config: SanitizedConfig, joinFieldPathsByCollection: Map<string, Map<string, string>>) => void;
|
|
28
28
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/orderable/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AAE3F,OAAO,KAAK,EAA4B,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/orderable/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AAE3F,OAAO,KAAK,EAA4B,eAAe,EAAE,MAAM,aAAa,CAAA;AAc5E;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,WAAY,eAAe,SA2DrD,CAAA;AAED,eAAO,MAAM,yBAAyB,eACxB,gBAAgB,uBACP,MAAM,EAAE,+BACA,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,SA2E9D,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,YAAY,EAAE,SAAS,GAAG,MAAM,CAAA;IAChC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAA;QACV,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF,CAAA;AAED,eAAO,MAAM,oBAAoB,WACvB,eAAe,8BACK,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,SA4L7D,CAAA"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { status as httpStatus } from 'http-status';
|
|
2
2
|
import { executeAccess } from '../../auth/executeAccess.js';
|
|
3
3
|
import { APIError } from '../../errors/index.js';
|
|
4
|
+
import { combineWhereConstraints } from '../../utilities/combineWhereConstraints.js';
|
|
4
5
|
import { commitTransaction } from '../../utilities/commitTransaction.js';
|
|
5
6
|
import { initTransaction } from '../../utilities/initTransaction.js';
|
|
6
7
|
import { killTransaction } from '../../utilities/killTransaction.js';
|
|
7
8
|
import { traverseFields } from '../../utilities/traverseFields.js';
|
|
8
9
|
import { generateKeyBetween, generateNKeysBetween } from './fractional-indexing.js';
|
|
10
|
+
import { getJoinScopeContext } from './utils/getJoinScopeContext.js';
|
|
11
|
+
import { getJoinScopeWhereFromDocData } from './utils/getJoinScopeWhereFromDocData.js';
|
|
12
|
+
import { resolvePendingTargetKey } from './utils/resolvePendingTargetKey.js';
|
|
9
13
|
/**
|
|
10
14
|
* This function creates:
|
|
11
15
|
* - N fields per collection, named `_order` or `_<collection>_<joinField>_order`
|
|
@@ -15,6 +19,7 @@ import { generateKeyBetween, generateNKeysBetween } from './fractional-indexing.
|
|
|
15
19
|
* Also, if collection.defaultSort or joinField.defaultSort is not set, it will be set to the orderable field.
|
|
16
20
|
*/ export const setupOrderable = (config)=>{
|
|
17
21
|
const fieldsToAdd = new Map();
|
|
22
|
+
const joinFieldPathsByCollection = new Map();
|
|
18
23
|
config.collections.forEach((collection)=>{
|
|
19
24
|
if (collection.orderable) {
|
|
20
25
|
const currentFields = fieldsToAdd.get(collection) || [];
|
|
@@ -47,23 +52,27 @@ import { generateKeyBetween, generateNKeysBetween } from './fractional-indexing.
|
|
|
47
52
|
const currentFields = fieldsToAdd.get(relationshipCollection) || [];
|
|
48
53
|
// @ts-expect-error ref is untyped
|
|
49
54
|
const prefix = parentRef?.prefix ? `${parentRef.prefix}_` : '';
|
|
55
|
+
const joinOrderableFieldName = `_${field.collection}_${prefix}${field.name}_order`;
|
|
50
56
|
fieldsToAdd.set(relationshipCollection, [
|
|
51
57
|
...currentFields,
|
|
52
|
-
|
|
58
|
+
joinOrderableFieldName
|
|
53
59
|
]);
|
|
60
|
+
const currentJoinFieldPaths = joinFieldPathsByCollection.get(relationshipCollection.slug) || new Map();
|
|
61
|
+
currentJoinFieldPaths.set(joinOrderableFieldName, field.on);
|
|
62
|
+
joinFieldPathsByCollection.set(relationshipCollection.slug, currentJoinFieldPaths);
|
|
54
63
|
}
|
|
55
64
|
},
|
|
56
65
|
fields: collection.fields
|
|
57
66
|
});
|
|
58
67
|
});
|
|
59
68
|
Array.from(fieldsToAdd.entries()).forEach(([collection, orderableFields])=>{
|
|
60
|
-
addOrderableFieldsAndHook(collection, orderableFields);
|
|
69
|
+
addOrderableFieldsAndHook(collection, orderableFields, joinFieldPathsByCollection);
|
|
61
70
|
});
|
|
62
71
|
if (fieldsToAdd.size > 0) {
|
|
63
|
-
addOrderableEndpoint(config);
|
|
72
|
+
addOrderableEndpoint(config, joinFieldPathsByCollection);
|
|
64
73
|
}
|
|
65
74
|
};
|
|
66
|
-
export const addOrderableFieldsAndHook = (collection, orderableFieldNames)=>{
|
|
75
|
+
export const addOrderableFieldsAndHook = (collection, orderableFieldNames, joinFieldPathsByCollection)=>{
|
|
67
76
|
// 1. Add field
|
|
68
77
|
orderableFieldNames.forEach((orderableFieldName)=>{
|
|
69
78
|
const orderField = {
|
|
@@ -99,6 +108,13 @@ export const addOrderableFieldsAndHook = (collection, orderableFieldNames)=>{
|
|
|
99
108
|
const orderBeforeChangeHook = async ({ data, originalDoc, req })=>{
|
|
100
109
|
for (const orderableFieldName of orderableFieldNames){
|
|
101
110
|
if (!data[orderableFieldName] && !originalDoc?.[orderableFieldName]) {
|
|
111
|
+
const joinScopeWhere = getJoinScopeWhereFromDocData({
|
|
112
|
+
collectionSlug: collection.slug,
|
|
113
|
+
data,
|
|
114
|
+
joinFieldPathsByCollection,
|
|
115
|
+
orderableFieldName,
|
|
116
|
+
originalDoc
|
|
117
|
+
});
|
|
102
118
|
const lastDoc = await req.payload.find({
|
|
103
119
|
collection: collection.slug,
|
|
104
120
|
depth: 0,
|
|
@@ -109,11 +125,14 @@ export const addOrderableFieldsAndHook = (collection, orderableFieldNames)=>{
|
|
|
109
125
|
[orderableFieldName]: true
|
|
110
126
|
},
|
|
111
127
|
sort: `-${orderableFieldName}`,
|
|
112
|
-
where:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
128
|
+
where: combineWhereConstraints([
|
|
129
|
+
{
|
|
130
|
+
[orderableFieldName]: {
|
|
131
|
+
exists: true
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
joinScopeWhere ?? undefined
|
|
135
|
+
])
|
|
117
136
|
});
|
|
118
137
|
const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null;
|
|
119
138
|
data[orderableFieldName] = generateKeyBetween(lastOrderValue, null);
|
|
@@ -123,7 +142,7 @@ export const addOrderableFieldsAndHook = (collection, orderableFieldNames)=>{
|
|
|
123
142
|
};
|
|
124
143
|
collection.hooks.beforeChange.push(orderBeforeChangeHook);
|
|
125
144
|
};
|
|
126
|
-
export const addOrderableEndpoint = (config)=>{
|
|
145
|
+
export const addOrderableEndpoint = (config, joinFieldPathsByCollection)=>{
|
|
127
146
|
// 3. Add endpoint
|
|
128
147
|
const reorderHandler = async (req)=>{
|
|
129
148
|
const body = await req.json?.();
|
|
@@ -169,6 +188,13 @@ export const addOrderableEndpoint = (config)=>{
|
|
|
169
188
|
status: 400
|
|
170
189
|
});
|
|
171
190
|
}
|
|
191
|
+
const { joinScopeWhere, targetDoc } = await getJoinScopeContext({
|
|
192
|
+
collectionSlug: collection.slug,
|
|
193
|
+
joinFieldPathsByCollection,
|
|
194
|
+
orderableFieldName,
|
|
195
|
+
req,
|
|
196
|
+
target
|
|
197
|
+
});
|
|
172
198
|
// Prevent reordering if user doesn't have editing permissions
|
|
173
199
|
if (collection.access?.update) {
|
|
174
200
|
await executeAccess({
|
|
@@ -196,11 +222,14 @@ export const addOrderableEndpoint = (config)=>{
|
|
|
196
222
|
select: {
|
|
197
223
|
[orderableFieldName]: true
|
|
198
224
|
},
|
|
199
|
-
where:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
225
|
+
where: combineWhereConstraints([
|
|
226
|
+
{
|
|
227
|
+
[orderableFieldName]: {
|
|
228
|
+
exists: false
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
joinScopeWhere ?? undefined
|
|
232
|
+
])
|
|
204
233
|
});
|
|
205
234
|
await initTransaction(req);
|
|
206
235
|
// We cannot update all documents in a single operation with `payload.update`,
|
|
@@ -244,20 +273,14 @@ export const addOrderableEndpoint = (config)=>{
|
|
|
244
273
|
});
|
|
245
274
|
}
|
|
246
275
|
const targetId = target.id;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
select: {
|
|
256
|
-
[orderableFieldName]: true
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
targetKey = beforeDoc?.[orderableFieldName] || null;
|
|
260
|
-
}
|
|
276
|
+
const targetKey = await resolvePendingTargetKey({
|
|
277
|
+
collectionSlug: collection.slug,
|
|
278
|
+
orderableFieldName,
|
|
279
|
+
req,
|
|
280
|
+
targetDoc,
|
|
281
|
+
targetID: targetId,
|
|
282
|
+
targetKey: target.key
|
|
283
|
+
});
|
|
261
284
|
// The reason the endpoint does not receive this docId as an argument is that there
|
|
262
285
|
// are situations where the user may not see or know what the next or previous one is. For
|
|
263
286
|
// example, access control restrictions, if docBefore is the last one on the page, etc.
|
|
@@ -270,11 +293,14 @@ export const addOrderableEndpoint = (config)=>{
|
|
|
270
293
|
[orderableFieldName]: true
|
|
271
294
|
},
|
|
272
295
|
sort: newKeyWillBe === 'greater' ? orderableFieldName : `-${orderableFieldName}`,
|
|
273
|
-
where:
|
|
274
|
-
|
|
275
|
-
[
|
|
276
|
-
|
|
277
|
-
|
|
296
|
+
where: combineWhereConstraints([
|
|
297
|
+
{
|
|
298
|
+
[orderableFieldName]: {
|
|
299
|
+
[newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: targetKey
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
joinScopeWhere ?? undefined
|
|
303
|
+
])
|
|
278
304
|
});
|
|
279
305
|
const adjacentDocKey = adjacentDoc.docs?.[0]?.[orderableFieldName] || null;
|
|
280
306
|
// Currently N (= docsToMove.length) is always 1. Maybe in the future we will
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/config/orderable/index.ts"],"sourcesContent":["import { status as httpStatus } from 'http-status'\n\nimport type { BeforeChangeHook, CollectionConfig } from '../../collections/config/types.js'\nimport type { Field } from '../../fields/config/types.js'\nimport type { Endpoint, PayloadHandler, SanitizedConfig } from '../types.js'\n\nimport { executeAccess } from '../../auth/executeAccess.js'\nimport { APIError } from '../../errors/index.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { traverseFields } from '../../utilities/traverseFields.js'\nimport { generateKeyBetween, generateNKeysBetween } from './fractional-indexing.js'\n\n/**\n * This function creates:\n * - N fields per collection, named `_order` or `_<collection>_<joinField>_order`\n * - 1 hook per collection\n * - 1 endpoint per app\n *\n * Also, if collection.defaultSort or joinField.defaultSort is not set, it will be set to the orderable field.\n */\nexport const setupOrderable = (config: SanitizedConfig) => {\n const fieldsToAdd = new Map<CollectionConfig, string[]>()\n\n config.collections.forEach((collection) => {\n if (collection.orderable) {\n const currentFields = fieldsToAdd.get(collection) || []\n fieldsToAdd.set(collection, [...currentFields, '_order'])\n collection.defaultSort = collection.defaultSort ?? '_order'\n }\n\n traverseFields({\n callback: ({ field, parentRef, ref }) => {\n if (field.type === 'array' || field.type === 'blocks') {\n return false\n }\n if (field.type === 'group' || field.type === 'tab') {\n // @ts-expect-error ref is untyped\n const parentPrefix = parentRef?.prefix ? `${parentRef.prefix}_` : ''\n // @ts-expect-error ref is untyped\n ref.prefix = `${parentPrefix}${field.name}`\n }\n if (field.type === 'join' && field.orderable === true) {\n if (Array.isArray(field.collection)) {\n throw new APIError(\n 'Orderable joins must target a single collection',\n httpStatus.BAD_REQUEST,\n {},\n true,\n )\n }\n const relationshipCollection = config.collections.find((c) => c.slug === field.collection)\n if (!relationshipCollection) {\n return false\n }\n field.defaultSort = field.defaultSort ?? `_${field.collection}_${field.name}_order`\n const currentFields = fieldsToAdd.get(relationshipCollection) || []\n // @ts-expect-error ref is untyped\n const prefix = parentRef?.prefix ? `${parentRef.prefix}_` : ''\n fieldsToAdd.set(relationshipCollection, [\n ...currentFields,\n `_${field.collection}_${prefix}${field.name}_order`,\n ])\n }\n },\n fields: collection.fields,\n })\n })\n\n Array.from(fieldsToAdd.entries()).forEach(([collection, orderableFields]) => {\n addOrderableFieldsAndHook(collection, orderableFields)\n })\n\n if (fieldsToAdd.size > 0) {\n addOrderableEndpoint(config)\n }\n}\n\nexport const addOrderableFieldsAndHook = (\n collection: CollectionConfig,\n orderableFieldNames: string[],\n) => {\n // 1. Add field\n orderableFieldNames.forEach((orderableFieldName) => {\n const orderField: Field = {\n name: orderableFieldName,\n type: 'text',\n admin: {\n disableBulkEdit: true,\n disabled: true,\n disableGroupBy: true,\n disableListColumn: true,\n disableListFilter: true,\n hidden: true,\n readOnly: true,\n },\n hooks: {\n beforeDuplicate: [\n ({ siblingData }) => {\n delete siblingData[orderableFieldName]\n },\n ],\n },\n index: true,\n }\n\n collection.fields.unshift(orderField)\n })\n\n // 2. Add hook\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks.beforeChange) {\n collection.hooks.beforeChange = []\n }\n\n const orderBeforeChangeHook: BeforeChangeHook = async ({ data, originalDoc, req }) => {\n for (const orderableFieldName of orderableFieldNames) {\n if (!data[orderableFieldName] && !originalDoc?.[orderableFieldName]) {\n const lastDoc = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 1,\n pagination: false,\n req,\n select: { [orderableFieldName]: true },\n sort: `-${orderableFieldName}`,\n where: {\n [orderableFieldName]: {\n exists: true,\n },\n },\n })\n\n const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null\n data[orderableFieldName] = generateKeyBetween(lastOrderValue, null)\n }\n }\n\n return data\n }\n\n collection.hooks.beforeChange.push(orderBeforeChangeHook)\n}\n\n/**\n * The body of the reorder endpoint.\n * @internal\n */\nexport type OrderableEndpointBody = {\n collectionSlug: string\n docsToMove: string[]\n newKeyWillBe: 'greater' | 'less'\n orderableFieldName: string\n target: {\n id: string\n key: string\n }\n}\n\nexport const addOrderableEndpoint = (config: SanitizedConfig) => {\n // 3. Add endpoint\n const reorderHandler: PayloadHandler = async (req) => {\n const body = (await req.json?.()) as OrderableEndpointBody\n\n const { collectionSlug, docsToMove, newKeyWillBe, orderableFieldName, target } = body\n\n if (!Array.isArray(docsToMove) || docsToMove.length === 0) {\n return new Response(JSON.stringify({ error: 'docsToMove must be a non-empty array' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n if (newKeyWillBe !== 'greater' && newKeyWillBe !== 'less') {\n return new Response(JSON.stringify({ error: 'newKeyWillBe must be \"greater\" or \"less\"' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n const collection = config.collections.find((c) => c.slug === collectionSlug)\n if (!collection) {\n return new Response(JSON.stringify({ error: `Collection ${collectionSlug} not found` }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n if (typeof orderableFieldName !== 'string') {\n return new Response(JSON.stringify({ error: 'orderableFieldName must be a string' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n\n // Prevent reordering if user doesn't have editing permissions\n if (collection.access?.update) {\n await executeAccess(\n {\n // Currently only one doc can be moved at a time. We should review this if we want to allow\n // multiple docs to be moved at once in the future.\n id: docsToMove[0],\n data: {},\n req,\n },\n collection.access.update,\n )\n }\n /**\n * If there is no target.key, we can assume the user enabled `orderable`\n * on a collection with existing documents, and that this is the first\n * time they tried to reorder them. Therefore, we perform a one-time\n * migration by setting the key value for all documents. We do this\n * instead of enforcing `required` and `unique` at the database schema\n * level, so that users don't have to run a migration when they enable\n * `orderable` on a collection with existing documents.\n */\n if (!target.key) {\n const { docs } = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 0,\n req,\n select: { [orderableFieldName]: true },\n where: {\n [orderableFieldName]: {\n exists: false,\n },\n },\n })\n await initTransaction(req)\n // We cannot update all documents in a single operation with `payload.update`,\n // because they would all end up with the same order key (`a0`).\n try {\n for (const doc of docs) {\n await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: {\n // no data needed since the order hooks will handle this\n },\n depth: 0,\n req,\n })\n await commitTransaction(req)\n }\n } catch (e) {\n await killTransaction(req)\n if (e instanceof Error) {\n throw new APIError(e.message, httpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n return new Response(JSON.stringify({ message: 'initial migration', success: true }), {\n headers: { 'Content-Type': 'application/json' },\n status: 200,\n })\n }\n\n if (\n typeof target !== 'object' ||\n typeof target.id === 'undefined' ||\n typeof target.key !== 'string'\n ) {\n return new Response(JSON.stringify({ error: 'target must be an object with id' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n\n const targetId = target.id\n let targetKey = target.key\n\n // If targetKey = pending, we need to find its current key.\n // This can only happen if the user reorders rows quickly with a slow connection.\n if (targetKey === 'pending') {\n const beforeDoc = await req.payload.findByID({\n id: targetId,\n collection: collection.slug,\n depth: 0,\n select: { [orderableFieldName]: true },\n })\n targetKey = beforeDoc?.[orderableFieldName] || null\n }\n\n // The reason the endpoint does not receive this docId as an argument is that there\n // are situations where the user may not see or know what the next or previous one is. For\n // example, access control restrictions, if docBefore is the last one on the page, etc.\n const adjacentDoc = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 1,\n pagination: false,\n select: { [orderableFieldName]: true },\n sort: newKeyWillBe === 'greater' ? orderableFieldName : `-${orderableFieldName}`,\n where: {\n [orderableFieldName]: {\n [newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: targetKey,\n },\n },\n })\n const adjacentDocKey = adjacentDoc.docs?.[0]?.[orderableFieldName] || null\n\n // Currently N (= docsToMove.length) is always 1. Maybe in the future we will\n // allow dragging and reordering multiple documents at once via the UI.\n const orderValues =\n newKeyWillBe === 'greater'\n ? generateNKeysBetween(targetKey, adjacentDocKey, docsToMove.length)\n : generateNKeysBetween(adjacentDocKey, targetKey, docsToMove.length)\n\n // Update each document with its new order value\n for (const [index, id] of docsToMove.entries()) {\n await req.payload.update({\n id,\n collection: collection.slug,\n data: {\n [orderableFieldName]: orderValues[index],\n },\n depth: 0,\n req,\n })\n }\n\n return new Response(JSON.stringify({ orderValues, success: true }), {\n headers: { 'Content-Type': 'application/json' },\n status: 200,\n })\n }\n\n const reorderEndpoint: Endpoint = {\n handler: reorderHandler,\n method: 'post',\n path: '/reorder',\n }\n\n if (!config.endpoints) {\n config.endpoints = []\n }\n\n config.endpoints.push(reorderEndpoint)\n}\n"],"names":["status","httpStatus","executeAccess","APIError","commitTransaction","initTransaction","killTransaction","traverseFields","generateKeyBetween","generateNKeysBetween","setupOrderable","config","fieldsToAdd","Map","collections","forEach","collection","orderable","currentFields","get","set","defaultSort","callback","field","parentRef","ref","type","parentPrefix","prefix","name","Array","isArray","BAD_REQUEST","relationshipCollection","find","c","slug","fields","from","entries","orderableFields","addOrderableFieldsAndHook","size","addOrderableEndpoint","orderableFieldNames","orderableFieldName","orderField","admin","disableBulkEdit","disabled","disableGroupBy","disableListColumn","disableListFilter","hidden","readOnly","hooks","beforeDuplicate","siblingData","index","unshift","beforeChange","orderBeforeChangeHook","data","originalDoc","req","lastDoc","payload","depth","limit","pagination","select","sort","where","exists","lastOrderValue","docs","push","reorderHandler","body","json","collectionSlug","docsToMove","newKeyWillBe","target","length","Response","JSON","stringify","error","headers","access","update","id","key","doc","e","Error","message","INTERNAL_SERVER_ERROR","success","targetId","targetKey","beforeDoc","findByID","adjacentDoc","adjacentDocKey","orderValues","reorderEndpoint","handler","method","path","endpoints"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/config/orderable/index.ts"],"sourcesContent":["import { status as httpStatus } from 'http-status'\n\nimport type { BeforeChangeHook, CollectionConfig } from '../../collections/config/types.js'\nimport type { Field } from '../../fields/config/types.js'\nimport type { Endpoint, PayloadHandler, SanitizedConfig } from '../types.js'\n\nimport { executeAccess } from '../../auth/executeAccess.js'\nimport { APIError } from '../../errors/index.js'\nimport { combineWhereConstraints } from '../../utilities/combineWhereConstraints.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { traverseFields } from '../../utilities/traverseFields.js'\nimport { generateKeyBetween, generateNKeysBetween } from './fractional-indexing.js'\nimport { getJoinScopeContext } from './utils/getJoinScopeContext.js'\nimport { getJoinScopeWhereFromDocData } from './utils/getJoinScopeWhereFromDocData.js'\nimport { resolvePendingTargetKey } from './utils/resolvePendingTargetKey.js'\n\n/**\n * This function creates:\n * - N fields per collection, named `_order` or `_<collection>_<joinField>_order`\n * - 1 hook per collection\n * - 1 endpoint per app\n *\n * Also, if collection.defaultSort or joinField.defaultSort is not set, it will be set to the orderable field.\n */\nexport const setupOrderable = (config: SanitizedConfig) => {\n const fieldsToAdd = new Map<CollectionConfig, string[]>()\n const joinFieldPathsByCollection = new Map<string, Map<string, string>>()\n\n config.collections.forEach((collection) => {\n if (collection.orderable) {\n const currentFields = fieldsToAdd.get(collection) || []\n fieldsToAdd.set(collection, [...currentFields, '_order'])\n collection.defaultSort = collection.defaultSort ?? '_order'\n }\n\n traverseFields({\n callback: ({ field, parentRef, ref }) => {\n if (field.type === 'array' || field.type === 'blocks') {\n return false\n }\n if (field.type === 'group' || field.type === 'tab') {\n // @ts-expect-error ref is untyped\n const parentPrefix = parentRef?.prefix ? `${parentRef.prefix}_` : ''\n // @ts-expect-error ref is untyped\n ref.prefix = `${parentPrefix}${field.name}`\n }\n if (field.type === 'join' && field.orderable === true) {\n if (Array.isArray(field.collection)) {\n throw new APIError(\n 'Orderable joins must target a single collection',\n httpStatus.BAD_REQUEST,\n {},\n true,\n )\n }\n const relationshipCollection = config.collections.find((c) => c.slug === field.collection)\n if (!relationshipCollection) {\n return false\n }\n field.defaultSort = field.defaultSort ?? `_${field.collection}_${field.name}_order`\n const currentFields = fieldsToAdd.get(relationshipCollection) || []\n // @ts-expect-error ref is untyped\n const prefix = parentRef?.prefix ? `${parentRef.prefix}_` : ''\n const joinOrderableFieldName = `_${field.collection}_${prefix}${field.name}_order`\n fieldsToAdd.set(relationshipCollection, [...currentFields, joinOrderableFieldName])\n\n const currentJoinFieldPaths =\n joinFieldPathsByCollection.get(relationshipCollection.slug) || new Map<string, string>()\n currentJoinFieldPaths.set(joinOrderableFieldName, field.on)\n joinFieldPathsByCollection.set(relationshipCollection.slug, currentJoinFieldPaths)\n }\n },\n fields: collection.fields,\n })\n })\n\n Array.from(fieldsToAdd.entries()).forEach(([collection, orderableFields]) => {\n addOrderableFieldsAndHook(collection, orderableFields, joinFieldPathsByCollection)\n })\n\n if (fieldsToAdd.size > 0) {\n addOrderableEndpoint(config, joinFieldPathsByCollection)\n }\n}\n\nexport const addOrderableFieldsAndHook = (\n collection: CollectionConfig,\n orderableFieldNames: string[],\n joinFieldPathsByCollection?: Map<string, Map<string, string>>,\n) => {\n // 1. Add field\n orderableFieldNames.forEach((orderableFieldName) => {\n const orderField: Field = {\n name: orderableFieldName,\n type: 'text',\n admin: {\n disableBulkEdit: true,\n disabled: true,\n disableGroupBy: true,\n disableListColumn: true,\n disableListFilter: true,\n hidden: true,\n readOnly: true,\n },\n hooks: {\n beforeDuplicate: [\n ({ siblingData }) => {\n delete siblingData[orderableFieldName]\n },\n ],\n },\n index: true,\n }\n\n collection.fields.unshift(orderField)\n })\n\n // 2. Add hook\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks.beforeChange) {\n collection.hooks.beforeChange = []\n }\n\n const orderBeforeChangeHook: BeforeChangeHook = async ({ data, originalDoc, req }) => {\n for (const orderableFieldName of orderableFieldNames) {\n if (!data[orderableFieldName] && !originalDoc?.[orderableFieldName]) {\n const joinScopeWhere = getJoinScopeWhereFromDocData({\n collectionSlug: collection.slug,\n data,\n joinFieldPathsByCollection,\n orderableFieldName,\n originalDoc,\n })\n\n const lastDoc = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 1,\n pagination: false,\n req,\n select: { [orderableFieldName]: true },\n sort: `-${orderableFieldName}`,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n exists: true,\n },\n },\n joinScopeWhere ?? undefined,\n ]),\n })\n\n const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null\n data[orderableFieldName] = generateKeyBetween(lastOrderValue, null)\n }\n }\n\n return data\n }\n\n collection.hooks.beforeChange.push(orderBeforeChangeHook)\n}\n\n/**\n * The body of the reorder endpoint.\n * @internal\n */\nexport type OrderableEndpointBody = {\n collectionSlug: string\n docsToMove: string[]\n newKeyWillBe: 'greater' | 'less'\n orderableFieldName: string\n target: {\n id: string\n key: string\n }\n}\n\nexport const addOrderableEndpoint = (\n config: SanitizedConfig,\n joinFieldPathsByCollection: Map<string, Map<string, string>>,\n) => {\n // 3. Add endpoint\n const reorderHandler: PayloadHandler = async (req) => {\n const body = (await req.json?.()) as OrderableEndpointBody\n\n const { collectionSlug, docsToMove, newKeyWillBe, orderableFieldName, target } = body\n\n if (!Array.isArray(docsToMove) || docsToMove.length === 0) {\n return new Response(JSON.stringify({ error: 'docsToMove must be a non-empty array' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n if (newKeyWillBe !== 'greater' && newKeyWillBe !== 'less') {\n return new Response(JSON.stringify({ error: 'newKeyWillBe must be \"greater\" or \"less\"' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n const collection = config.collections.find((c) => c.slug === collectionSlug)\n if (!collection) {\n return new Response(JSON.stringify({ error: `Collection ${collectionSlug} not found` }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n if (typeof orderableFieldName !== 'string') {\n return new Response(JSON.stringify({ error: 'orderableFieldName must be a string' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n\n const { joinScopeWhere, targetDoc } = await getJoinScopeContext({\n collectionSlug: collection.slug,\n joinFieldPathsByCollection,\n orderableFieldName,\n req,\n target,\n })\n\n // Prevent reordering if user doesn't have editing permissions\n if (collection.access?.update) {\n await executeAccess(\n {\n // Currently only one doc can be moved at a time. We should review this if we want to allow\n // multiple docs to be moved at once in the future.\n id: docsToMove[0],\n data: {},\n req,\n },\n collection.access.update,\n )\n }\n /**\n * If there is no target.key, we can assume the user enabled `orderable`\n * on a collection with existing documents, and that this is the first\n * time they tried to reorder them. Therefore, we perform a one-time\n * migration by setting the key value for all documents. We do this\n * instead of enforcing `required` and `unique` at the database schema\n * level, so that users don't have to run a migration when they enable\n * `orderable` on a collection with existing documents.\n */\n if (!target.key) {\n const { docs } = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 0,\n req,\n select: { [orderableFieldName]: true },\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n exists: false,\n },\n },\n joinScopeWhere ?? undefined,\n ]),\n })\n await initTransaction(req)\n // We cannot update all documents in a single operation with `payload.update`,\n // because they would all end up with the same order key (`a0`).\n try {\n for (const doc of docs) {\n await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: {\n // no data needed since the order hooks will handle this\n },\n depth: 0,\n req,\n })\n await commitTransaction(req)\n }\n } catch (e) {\n await killTransaction(req)\n if (e instanceof Error) {\n throw new APIError(e.message, httpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n return new Response(JSON.stringify({ message: 'initial migration', success: true }), {\n headers: { 'Content-Type': 'application/json' },\n status: 200,\n })\n }\n\n if (\n typeof target !== 'object' ||\n typeof target.id === 'undefined' ||\n typeof target.key !== 'string'\n ) {\n return new Response(JSON.stringify({ error: 'target must be an object with id' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n\n const targetId = target.id\n const targetKey = await resolvePendingTargetKey({\n collectionSlug: collection.slug,\n orderableFieldName,\n req,\n targetDoc,\n targetID: targetId,\n targetKey: target.key,\n })\n\n // The reason the endpoint does not receive this docId as an argument is that there\n // are situations where the user may not see or know what the next or previous one is. For\n // example, access control restrictions, if docBefore is the last one on the page, etc.\n const adjacentDoc = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 1,\n pagination: false,\n select: { [orderableFieldName]: true },\n sort: newKeyWillBe === 'greater' ? orderableFieldName : `-${orderableFieldName}`,\n where: combineWhereConstraints([\n {\n [orderableFieldName]: {\n [newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: targetKey,\n },\n },\n joinScopeWhere ?? undefined,\n ]),\n })\n const adjacentDocKey = adjacentDoc.docs?.[0]?.[orderableFieldName] || null\n\n // Currently N (= docsToMove.length) is always 1. Maybe in the future we will\n // allow dragging and reordering multiple documents at once via the UI.\n const orderValues =\n newKeyWillBe === 'greater'\n ? generateNKeysBetween(targetKey, adjacentDocKey, docsToMove.length)\n : generateNKeysBetween(adjacentDocKey, targetKey, docsToMove.length)\n\n // Update each document with its new order value\n for (const [index, id] of docsToMove.entries()) {\n await req.payload.update({\n id,\n collection: collection.slug,\n data: {\n [orderableFieldName]: orderValues[index],\n },\n depth: 0,\n req,\n })\n }\n\n return new Response(JSON.stringify({ orderValues, success: true }), {\n headers: { 'Content-Type': 'application/json' },\n status: 200,\n })\n }\n\n const reorderEndpoint: Endpoint = {\n handler: reorderHandler,\n method: 'post',\n path: '/reorder',\n }\n\n if (!config.endpoints) {\n config.endpoints = []\n }\n\n config.endpoints.push(reorderEndpoint)\n}\n"],"names":["status","httpStatus","executeAccess","APIError","combineWhereConstraints","commitTransaction","initTransaction","killTransaction","traverseFields","generateKeyBetween","generateNKeysBetween","getJoinScopeContext","getJoinScopeWhereFromDocData","resolvePendingTargetKey","setupOrderable","config","fieldsToAdd","Map","joinFieldPathsByCollection","collections","forEach","collection","orderable","currentFields","get","set","defaultSort","callback","field","parentRef","ref","type","parentPrefix","prefix","name","Array","isArray","BAD_REQUEST","relationshipCollection","find","c","slug","joinOrderableFieldName","currentJoinFieldPaths","on","fields","from","entries","orderableFields","addOrderableFieldsAndHook","size","addOrderableEndpoint","orderableFieldNames","orderableFieldName","orderField","admin","disableBulkEdit","disabled","disableGroupBy","disableListColumn","disableListFilter","hidden","readOnly","hooks","beforeDuplicate","siblingData","index","unshift","beforeChange","orderBeforeChangeHook","data","originalDoc","req","joinScopeWhere","collectionSlug","lastDoc","payload","depth","limit","pagination","select","sort","where","exists","undefined","lastOrderValue","docs","push","reorderHandler","body","json","docsToMove","newKeyWillBe","target","length","Response","JSON","stringify","error","headers","targetDoc","access","update","id","key","doc","e","Error","message","INTERNAL_SERVER_ERROR","success","targetId","targetKey","targetID","adjacentDoc","adjacentDocKey","orderValues","reorderEndpoint","handler","method","path","endpoints"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Where } from '../../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a `where` fragment that scopes order operations to docs sharing the
|
|
4
|
+
* same join `on` field value.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildJoinScopeWhere(args: {
|
|
7
|
+
joinOnFieldPath: string;
|
|
8
|
+
scopeValue: unknown;
|
|
9
|
+
}): null | Where;
|
|
10
|
+
//# sourceMappingURL=buildJoinScopeWhere.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildJoinScopeWhere.d.ts","sourceRoot":"","sources":["../../../../src/config/orderable/utils/buildJoinScopeWhere.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAEpD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,OAAO,CAAA;CACpB,GAAG,IAAI,GAAG,KAAK,CAgDf"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a `where` fragment that scopes order operations to docs sharing the
|
|
3
|
+
* same join `on` field value.
|
|
4
|
+
*/ export function buildJoinScopeWhere(args) {
|
|
5
|
+
const { joinOnFieldPath, scopeValue } = args;
|
|
6
|
+
if (typeof scopeValue === 'undefined') {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
if (Array.isArray(scopeValue)) {
|
|
10
|
+
return buildJoinScopeWhere({
|
|
11
|
+
joinOnFieldPath,
|
|
12
|
+
scopeValue: scopeValue[0]
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (scopeValue && typeof scopeValue === 'object' && 'relationTo' in scopeValue && 'value' in scopeValue) {
|
|
16
|
+
const relation = scopeValue.relationTo;
|
|
17
|
+
const value = scopeValue.value;
|
|
18
|
+
if (typeof relation === 'undefined' || typeof value === 'undefined') {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
and: [
|
|
23
|
+
{
|
|
24
|
+
[`${joinOnFieldPath}.relationTo`]: {
|
|
25
|
+
equals: relation
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
[`${joinOnFieldPath}.value`]: {
|
|
30
|
+
equals: value
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
[joinOnFieldPath]: {
|
|
38
|
+
equals: scopeValue
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=buildJoinScopeWhere.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/config/orderable/utils/buildJoinScopeWhere.ts"],"sourcesContent":["import type { Where } from '../../../types/index.js'\n\n/**\n * Builds a `where` fragment that scopes order operations to docs sharing the\n * same join `on` field value.\n */\nexport function buildJoinScopeWhere(args: {\n joinOnFieldPath: string\n scopeValue: unknown\n}): null | Where {\n const { joinOnFieldPath, scopeValue } = args\n\n if (typeof scopeValue === 'undefined') {\n return null\n }\n\n if (Array.isArray(scopeValue)) {\n return buildJoinScopeWhere({\n joinOnFieldPath,\n scopeValue: scopeValue[0],\n })\n }\n\n if (\n scopeValue &&\n typeof scopeValue === 'object' &&\n 'relationTo' in scopeValue &&\n 'value' in scopeValue\n ) {\n const relation = (scopeValue as { relationTo?: unknown }).relationTo\n const value = (scopeValue as { value?: unknown }).value\n\n if (typeof relation === 'undefined' || typeof value === 'undefined') {\n return null\n }\n\n return {\n and: [\n {\n [`${joinOnFieldPath}.relationTo`]: {\n equals: relation,\n },\n },\n {\n [`${joinOnFieldPath}.value`]: {\n equals: value,\n },\n },\n ],\n }\n }\n\n return {\n [joinOnFieldPath]: {\n equals: scopeValue,\n },\n }\n}\n"],"names":["buildJoinScopeWhere","args","joinOnFieldPath","scopeValue","Array","isArray","relation","relationTo","value","and","equals"],"mappings":"AAEA;;;CAGC,GACD,OAAO,SAASA,oBAAoBC,IAGnC;IACC,MAAM,EAAEC,eAAe,EAAEC,UAAU,EAAE,GAAGF;IAExC,IAAI,OAAOE,eAAe,aAAa;QACrC,OAAO;IACT;IAEA,IAAIC,MAAMC,OAAO,CAACF,aAAa;QAC7B,OAAOH,oBAAoB;YACzBE;YACAC,YAAYA,UAAU,CAAC,EAAE;QAC3B;IACF;IAEA,IACEA,cACA,OAAOA,eAAe,YACtB,gBAAgBA,cAChB,WAAWA,YACX;QACA,MAAMG,WAAW,AAACH,WAAwCI,UAAU;QACpE,MAAMC,QAAQ,AAACL,WAAmCK,KAAK;QAEvD,IAAI,OAAOF,aAAa,eAAe,OAAOE,UAAU,aAAa;YACnE,OAAO;QACT;QAEA,OAAO;YACLC,KAAK;gBACH;oBACE,CAAC,GAAGP,gBAAgB,WAAW,CAAC,CAAC,EAAE;wBACjCQ,QAAQJ;oBACV;gBACF;gBACA;oBACE,CAAC,GAAGJ,gBAAgB,MAAM,CAAC,CAAC,EAAE;wBAC5BQ,QAAQF;oBACV;gBACF;aACD;QACH;IACF;IAEA,OAAO;QACL,CAACN,gBAAgB,EAAE;YACjBQ,QAAQP;QACV;IACF;AACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PayloadHandler } from '../../types.js';
|
|
2
|
+
import { buildJoinScopeWhere } from './buildJoinScopeWhere.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves join scope and target document context for reorder operations.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getJoinScopeContext(args: {
|
|
7
|
+
collectionSlug: string;
|
|
8
|
+
joinFieldPathsByCollection: Map<string, Map<string, string>>;
|
|
9
|
+
orderableFieldName: string;
|
|
10
|
+
req: Parameters<PayloadHandler>[0];
|
|
11
|
+
target: unknown;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
joinScopeWhere: ReturnType<typeof buildJoinScopeWhere>;
|
|
14
|
+
targetDoc: null | Record<string, unknown>;
|
|
15
|
+
}>;
|
|
16
|
+
//# sourceMappingURL=getJoinScopeContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getJoinScopeContext.d.ts","sourceRoot":"","sources":["../../../../src/config/orderable/utils/getJoinScopeContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAG9D;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,cAAc,EAAE,MAAM,CAAA;IACtB,0BAA0B,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC5D,kBAAkB,EAAE,MAAM,CAAA;IAC1B,GAAG,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;IAClC,MAAM,EAAE,OAAO,CAAA;CAChB,GAAG,OAAO,CAAC;IACV,cAAc,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA;IACtD,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC1C,CAAC,CA4CD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { buildJoinScopeWhere } from './buildJoinScopeWhere.js';
|
|
2
|
+
import { getValueAtPath } from './getValueAtPath.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves join scope and target document context for reorder operations.
|
|
5
|
+
*/ export async function getJoinScopeContext(args) {
|
|
6
|
+
const { collectionSlug, joinFieldPathsByCollection, orderableFieldName, req, target } = args;
|
|
7
|
+
const joinOnFieldPath = joinFieldPathsByCollection.get(collectionSlug)?.get(orderableFieldName);
|
|
8
|
+
let targetDoc = null;
|
|
9
|
+
if (typeof target === 'object' && target && 'id' in target && (joinOnFieldPath || 'key' in target && target.key === 'pending')) {
|
|
10
|
+
const targetID = target.id;
|
|
11
|
+
if (typeof targetID === 'number' || typeof targetID === 'string') {
|
|
12
|
+
targetDoc = await req.payload.findByID({
|
|
13
|
+
id: targetID,
|
|
14
|
+
collection: collectionSlug,
|
|
15
|
+
depth: 0,
|
|
16
|
+
req,
|
|
17
|
+
select: {
|
|
18
|
+
...joinOnFieldPath ? {
|
|
19
|
+
[joinOnFieldPath]: true
|
|
20
|
+
} : {},
|
|
21
|
+
[orderableFieldName]: true
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (!joinOnFieldPath) {
|
|
27
|
+
return {
|
|
28
|
+
joinScopeWhere: null,
|
|
29
|
+
targetDoc
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const joinScopeValue = getValueAtPath(targetDoc, joinOnFieldPath);
|
|
33
|
+
return {
|
|
34
|
+
joinScopeWhere: buildJoinScopeWhere({
|
|
35
|
+
joinOnFieldPath,
|
|
36
|
+
scopeValue: joinScopeValue
|
|
37
|
+
}),
|
|
38
|
+
targetDoc
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=getJoinScopeContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/config/orderable/utils/getJoinScopeContext.ts"],"sourcesContent":["import type { PayloadHandler } from '../../types.js'\n\nimport { buildJoinScopeWhere } from './buildJoinScopeWhere.js'\nimport { getValueAtPath } from './getValueAtPath.js'\n\n/**\n * Resolves join scope and target document context for reorder operations.\n */\nexport async function getJoinScopeContext(args: {\n collectionSlug: string\n joinFieldPathsByCollection: Map<string, Map<string, string>>\n orderableFieldName: string\n req: Parameters<PayloadHandler>[0]\n target: unknown\n}): Promise<{\n joinScopeWhere: ReturnType<typeof buildJoinScopeWhere>\n targetDoc: null | Record<string, unknown>\n}> {\n const { collectionSlug, joinFieldPathsByCollection, orderableFieldName, req, target } = args\n\n const joinOnFieldPath = joinFieldPathsByCollection.get(collectionSlug)?.get(orderableFieldName)\n let targetDoc: null | Record<string, unknown> = null\n\n if (\n typeof target === 'object' &&\n target &&\n 'id' in target &&\n (joinOnFieldPath || ('key' in target && target.key === 'pending'))\n ) {\n const targetID = (target as { id?: unknown }).id\n\n if (typeof targetID === 'number' || typeof targetID === 'string') {\n targetDoc = await req.payload.findByID({\n id: targetID,\n collection: collectionSlug,\n depth: 0,\n req,\n select: {\n ...(joinOnFieldPath ? { [joinOnFieldPath]: true } : {}),\n [orderableFieldName]: true,\n },\n })\n }\n }\n\n if (!joinOnFieldPath) {\n return {\n joinScopeWhere: null,\n targetDoc,\n }\n }\n\n const joinScopeValue = getValueAtPath(targetDoc, joinOnFieldPath)\n\n return {\n joinScopeWhere: buildJoinScopeWhere({\n joinOnFieldPath,\n scopeValue: joinScopeValue,\n }),\n targetDoc,\n }\n}\n"],"names":["buildJoinScopeWhere","getValueAtPath","getJoinScopeContext","args","collectionSlug","joinFieldPathsByCollection","orderableFieldName","req","target","joinOnFieldPath","get","targetDoc","key","targetID","id","payload","findByID","collection","depth","select","joinScopeWhere","joinScopeValue","scopeValue"],"mappings":"AAEA,SAASA,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,cAAc,QAAQ,sBAAqB;AAEpD;;CAEC,GACD,OAAO,eAAeC,oBAAoBC,IAMzC;IAIC,MAAM,EAAEC,cAAc,EAAEC,0BAA0B,EAAEC,kBAAkB,EAAEC,GAAG,EAAEC,MAAM,EAAE,GAAGL;IAExF,MAAMM,kBAAkBJ,2BAA2BK,GAAG,CAACN,iBAAiBM,IAAIJ;IAC5E,IAAIK,YAA4C;IAEhD,IACE,OAAOH,WAAW,YAClBA,UACA,QAAQA,UACPC,CAAAA,mBAAoB,SAASD,UAAUA,OAAOI,GAAG,KAAK,SAAS,GAChE;QACA,MAAMC,WAAW,AAACL,OAA4BM,EAAE;QAEhD,IAAI,OAAOD,aAAa,YAAY,OAAOA,aAAa,UAAU;YAChEF,YAAY,MAAMJ,IAAIQ,OAAO,CAACC,QAAQ,CAAC;gBACrCF,IAAID;gBACJI,YAAYb;gBACZc,OAAO;gBACPX;gBACAY,QAAQ;oBACN,GAAIV,kBAAkB;wBAAE,CAACA,gBAAgB,EAAE;oBAAK,IAAI,CAAC,CAAC;oBACtD,CAACH,mBAAmB,EAAE;gBACxB;YACF;QACF;IACF;IAEA,IAAI,CAACG,iBAAiB;QACpB,OAAO;YACLW,gBAAgB;YAChBT;QACF;IACF;IAEA,MAAMU,iBAAiBpB,eAAeU,WAAWF;IAEjD,OAAO;QACLW,gBAAgBpB,oBAAoB;YAClCS;YACAa,YAAYD;QACd;QACAV;IACF;AACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { buildJoinScopeWhere } from './buildJoinScopeWhere.js';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a join-scope filter for order key generation during beforeChange.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getJoinScopeWhereFromDocData(args: {
|
|
6
|
+
collectionSlug: string;
|
|
7
|
+
data: Record<string, unknown>;
|
|
8
|
+
joinFieldPathsByCollection?: Map<string, Map<string, string>>;
|
|
9
|
+
orderableFieldName: string;
|
|
10
|
+
originalDoc?: Record<string, unknown>;
|
|
11
|
+
}): ReturnType<typeof buildJoinScopeWhere>;
|
|
12
|
+
//# sourceMappingURL=getJoinScopeWhereFromDocData.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getJoinScopeWhereFromDocData.d.ts","sourceRoot":"","sources":["../../../../src/config/orderable/utils/getJoinScopeWhereFromDocData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAG9D;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,0BAA0B,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC7D,kBAAkB,EAAE,MAAM,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACtC,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAgBzC"}
|