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.
Files changed (135) hide show
  1. package/dist/auth/endpoints/forgotPassword.d.ts.map +1 -1
  2. package/dist/auth/endpoints/forgotPassword.js +0 -2
  3. package/dist/auth/endpoints/forgotPassword.js.map +1 -1
  4. package/dist/auth/extractJWT.d.ts.map +1 -1
  5. package/dist/auth/extractJWT.js +18 -4
  6. package/dist/auth/extractJWT.js.map +1 -1
  7. package/dist/auth/operations/forgotPassword.d.ts.map +1 -1
  8. package/dist/auth/operations/forgotPassword.js +5 -4
  9. package/dist/auth/operations/forgotPassword.js.map +1 -1
  10. package/dist/auth/operations/me.js +5 -5
  11. package/dist/auth/operations/me.js.map +1 -1
  12. package/dist/auth/sendVerificationEmail.d.ts.map +1 -1
  13. package/dist/auth/sendVerificationEmail.js +5 -4
  14. package/dist/auth/sendVerificationEmail.js.map +1 -1
  15. package/dist/collections/operations/update.js +1 -1
  16. package/dist/collections/operations/update.js.map +1 -1
  17. package/dist/collections/operations/utilities/update.d.ts.map +1 -1
  18. package/dist/collections/operations/utilities/update.js +2 -1
  19. package/dist/collections/operations/utilities/update.js.map +1 -1
  20. package/dist/config/orderable/index.d.ts +2 -2
  21. package/dist/config/orderable/index.d.ts.map +1 -1
  22. package/dist/config/orderable/index.js +60 -34
  23. package/dist/config/orderable/index.js.map +1 -1
  24. package/dist/config/orderable/utils/buildJoinScopeWhere.d.ts +10 -0
  25. package/dist/config/orderable/utils/buildJoinScopeWhere.d.ts.map +1 -0
  26. package/dist/config/orderable/utils/buildJoinScopeWhere.js +43 -0
  27. package/dist/config/orderable/utils/buildJoinScopeWhere.js.map +1 -0
  28. package/dist/config/orderable/utils/getJoinScopeContext.d.ts +16 -0
  29. package/dist/config/orderable/utils/getJoinScopeContext.d.ts.map +1 -0
  30. package/dist/config/orderable/utils/getJoinScopeContext.js +42 -0
  31. package/dist/config/orderable/utils/getJoinScopeContext.js.map +1 -0
  32. package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.d.ts +12 -0
  33. package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.d.ts.map +1 -0
  34. package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.js +18 -0
  35. package/dist/config/orderable/utils/getJoinScopeWhereFromDocData.js.map +1 -0
  36. package/dist/config/orderable/utils/getValueAtPath.d.ts +5 -0
  37. package/dist/config/orderable/utils/getValueAtPath.d.ts.map +1 -0
  38. package/dist/config/orderable/utils/getValueAtPath.js +18 -0
  39. package/dist/config/orderable/utils/getValueAtPath.js.map +1 -0
  40. package/dist/config/orderable/utils/resolvePendingTargetKey.d.ts +13 -0
  41. package/dist/config/orderable/utils/resolvePendingTargetKey.d.ts.map +1 -0
  42. package/dist/config/orderable/utils/resolvePendingTargetKey.js +24 -0
  43. package/dist/config/orderable/utils/resolvePendingTargetKey.js.map +1 -0
  44. package/dist/config/types.d.ts +1 -1
  45. package/dist/config/types.js.map +1 -1
  46. package/dist/database/getLocalizedPaths.d.ts.map +1 -1
  47. package/dist/database/getLocalizedPaths.js +2 -1
  48. package/dist/database/getLocalizedPaths.js.map +1 -1
  49. package/dist/database/queryValidation/validateQueryPaths.js +1 -1
  50. package/dist/database/queryValidation/validateQueryPaths.js.map +1 -1
  51. package/dist/database/queryValidation/validateSearchParams.d.ts.map +1 -1
  52. package/dist/database/queryValidation/validateSearchParams.js +2 -1
  53. package/dist/database/queryValidation/validateSearchParams.js.map +1 -1
  54. package/dist/database/sanitizeJoinQuery.d.ts.map +1 -1
  55. package/dist/database/sanitizeJoinQuery.js +6 -0
  56. package/dist/database/sanitizeJoinQuery.js.map +1 -1
  57. package/dist/database/types.d.ts +0 -1
  58. package/dist/database/types.d.ts.map +1 -1
  59. package/dist/database/types.js.map +1 -1
  60. package/dist/exports/shared.d.ts +1 -0
  61. package/dist/exports/shared.d.ts.map +1 -1
  62. package/dist/exports/shared.js +1 -0
  63. package/dist/exports/shared.js.map +1 -1
  64. package/dist/fields/baseFields/slug/index.d.ts +7 -0
  65. package/dist/fields/baseFields/slug/index.d.ts.map +1 -1
  66. package/dist/fields/baseFields/slug/index.js +2 -2
  67. package/dist/fields/baseFields/slug/index.js.map +1 -1
  68. package/dist/fields/validations.js +1 -1
  69. package/dist/fields/validations.js.map +1 -1
  70. package/dist/fields/validations.spec.js +25 -0
  71. package/dist/fields/validations.spec.js.map +1 -1
  72. package/dist/globals/operations/update.d.ts.map +1 -1
  73. package/dist/globals/operations/update.js +2 -1
  74. package/dist/globals/operations/update.js.map +1 -1
  75. package/dist/index.bundled.d.ts +16 -13
  76. package/dist/index.d.ts +1 -7
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +1 -10
  79. package/dist/index.js.map +1 -1
  80. package/dist/queues/localAPI.d.ts +0 -1
  81. package/dist/queues/localAPI.d.ts.map +1 -1
  82. package/dist/queues/localAPI.js +0 -4
  83. package/dist/queues/localAPI.js.map +1 -1
  84. package/dist/queues/operations/runJobs/index.d.ts +0 -1
  85. package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
  86. package/dist/queues/operations/runJobs/index.js +1 -96
  87. package/dist/queues/operations/runJobs/index.js.map +1 -1
  88. package/dist/queues/utilities/updateJob.d.ts +1 -2
  89. package/dist/queues/utilities/updateJob.d.ts.map +1 -1
  90. package/dist/queues/utilities/updateJob.js +31 -92
  91. package/dist/queues/utilities/updateJob.js.map +1 -1
  92. package/dist/types/constants.d.ts +5 -0
  93. package/dist/types/constants.d.ts.map +1 -1
  94. package/dist/types/constants.js +4 -0
  95. package/dist/types/constants.js.map +1 -1
  96. package/dist/uploads/endpoints/getFile.d.ts.map +1 -1
  97. package/dist/uploads/endpoints/getFile.js +7 -1
  98. package/dist/uploads/endpoints/getFile.js.map +1 -1
  99. package/dist/uploads/endpoints/getFileFromURL.d.ts.map +1 -1
  100. package/dist/uploads/endpoints/getFileFromURL.js +67 -28
  101. package/dist/uploads/endpoints/getFileFromURL.js.map +1 -1
  102. package/dist/uploads/getExternalFile.d.ts.map +1 -1
  103. package/dist/uploads/getExternalFile.js +3 -0
  104. package/dist/uploads/getExternalFile.js.map +1 -1
  105. package/dist/uploads/safeFetch.d.ts +1 -1
  106. package/dist/uploads/safeFetch.d.ts.map +1 -1
  107. package/dist/uploads/safeFetch.js.map +1 -1
  108. package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
  109. package/dist/utilities/addDataAndFileToRequest.js +7 -1
  110. package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
  111. package/dist/utilities/configToJSONSchema.d.ts +7 -3
  112. package/dist/utilities/configToJSONSchema.d.ts.map +1 -1
  113. package/dist/utilities/configToJSONSchema.js +23 -33
  114. package/dist/utilities/configToJSONSchema.js.map +1 -1
  115. package/dist/utilities/configToJSONSchema.spec.js +75 -1
  116. package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
  117. package/dist/utilities/getRequestOrigin.d.ts +10 -0
  118. package/dist/utilities/getRequestOrigin.d.ts.map +1 -0
  119. package/dist/utilities/getRequestOrigin.js +50 -0
  120. package/dist/utilities/getRequestOrigin.js.map +1 -0
  121. package/dist/utilities/getRequestOrigin.spec.js +151 -0
  122. package/dist/utilities/getRequestOrigin.spec.js.map +1 -0
  123. package/dist/utilities/sanitizeUrl.d.ts +7 -0
  124. package/dist/utilities/sanitizeUrl.d.ts.map +1 -0
  125. package/dist/utilities/sanitizeUrl.js +28 -0
  126. package/dist/utilities/sanitizeUrl.js.map +1 -0
  127. package/dist/versions/saveVersion.d.ts +1 -0
  128. package/dist/versions/saveVersion.d.ts.map +1 -1
  129. package/dist/versions/saveVersion.js +16 -66
  130. package/dist/versions/saveVersion.js.map +1 -1
  131. package/dist/versions/updateLatestVersion.d.ts +24 -0
  132. package/dist/versions/updateLatestVersion.d.ts.map +1 -0
  133. package/dist/versions/updateLatestVersion.js +64 -0
  134. package/dist/versions/updateLatestVersion.js.map +1 -0
  135. 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;AAU5E;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,WAAY,eAAe,SAuDrD,CAAA;AAED,eAAO,MAAM,yBAAyB,eACxB,gBAAgB,uBACP,MAAM,EAAE,SAgE9B,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,WAAY,eAAe,SAkL3D,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
- `_${field.collection}_${prefix}${field.name}_order`
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
- [orderableFieldName]: {
114
- exists: true
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
- [orderableFieldName]: {
201
- exists: false
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
- let targetKey = target.key;
248
- // If targetKey = pending, we need to find its current key.
249
- // This can only happen if the user reorders rows quickly with a slow connection.
250
- if (targetKey === 'pending') {
251
- const beforeDoc = await req.payload.findByID({
252
- id: targetId,
253
- collection: collection.slug,
254
- depth: 0,
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
- [orderableFieldName]: {
275
- [newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: targetKey
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"}