payload 4.0.0-internal.cd69eef → 4.0.0-internal.d1cc1d3
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/admin/RichText.d.ts +1 -1
- package/dist/admin/RichText.d.ts.map +1 -1
- package/dist/admin/RichText.js.map +1 -1
- package/dist/admin/functions/index.d.ts +10 -8
- package/dist/admin/functions/index.d.ts.map +1 -1
- package/dist/admin/functions/index.js.map +1 -1
- package/dist/admin/types.d.ts +2 -2
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/admin/types.js.map +1 -1
- package/dist/auth/endpoints/login.d.ts.map +1 -1
- package/dist/auth/endpoints/login.js +2 -11
- package/dist/auth/endpoints/login.js.map +1 -1
- package/dist/auth/loginWithCookie.d.ts +33 -0
- package/dist/auth/loginWithCookie.d.ts.map +1 -0
- package/dist/auth/loginWithCookie.js +34 -0
- package/dist/auth/loginWithCookie.js.map +1 -0
- package/dist/auth/serverFunctions/cookies.d.ts +47 -0
- package/dist/auth/serverFunctions/cookies.d.ts.map +1 -0
- package/dist/auth/serverFunctions/cookies.js +52 -0
- package/dist/auth/serverFunctions/cookies.js.map +1 -0
- package/dist/auth/serverFunctions/login.d.ts +29 -0
- package/dist/auth/serverFunctions/login.d.ts.map +1 -0
- package/dist/auth/serverFunctions/login.js +63 -0
- package/dist/auth/serverFunctions/login.js.map +1 -0
- package/dist/auth/serverFunctions/logout.d.ts +17 -0
- package/dist/auth/serverFunctions/logout.d.ts.map +1 -0
- package/dist/auth/serverFunctions/logout.js +58 -0
- package/dist/auth/serverFunctions/logout.js.map +1 -0
- package/dist/auth/serverFunctions/refresh.d.ts +17 -0
- package/dist/auth/serverFunctions/refresh.d.ts.map +1 -0
- package/dist/auth/serverFunctions/refresh.js +61 -0
- package/dist/auth/serverFunctions/refresh.js.map +1 -0
- package/dist/collections/config/client.d.ts +2 -3
- package/dist/collections/config/client.d.ts.map +1 -1
- package/dist/collections/config/client.js +5 -7
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/config/defaults.d.ts.map +1 -1
- package/dist/collections/config/defaults.js +1 -0
- package/dist/collections/config/defaults.js.map +1 -1
- package/dist/collections/config/sanitize.d.ts +3 -8
- package/dist/collections/config/sanitize.d.ts.map +1 -1
- package/dist/collections/config/sanitize.js +2 -6
- package/dist/collections/config/sanitize.js.map +1 -1
- package/dist/collections/config/types.d.ts +1 -1
- package/dist/collections/config/types.d.ts.map +1 -1
- package/dist/collections/config/types.js.map +1 -1
- package/dist/collections/config/useAsTitle.spec.js +27 -27
- package/dist/collections/config/useAsTitle.spec.js.map +1 -1
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +10 -0
- package/dist/collections/operations/create.js.map +1 -1
- package/dist/collections/operations/restoreVersion.d.ts.map +1 -1
- package/dist/collections/operations/restoreVersion.js +7 -4
- package/dist/collections/operations/restoreVersion.js.map +1 -1
- package/dist/collections/operations/updateByID.js +1 -0
- package/dist/collections/operations/updateByID.js.map +1 -1
- package/dist/config/build.js +1 -1
- package/dist/config/build.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +5 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/orderable/index.d.ts +1 -1
- package/dist/config/orderable/index.d.ts.map +1 -1
- package/dist/config/orderable/index.js +2 -2
- package/dist/config/orderable/index.js.map +1 -1
- package/dist/config/sanitize.d.ts +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +33 -40
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/createDatabaseAdapter.d.ts +1 -1
- package/dist/database/createDatabaseAdapter.d.ts.map +1 -1
- package/dist/database/createDatabaseAdapter.js +0 -2
- package/dist/database/createDatabaseAdapter.js.map +1 -1
- package/dist/database/types.d.ts +6 -0
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/exports/auth.d.ts +5 -0
- package/dist/exports/auth.d.ts.map +1 -0
- package/dist/exports/auth.js +6 -0
- package/dist/exports/auth.js.map +1 -0
- package/dist/exports/internal.d.ts +2 -0
- package/dist/exports/internal.d.ts.map +1 -1
- package/dist/exports/internal.js +3 -1
- package/dist/exports/internal.js.map +1 -1
- package/dist/fields/baseFields/slug/duplicateContext.d.ts +11 -0
- package/dist/fields/baseFields/slug/duplicateContext.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/duplicateContext.js +21 -0
- package/dist/fields/baseFields/slug/duplicateContext.js.map +1 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.d.ts +22 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.js +63 -0
- package/dist/fields/baseFields/slug/fillEmptyLocalizedSlugs.js.map +1 -0
- package/dist/fields/baseFields/slug/generateSlug.d.ts +13 -8
- package/dist/fields/baseFields/slug/generateSlug.d.ts.map +1 -1
- package/dist/fields/baseFields/slug/generateSlug.js +98 -45
- package/dist/fields/baseFields/slug/generateSlug.js.map +1 -1
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.d.ts +18 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.js +20 -0
- package/dist/fields/baseFields/slug/generateSlugBeforeDuplicate.js.map +1 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.d.ts +22 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.js +23 -0
- package/dist/fields/baseFields/slug/getSlugFallbackValue.js.map +1 -0
- package/dist/fields/baseFields/slug/hasValue.d.ts +3 -0
- package/dist/fields/baseFields/slug/hasValue.d.ts.map +1 -0
- package/dist/fields/baseFields/slug/hasValue.js +3 -0
- package/dist/fields/baseFields/slug/hasValue.js.map +1 -0
- package/dist/fields/config/reservedFieldNames.spec.js +18 -18
- package/dist/fields/config/reservedFieldNames.spec.js.map +1 -1
- package/dist/fields/config/sanitize.d.ts +3 -9
- package/dist/fields/config/sanitize.d.ts.map +1 -1
- package/dist/fields/config/sanitize.js +33 -34
- package/dist/fields/config/sanitize.js.map +1 -1
- package/dist/fields/config/sanitize.spec.js +128 -105
- package/dist/fields/config/sanitize.spec.js.map +1 -1
- package/dist/fields/config/types.d.ts +4 -3
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/config/types.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.js +5 -3
- package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts +10 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.d.ts.map +1 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js +18 -0
- package/dist/fields/hooks/beforeValidate/stripNullRows.js.map +1 -0
- package/dist/fields/validations.d.ts.map +1 -1
- package/dist/fields/validations.js +7 -8
- package/dist/fields/validations.js.map +1 -1
- package/dist/fields/validations.spec.js +61 -37
- package/dist/fields/validations.spec.js.map +1 -1
- package/dist/globals/config/sanitize.d.ts +2 -7
- package/dist/globals/config/sanitize.d.ts.map +1 -1
- package/dist/globals/config/sanitize.js +2 -6
- package/dist/globals/config/sanitize.js.map +1 -1
- package/dist/globals/config/sanitize.spec.js +6 -6
- package/dist/globals/config/sanitize.spec.js.map +1 -1
- package/dist/globals/operations/countGlobalVersions.d.ts.map +1 -1
- package/dist/globals/operations/countGlobalVersions.js +1 -0
- package/dist/globals/operations/countGlobalVersions.js.map +1 -1
- package/dist/index.bundled.d.ts +247 -178
- package/dist/index.d.ts +49 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/query-presets/constraints.js +1 -1
- package/dist/query-presets/constraints.js.map +1 -1
- package/dist/queues/config/collection.d.ts.map +1 -1
- package/dist/queues/config/collection.js +37 -43
- package/dist/queues/config/collection.js.map +1 -1
- package/dist/queues/config/global.d.ts +5 -6
- package/dist/queues/config/global.d.ts.map +1 -1
- package/dist/queues/config/global.js +1 -1
- package/dist/queues/config/global.js.map +1 -1
- package/dist/queues/config/types/index.d.ts +29 -24
- package/dist/queues/config/types/index.d.ts.map +1 -1
- package/dist/queues/config/types/index.js.map +1 -1
- package/dist/queues/config/types/taskTypes.d.ts +4 -7
- package/dist/queues/config/types/taskTypes.d.ts.map +1 -1
- package/dist/queues/config/types/taskTypes.js.map +1 -1
- package/dist/queues/config/types/workflowJSONTypes.d.ts +10 -9
- package/dist/queues/config/types/workflowJSONTypes.d.ts.map +1 -1
- package/dist/queues/config/types/workflowJSONTypes.js.map +1 -1
- package/dist/queues/config/types/workflowTypes.d.ts +11 -58
- package/dist/queues/config/types/workflowTypes.d.ts.map +1 -1
- package/dist/queues/config/types/workflowTypes.js.map +1 -1
- package/dist/queues/endpoints/handleSchedules.js +1 -1
- package/dist/queues/endpoints/handleSchedules.js.map +1 -1
- package/dist/queues/errors/handleTaskError.js +4 -4
- package/dist/queues/errors/handleTaskError.js.map +1 -1
- package/dist/queues/errors/handleWorkflowError.js +1 -1
- package/dist/queues/errors/handleWorkflowError.js.map +1 -1
- package/dist/queues/errors/index.d.ts +6 -0
- package/dist/queues/errors/index.d.ts.map +1 -1
- package/dist/queues/errors/index.js +5 -0
- package/dist/queues/errors/index.js.map +1 -1
- package/dist/queues/localAPI.d.ts +4 -4
- package/dist/queues/localAPI.d.ts.map +1 -1
- package/dist/queues/localAPI.js +63 -66
- package/dist/queues/localAPI.js.map +1 -1
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.d.ts +4 -4
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.d.ts.map +1 -1
- package/dist/queues/operations/handleSchedules/countRunnableOrActiveJobsForQueue.js.map +1 -1
- package/dist/queues/operations/handleSchedules/index.d.ts +1 -1
- package/dist/queues/operations/handleSchedules/index.d.ts.map +1 -1
- package/dist/queues/operations/handleSchedules/index.js +1 -1
- package/dist/queues/operations/handleSchedules/index.js.map +1 -1
- package/dist/queues/operations/runJobs/heartbeat.d.ts +13 -0
- package/dist/queues/operations/runJobs/heartbeat.d.ts.map +1 -0
- package/dist/queues/operations/runJobs/heartbeat.js +66 -0
- package/dist/queues/operations/runJobs/heartbeat.js.map +1 -0
- package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/index.js +133 -84
- package/dist/queues/operations/runJobs/index.js.map +1 -1
- package/dist/queues/operations/runJobs/runJSONJob/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJSONJob/index.js +6 -3
- package/dist/queues/operations/runJobs/runJSONJob/index.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +5 -5
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts +2 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js +39 -8
- package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/importHandlerPath.js.map +1 -1
- package/dist/queues/operations/runJobs/runJob/index.d.ts.map +1 -1
- package/dist/queues/operations/runJobs/runJob/index.js +4 -4
- package/dist/queues/operations/runJobs/runJob/index.js.map +1 -1
- package/dist/queues/utilities/updateJob.d.ts.map +1 -1
- package/dist/queues/utilities/updateJob.js +3 -0
- package/dist/queues/utilities/updateJob.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/uploads/checkFileRestrictions.d.ts +1 -1
- package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
- package/dist/uploads/checkFileRestrictions.js +15 -1
- package/dist/uploads/checkFileRestrictions.js.map +1 -1
- package/dist/uploads/endpoints/uploadInstructions.d.ts +12 -0
- package/dist/uploads/endpoints/uploadInstructions.d.ts.map +1 -1
- package/dist/uploads/endpoints/uploadInstructions.js +66 -20
- package/dist/uploads/endpoints/uploadInstructions.js.map +1 -1
- package/dist/uploads/generateFileData.js +4 -1
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getFileFromUploadInstructions.d.ts +8 -0
- package/dist/uploads/getFileFromUploadInstructions.d.ts.map +1 -0
- package/dist/uploads/getFileFromUploadInstructions.js +62 -0
- package/dist/uploads/getFileFromUploadInstructions.js.map +1 -0
- package/dist/uploads/getImageSize.d.ts +12 -1
- package/dist/uploads/getImageSize.d.ts.map +1 -1
- package/dist/uploads/getImageSize.js +20 -18
- package/dist/uploads/getImageSize.js.map +1 -1
- package/dist/uploads/getImageSize.spec.js +298 -0
- package/dist/uploads/getImageSize.spec.js.map +1 -0
- package/dist/uploads/probeImageSize.d.ts +39 -0
- package/dist/uploads/probeImageSize.d.ts.map +1 -0
- package/dist/uploads/probeImageSize.js +374 -0
- package/dist/uploads/probeImageSize.js.map +1 -0
- package/dist/uploads/probeImageSize.spec.js +366 -0
- package/dist/uploads/probeImageSize.spec.js.map +1 -0
- package/dist/uploads/stagedUpload.d.ts +27 -0
- package/dist/uploads/stagedUpload.d.ts.map +1 -0
- package/dist/uploads/stagedUpload.js +197 -0
- package/dist/uploads/stagedUpload.js.map +1 -0
- package/dist/uploads/types.d.ts +41 -13
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.js +12 -46
- package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
- package/dist/utilities/configToJSONSchema.spec.js +33 -33
- package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
- package/dist/utilities/fieldValueExists.d.ts +29 -0
- package/dist/utilities/fieldValueExists.d.ts.map +1 -0
- package/dist/utilities/fieldValueExists.js +27 -0
- package/dist/utilities/fieldValueExists.js.map +1 -0
- package/dist/utilities/getUniqueFieldValue.d.ts +27 -0
- package/dist/utilities/getUniqueFieldValue.d.ts.map +1 -0
- package/dist/utilities/getUniqueFieldValue.js +26 -0
- package/dist/utilities/getUniqueFieldValue.js.map +1 -0
- package/dist/versions/deleteScheduledPublishJobs.js +2 -2
- package/dist/versions/deleteScheduledPublishJobs.js.map +1 -1
- package/dist/versions/payloadPackageList.d.ts.map +1 -1
- package/dist/versions/payloadPackageList.js +0 -1
- package/dist/versions/payloadPackageList.js.map +1 -1
- package/package.json +8 -3
- package/dist/database/defaultUpdateJobs.d.ts +0 -3
- package/dist/database/defaultUpdateJobs.d.ts.map +0 -1
- package/dist/database/defaultUpdateJobs.js +0 -41
- package/dist/database/defaultUpdateJobs.js.map +0 -1
- package/dist/fields/baseFields/slug/countVersions.d.ts +0 -13
- package/dist/fields/baseFields/slug/countVersions.d.ts.map +0 -1
- package/dist/fields/baseFields/slug/countVersions.js +0 -27
- package/dist/fields/baseFields/slug/countVersions.js.map +0 -1
- package/dist/uploads/tempFile.d.ts +0 -7
- package/dist/uploads/tempFile.d.ts.map +0 -1
- package/dist/uploads/tempFile.js +0 -39
- package/dist/uploads/tempFile.js.map +0 -1
|
@@ -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 { Config } from '../../config/types.js'\nimport type { Field, TextField } 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 { sanitizeField } from '../../fields/config/sanitize.js'\nimport { combineWhereConstraints } from '../../utilities/combineWhereConstraints.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { hasDraftsEnabled } from '../../utilities/getVersionsConfig.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { getLatestCollectionVersion } from '../../versions/getLatestCollectionVersion.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\nexport const addOrderableFieldsAndHook = async (\n collection: CollectionConfig,\n config: Config,\n orderableFieldNames: string[],\n joinFieldPathsByCollection?: Map<string, Map<string, string>>,\n) => {\n // 1. Add fields\n for (const orderableFieldName of orderableFieldNames) {\n const orderField: TextField = {\n name: orderableFieldName,\n type: 'text',\n admin: {\n disabled: 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 // Sanitize the field using the standard sanitization logic\n await sanitizeField({\n collectionConfig: collection,\n config,\n existingFieldNames: new Set(),\n field: orderField,\n index: 0,\n isTopLevelField: true,\n joinPath: '',\n parentIndexPath: '',\n parentIsLocalized: false,\n parentSchemaPath: '',\n requireFieldLevelRichTextEditor: false,\n validRelationships: null,\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 const draftsEnabled = hasDraftsEnabled(collection)\n\n // Update each document with its new order value\n for (const [index, id] of docsToMove.entries()) {\n let draft: boolean | undefined\n\n if (draftsEnabled) {\n const latestVersion = await getLatestCollectionVersion({\n id,\n config: collection,\n payload: req.payload,\n query: {\n collection: collection.slug,\n req,\n where: { id: { equals: id } },\n },\n req,\n })\n\n draft = latestVersion?._status === 'draft'\n }\n\n await req.payload.update({\n id,\n collection: collection.slug,\n data: {\n [orderableFieldName]: orderValues[index],\n },\n depth: 0,\n draft,\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","sanitizeField","combineWhereConstraints","commitTransaction","hasDraftsEnabled","initTransaction","killTransaction","getLatestCollectionVersion","generateKeyBetween","generateNKeysBetween","getJoinScopeContext","getJoinScopeWhereFromDocData","resolvePendingTargetKey","addOrderableFieldsAndHook","collection","config","orderableFieldNames","joinFieldPathsByCollection","orderableFieldName","orderField","name","type","admin","disabled","hidden","readOnly","hooks","beforeDuplicate","siblingData","index","collectionConfig","existingFieldNames","Set","field","isTopLevelField","joinPath","parentIndexPath","parentIsLocalized","parentSchemaPath","requireFieldLevelRichTextEditor","validRelationships","fields","unshift","beforeChange","orderBeforeChangeHook","data","originalDoc","req","joinScopeWhere","collectionSlug","slug","lastDoc","payload","find","depth","limit","pagination","select","sort","where","exists","undefined","lastOrderValue","docs","push","addOrderableEndpoint","reorderHandler","body","json","docsToMove","newKeyWillBe","target","Array","isArray","length","Response","JSON","stringify","error","headers","collections","c","targetDoc","access","update","id","key","doc","e","Error","message","INTERNAL_SERVER_ERROR","success","targetId","targetKey","targetID","adjacentDoc","adjacentDocKey","orderValues","draftsEnabled","entries","draft","latestVersion","query","equals","_status","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 { Config } from '../../config/types.js'\nimport type { Field, TextField } 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 { sanitizeField } from '../../fields/config/sanitize.js'\nimport { combineWhereConstraints } from '../../utilities/combineWhereConstraints.js'\nimport { commitTransaction } from '../../utilities/commitTransaction.js'\nimport { hasDraftsEnabled } from '../../utilities/getVersionsConfig.js'\nimport { initTransaction } from '../../utilities/initTransaction.js'\nimport { killTransaction } from '../../utilities/killTransaction.js'\nimport { getLatestCollectionVersion } from '../../versions/getLatestCollectionVersion.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\nexport const addOrderableFieldsAndHook = (\n collection: CollectionConfig,\n config: Config,\n orderableFieldNames: string[],\n joinFieldPathsByCollection?: Map<string, Map<string, string>>,\n): void => {\n // 1. Add fields\n for (const orderableFieldName of orderableFieldNames) {\n const orderField: TextField = {\n name: orderableFieldName,\n type: 'text',\n admin: {\n disabled: 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 // Sanitize the field using the standard sanitization logic\n sanitizeField({\n collectionConfig: collection,\n config,\n existingFieldNames: new Set(),\n field: orderField,\n index: 0,\n isTopLevelField: true,\n joinPath: '',\n parentIndexPath: '',\n parentIsLocalized: false,\n parentSchemaPath: '',\n requireFieldLevelRichTextEditor: false,\n validRelationships: null,\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 const draftsEnabled = hasDraftsEnabled(collection)\n\n // Update each document with its new order value\n for (const [index, id] of docsToMove.entries()) {\n let draft: boolean | undefined\n\n if (draftsEnabled) {\n const latestVersion = await getLatestCollectionVersion({\n id,\n config: collection,\n payload: req.payload,\n query: {\n collection: collection.slug,\n req,\n where: { id: { equals: id } },\n },\n req,\n })\n\n draft = latestVersion?._status === 'draft'\n }\n\n await req.payload.update({\n id,\n collection: collection.slug,\n data: {\n [orderableFieldName]: orderValues[index],\n },\n depth: 0,\n draft,\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","sanitizeField","combineWhereConstraints","commitTransaction","hasDraftsEnabled","initTransaction","killTransaction","getLatestCollectionVersion","generateKeyBetween","generateNKeysBetween","getJoinScopeContext","getJoinScopeWhereFromDocData","resolvePendingTargetKey","addOrderableFieldsAndHook","collection","config","orderableFieldNames","joinFieldPathsByCollection","orderableFieldName","orderField","name","type","admin","disabled","hidden","readOnly","hooks","beforeDuplicate","siblingData","index","collectionConfig","existingFieldNames","Set","field","isTopLevelField","joinPath","parentIndexPath","parentIsLocalized","parentSchemaPath","requireFieldLevelRichTextEditor","validRelationships","fields","unshift","beforeChange","orderBeforeChangeHook","data","originalDoc","req","joinScopeWhere","collectionSlug","slug","lastDoc","payload","find","depth","limit","pagination","select","sort","where","exists","undefined","lastOrderValue","docs","push","addOrderableEndpoint","reorderHandler","body","json","docsToMove","newKeyWillBe","target","Array","isArray","length","Response","JSON","stringify","error","headers","collections","c","targetDoc","access","update","id","key","doc","e","Error","message","INTERNAL_SERVER_ERROR","success","targetId","targetKey","targetID","adjacentDoc","adjacentDocKey","orderValues","draftsEnabled","entries","draft","latestVersion","query","equals","_status","reorderEndpoint","handler","method","path","endpoints"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Config, SanitizedConfig } from './types.js';
|
|
2
|
-
export declare const sanitizeConfig: (incomingConfig: Config) =>
|
|
2
|
+
export declare const sanitizeConfig: (incomingConfig: Config) => SanitizedConfig;
|
|
3
3
|
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,MAAM,EAIN,eAAe,EAIhB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,MAAM,EAIN,eAAe,EAIhB,MAAM,YAAY,CAAA;AAiOnB,eAAO,MAAM,cAAc,mBAAoB,MAAM,KAAG,eAuXvD,CAAA"}
|
package/dist/config/sanitize.js
CHANGED
|
@@ -13,7 +13,7 @@ import { getPreferencesCollection, preferencesCollectionSlug } from '../preferen
|
|
|
13
13
|
import { getQueryPresetsConfig, queryPresetsCollectionSlug } from '../query-presets/config.js';
|
|
14
14
|
import { getDefaultJobsCollection, jobsCollectionSlug } from '../queues/config/collection.js';
|
|
15
15
|
import { getJobStatsGlobal } from '../queues/config/global.js';
|
|
16
|
-
import { uploadInstructionsEndpoint } from '../uploads/endpoints/uploadInstructions.js';
|
|
16
|
+
import { stagedUploadEndpoints, uploadInstructionsEndpoint } from '../uploads/endpoints/uploadInstructions.js';
|
|
17
17
|
import { flattenAllFields, flattenBlock } from '../utilities/flattenAllFields.js';
|
|
18
18
|
import { hasScheduledPublishEnabled } from '../utilities/getVersionsConfig.js';
|
|
19
19
|
import { validateTimezones } from '../utilities/validateTimezones.js';
|
|
@@ -67,7 +67,7 @@ const sanitizeAdminConfig = (configToSanitize)=>{
|
|
|
67
67
|
});
|
|
68
68
|
return sanitizedConfig;
|
|
69
69
|
};
|
|
70
|
-
const addDefaultDashboardWidgets =
|
|
70
|
+
const addDefaultDashboardWidgets = ({ config, validRelationships })=>{
|
|
71
71
|
const collectionQueryFields = [
|
|
72
72
|
{
|
|
73
73
|
name: 'title',
|
|
@@ -168,12 +168,11 @@ const addDefaultDashboardWidgets = async ({ config, richTextSanitizationPromises
|
|
|
168
168
|
dashboard.widgets.push({
|
|
169
169
|
slug: 'collection-query',
|
|
170
170
|
Component: '@payloadcms/ui/rsc#CollectionQueryWidget',
|
|
171
|
-
fields:
|
|
171
|
+
fields: sanitizeFields({
|
|
172
172
|
config: config,
|
|
173
173
|
existingFieldNames: new Set(),
|
|
174
174
|
fields: collectionQueryFields,
|
|
175
175
|
parentIsLocalized: false,
|
|
176
|
-
richTextSanitizationPromises,
|
|
177
176
|
validRelationships
|
|
178
177
|
}),
|
|
179
178
|
minWidth: 'x-small'
|
|
@@ -181,12 +180,11 @@ const addDefaultDashboardWidgets = async ({ config, richTextSanitizationPromises
|
|
|
181
180
|
dashboard.widgets.push({
|
|
182
181
|
slug: 'activity',
|
|
183
182
|
Component: '@payloadcms/ui/rsc#RecentlyViewedWidget',
|
|
184
|
-
fields:
|
|
183
|
+
fields: sanitizeFields({
|
|
185
184
|
config: config,
|
|
186
185
|
existingFieldNames: new Set(),
|
|
187
186
|
fields: recentlyViewedFields,
|
|
188
187
|
parentIsLocalized: false,
|
|
189
|
-
richTextSanitizationPromises,
|
|
190
188
|
validRelationships
|
|
191
189
|
}),
|
|
192
190
|
label: ({ t })=>t('dashboard:widgetRecentlyViewedTitle'),
|
|
@@ -199,14 +197,18 @@ const addDefaultDashboardWidgets = async ({ config, richTextSanitizationPromises
|
|
|
199
197
|
}
|
|
200
198
|
];
|
|
201
199
|
};
|
|
202
|
-
export const sanitizeConfig =
|
|
200
|
+
export const sanitizeConfig = (incomingConfig)=>{
|
|
203
201
|
const configWithDefaults = addDefaultsToConfig(incomingConfig);
|
|
202
|
+
const { duration, safetyBuffer } = configWithDefaults.jobs.processingLease;
|
|
203
|
+
if (!(safetyBuffer >= 0 && safetyBuffer < duration)) {
|
|
204
|
+
throw new InvalidConfiguration('`jobs.processingLease.safetyBuffer` must be non-negative and less than `jobs.processingLease.duration`.');
|
|
205
|
+
}
|
|
204
206
|
const config = sanitizeAdminConfig(configWithDefaults);
|
|
205
207
|
if (!config.endpoints) {
|
|
206
208
|
config.endpoints = [];
|
|
207
209
|
}
|
|
208
|
-
if (configWithDefaults.collections?.some(({ upload })=>
|
|
209
|
-
config.endpoints.push(uploadInstructionsEndpoint);
|
|
210
|
+
if (configWithDefaults.collections?.some(({ upload })=>upload)) {
|
|
211
|
+
config.endpoints.push(uploadInstructionsEndpoint, ...stagedUploadEndpoints);
|
|
210
212
|
}
|
|
211
213
|
for (const endpoint of authRootEndpoints){
|
|
212
214
|
config.endpoints.push(endpoint);
|
|
@@ -251,7 +253,13 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
251
253
|
i18nConfig.translations = incomingConfig.i18n?.translations || i18nConfig.translations;
|
|
252
254
|
}
|
|
253
255
|
config.i18n = i18nConfig;
|
|
254
|
-
|
|
256
|
+
if (typeof incomingConfig.editor === 'function') {
|
|
257
|
+
config.editor = incomingConfig.editor({
|
|
258
|
+
config: config,
|
|
259
|
+
isRoot: true,
|
|
260
|
+
parentIsLocalized: false
|
|
261
|
+
});
|
|
262
|
+
}
|
|
255
263
|
const schedulePublishCollections = [];
|
|
256
264
|
const queryPresetsCollections = [];
|
|
257
265
|
const schedulePublishGlobals = [];
|
|
@@ -265,12 +273,11 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
265
273
|
const dashboardWidgets = config.admin?.dashboard?.widgets ?? [];
|
|
266
274
|
for (const widget of dashboardWidgets){
|
|
267
275
|
if (widget.fields?.length) {
|
|
268
|
-
widget.fields =
|
|
276
|
+
widget.fields = sanitizeFields({
|
|
269
277
|
config: config,
|
|
270
278
|
existingFieldNames: new Set(),
|
|
271
279
|
fields: widget.fields,
|
|
272
280
|
parentIsLocalized: false,
|
|
273
|
-
richTextSanitizationPromises,
|
|
274
281
|
validRelationships
|
|
275
282
|
});
|
|
276
283
|
}
|
|
@@ -288,12 +295,11 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
288
295
|
sanitizedBlock._sanitized = true;
|
|
289
296
|
sanitizedBlock.fields = sanitizedBlock.fields.concat(baseBlockFields);
|
|
290
297
|
sanitizedBlock.labels = !sanitizedBlock.labels ? formatLabels(sanitizedBlock.slug) : sanitizedBlock.labels;
|
|
291
|
-
sanitizedBlock.fields =
|
|
298
|
+
sanitizedBlock.fields = sanitizeFields({
|
|
292
299
|
config: config,
|
|
293
300
|
existingFieldNames: new Set(),
|
|
294
301
|
fields: sanitizedBlock.fields,
|
|
295
302
|
parentIsLocalized: false,
|
|
296
|
-
richTextSanitizationPromises,
|
|
297
303
|
validRelationships
|
|
298
304
|
});
|
|
299
305
|
const flattenedSanitizedBlock = flattenBlock({
|
|
@@ -319,7 +325,7 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
319
325
|
validRelationships.push(queryPresetsCollectionSlug);
|
|
320
326
|
}
|
|
321
327
|
}
|
|
322
|
-
config.collections[i] =
|
|
328
|
+
config.collections[i] = sanitizeCollection(config, config.collections[i], validRelationships, orderableJoins);
|
|
323
329
|
}
|
|
324
330
|
// Process orderable features after all collections are sanitized
|
|
325
331
|
const fieldsToAdd = new Map();
|
|
@@ -351,7 +357,7 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
351
357
|
}
|
|
352
358
|
// Add fields, hooks, and update flattenedFields
|
|
353
359
|
for (const [collection, orderableFields] of fieldsToAdd){
|
|
354
|
-
|
|
360
|
+
addOrderableFieldsAndHook(collection, config, orderableFields, joinFieldPathsByCollection);
|
|
355
361
|
// Regenerate flattenedFields since we added new fields
|
|
356
362
|
collection.flattenedFields = flattenAllFields({
|
|
357
363
|
fields: collection.fields
|
|
@@ -366,7 +372,7 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
366
372
|
if (hasScheduledPublishEnabled(config.globals[i])) {
|
|
367
373
|
schedulePublishGlobals.push(config.globals[i].slug);
|
|
368
374
|
}
|
|
369
|
-
config.globals[i] =
|
|
375
|
+
config.globals[i] = sanitizeGlobal(config, config.globals[i], validRelationships);
|
|
370
376
|
}
|
|
371
377
|
}
|
|
372
378
|
// Resolve hierarchy relationships across collections (also adds sidebar tabs)
|
|
@@ -381,30 +387,32 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
381
387
|
}
|
|
382
388
|
;
|
|
383
389
|
(config.jobs ??= {}).enabled = Boolean(Array.isArray(configWithDefaults.jobs?.tasks) && configWithDefaults.jobs?.tasks?.length || Array.isArray(configWithDefaults.jobs?.workflows) && configWithDefaults.jobs?.workflows?.length);
|
|
390
|
+
config.jobs.hasConcurrency = Boolean(config.jobs.tasks?.some((task)=>task.concurrency) || config.jobs.workflows?.some((workflow)=>workflow.concurrency));
|
|
384
391
|
// Need to add default jobs collection before locked documents collections
|
|
385
392
|
if (config.jobs.enabled) {
|
|
386
393
|
// Check for schedule property in both tasks and workflows
|
|
387
394
|
const hasScheduleProperty = config?.jobs?.tasks?.length && config.jobs.tasks.some((task)=>task.schedule) || config?.jobs?.workflows?.length && config.jobs.workflows.some((workflow)=>workflow.schedule);
|
|
388
395
|
if (hasScheduleProperty) {
|
|
389
396
|
config.jobs.scheduling = true;
|
|
390
|
-
(config.globals ??= []).push(await sanitizeGlobal(config, getJobStatsGlobal(config), richTextSanitizationPromises, validRelationships));
|
|
391
|
-
config.jobs.stats = true;
|
|
392
397
|
}
|
|
398
|
+
// Add payload-jobs-stats global for tracking job system metadata.
|
|
399
|
+
;
|
|
400
|
+
(config.globals ??= []).push(sanitizeGlobal(config, getJobStatsGlobal(), validRelationships));
|
|
393
401
|
let defaultJobsCollection = getDefaultJobsCollection(config.jobs);
|
|
394
402
|
if (typeof config.jobs.jobsCollectionOverrides === 'function') {
|
|
395
403
|
defaultJobsCollection = config.jobs.jobsCollectionOverrides({
|
|
396
404
|
defaultJobsCollection
|
|
397
405
|
});
|
|
398
406
|
}
|
|
399
|
-
const sanitizedJobsCollection =
|
|
407
|
+
const sanitizedJobsCollection = sanitizeCollection(config, defaultJobsCollection, validRelationships);
|
|
400
408
|
(config.collections ??= []).push(sanitizedJobsCollection);
|
|
401
409
|
}
|
|
402
410
|
const lockedDocumentsCollection = getLockedDocumentsCollection(config);
|
|
403
411
|
if (lockedDocumentsCollection) {
|
|
404
|
-
configWithDefaults.collections.push(
|
|
412
|
+
configWithDefaults.collections.push(sanitizeCollection(config, lockedDocumentsCollection, validRelationships));
|
|
405
413
|
}
|
|
406
|
-
configWithDefaults.collections.push(
|
|
407
|
-
const migrations =
|
|
414
|
+
configWithDefaults.collections.push(sanitizeCollection(config, getPreferencesCollection(config), validRelationships));
|
|
415
|
+
const migrations = sanitizeCollection(config, migrationsCollection, validRelationships);
|
|
408
416
|
// @ts-expect-error indexSortableFields is only valid for @payloadcms/db-mongodb
|
|
409
417
|
if (config?.db?.indexSortableFields) {
|
|
410
418
|
migrations.indexes = [
|
|
@@ -419,11 +427,10 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
419
427
|
}
|
|
420
428
|
configWithDefaults.collections.push(migrations);
|
|
421
429
|
if (queryPresetsCollections.length > 0) {
|
|
422
|
-
configWithDefaults.collections.push(
|
|
430
|
+
configWithDefaults.collections.push(sanitizeCollection(config, getQueryPresetsConfig(config), validRelationships));
|
|
423
431
|
}
|
|
424
|
-
|
|
432
|
+
addDefaultDashboardWidgets({
|
|
425
433
|
config,
|
|
426
|
-
richTextSanitizationPromises,
|
|
427
434
|
validRelationships
|
|
428
435
|
});
|
|
429
436
|
if (config.serverURL !== '') {
|
|
@@ -442,20 +449,6 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
442
449
|
if (incomingConfig.email) {
|
|
443
450
|
config.email = incomingConfig.email;
|
|
444
451
|
}
|
|
445
|
-
/*
|
|
446
|
-
Execute richText sanitization
|
|
447
|
-
*/ if (typeof incomingConfig.editor === 'function') {
|
|
448
|
-
config.editor = await incomingConfig.editor({
|
|
449
|
-
config: config,
|
|
450
|
-
isRoot: true,
|
|
451
|
-
parentIsLocalized: false
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
const promises = [];
|
|
455
|
-
for (const sanitizeFunction of richTextSanitizationPromises){
|
|
456
|
-
promises.push(sanitizeFunction(config));
|
|
457
|
-
}
|
|
458
|
-
await Promise.all(promises);
|
|
459
452
|
return config;
|
|
460
453
|
};
|
|
461
454
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/sanitize.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\n\nimport { en } from '@payloadcms/translations/languages/en'\n\nimport type { OrderableJoinInfo } from '../fields/config/sanitizeJoinField.js'\nimport type { CollectionSlug, GlobalSlug, SanitizedCollectionConfig } from '../index.js'\nimport type { SanitizedJobsConfig } from '../queues/config/types/index.js'\nimport type {\n Config,\n DashboardConfig,\n LocalizationConfigWithLabels,\n LocalizationConfigWithNoLabels,\n SanitizedConfig,\n Timezone,\n Widget,\n WidgetInstance,\n} from './types.js'\n\nimport { defaultUserCollection } from '../auth/defaultUser.js'\nimport { authRootEndpoints } from '../auth/endpoints/index.js'\nimport { sanitizeCollection } from '../collections/config/sanitize.js'\nimport { migrationsCollection } from '../database/migrations/migrationsCollection.js'\nimport { DuplicateCollection, InvalidConfiguration } from '../errors/index.js'\nimport { defaultTimezones } from '../fields/baseFields/timezone/defaultTimezones.js'\nimport { sanitizeGlobal } from '../globals/config/sanitize.js'\nimport { resolveHierarchyCollections } from '../hierarchy/resolveHierarchyCollections.js'\nimport { baseBlockFields, formatLabels, sanitizeFields } from '../index.js'\nimport {\n getLockedDocumentsCollection,\n lockedDocumentsCollectionSlug,\n} from '../locked-documents/config.js'\nimport { getPreferencesCollection, preferencesCollectionSlug } from '../preferences/config.js'\nimport { getQueryPresetsConfig, queryPresetsCollectionSlug } from '../query-presets/config.js'\nimport { getDefaultJobsCollection, jobsCollectionSlug } from '../queues/config/collection.js'\nimport { getJobStatsGlobal } from '../queues/config/global.js'\nimport { uploadInstructionsEndpoint } from '../uploads/endpoints/uploadInstructions.js'\nimport { flattenAllFields, flattenBlock } from '../utilities/flattenAllFields.js'\nimport { hasScheduledPublishEnabled } from '../utilities/getVersionsConfig.js'\nimport { validateTimezones } from '../utilities/validateTimezones.js'\nimport { getSchedulePublishTask } from '../versions/schedule/job.js'\nimport { addDefaultsToConfig } from './defaults.js'\nimport { addOrderableEndpoint, addOrderableFieldsAndHook } from './orderable/index.js'\n\nconst sanitizeAdminConfig = (configToSanitize: Config): Partial<SanitizedConfig> => {\n const sanitizedConfig = { ...configToSanitize }\n\n // default logging level will be 'error' if not provided\n sanitizedConfig.loggingLevels = {\n Forbidden: 'info',\n Locked: 'info',\n MissingFile: 'info',\n NotFound: 'info',\n ValidationError: 'info',\n ...(sanitizedConfig.loggingLevels || {}),\n }\n // add default user collection if none provided\n if (!sanitizedConfig?.admin?.user) {\n const firstCollectionWithAuth = sanitizedConfig.collections!.find(({ auth }) => Boolean(auth))\n\n if (firstCollectionWithAuth) {\n sanitizedConfig.admin!.user = firstCollectionWithAuth.slug\n } else {\n sanitizedConfig.admin!.user = defaultUserCollection.slug\n sanitizedConfig.collections!.push(defaultUserCollection)\n }\n }\n\n const userCollection = sanitizedConfig.collections!.find(\n ({ slug }) => slug === sanitizedConfig.admin!.user,\n )\n\n if (!userCollection || !userCollection.auth) {\n throw new InvalidConfiguration(\n `${sanitizedConfig.admin!.user} is not a valid admin user collection`,\n )\n }\n\n if (sanitizedConfig?.admin?.timezones) {\n if (typeof configToSanitize?.admin?.timezones?.supportedTimezones === 'function') {\n sanitizedConfig.admin.timezones.supportedTimezones =\n configToSanitize.admin.timezones.supportedTimezones({ defaultTimezones })\n }\n\n if (!sanitizedConfig?.admin?.timezones?.supportedTimezones) {\n sanitizedConfig.admin.timezones.supportedTimezones = defaultTimezones\n }\n } else {\n sanitizedConfig.admin!.timezones = {\n supportedTimezones: defaultTimezones,\n }\n }\n\n validateTimezones({\n source: 'admin.timezones.supportedTimezones',\n timezones: sanitizedConfig.admin!.timezones.supportedTimezones as Timezone[],\n })\n\n return sanitizedConfig as unknown as Partial<SanitizedConfig>\n}\n\nconst addDefaultDashboardWidgets = async ({\n config,\n richTextSanitizationPromises,\n validRelationships,\n}: {\n config: Partial<SanitizedConfig>\n richTextSanitizationPromises: Array<(config: SanitizedConfig) => Promise<void>>\n validRelationships: string[]\n}) => {\n const collectionQueryFields: NonNullable<Widget['fields']> = [\n {\n name: 'title',\n type: 'text',\n label: ({ t }) => t('dashboard:widgetTitleLabel'),\n },\n {\n name: 'relatedCollection',\n type: 'select',\n label: ({ t }) => t('general:collection'),\n // Only offer collections that are visible in the admin UI. Collections hidden via a function\n // are kept since they may still be visible for some users.\n options: (config.collections ?? [])\n .filter((collection) => collection.admin?.hidden !== true)\n .map((collection) => ({\n label: collection.labels?.plural || collection.slug,\n value: collection.slug,\n })),\n required: true,\n },\n {\n name: 'where',\n type: 'json',\n admin: {\n components: {\n Field: '@payloadcms/ui#QueryPresetsWhereField',\n },\n },\n label: ({ t }) => t('general:filters'),\n },\n {\n name: 'sortField',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/ui#CollectionQuerySortField',\n },\n },\n label: ({ t }) => t('dashboard:widgetSortFieldLabel'),\n },\n {\n name: 'sortDirection',\n type: 'select',\n defaultValue: 'desc',\n label: ({ t }) => t('dashboard:widgetSortDirectionLabel'),\n options: [\n {\n label: ({ t }) => t('general:ascending'),\n value: 'asc',\n },\n {\n label: ({ t }) => t('general:descending'),\n value: 'desc',\n },\n ],\n },\n {\n name: 'limit',\n type: 'number',\n defaultValue: 5,\n label: ({ t }) => t('dashboard:widgetLimitLabel'),\n max: 25,\n min: 1,\n },\n ]\n\n const recentlyViewedFields: NonNullable<Widget['fields']> = [\n {\n name: 'excludedCollections',\n type: 'select',\n admin: {\n components: {\n // Presents an inclusion filter (all collections checked by default) while persisting the\n // inverse as an exclusion list, so collections added later stay visible by default.\n Field: '@payloadcms/ui#RecentlyViewedCollectionsField',\n },\n },\n hasMany: true,\n label: ({ t }) => t('general:collections'),\n // Exclusion list, so an empty value shows every collection and newly added collections are\n // included by default. Hidden collections are never offered as options.\n options: (config.collections ?? [])\n .filter((collection) => collection.admin?.hidden !== true)\n .map((collection) => ({\n label: collection.labels?.plural || collection.slug,\n value: collection.slug,\n })),\n },\n ]\n\n const adminConfig: NonNullable<Config['admin']> = config.admin ?? { dashboard: { widgets: [] } }\n const dashboard: DashboardConfig = (adminConfig.dashboard ??= { widgets: [] })\n\n dashboard.widgets.push({\n slug: 'collections',\n Component: '@payloadcms/ui/rsc#CollectionCards',\n minWidth: 'full',\n })\n dashboard.widgets.push({\n slug: 'collection-query',\n Component: '@payloadcms/ui/rsc#CollectionQueryWidget',\n fields: await sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: collectionQueryFields,\n parentIsLocalized: false,\n richTextSanitizationPromises,\n validRelationships,\n }),\n minWidth: 'x-small',\n })\n dashboard.widgets.push({\n slug: 'activity',\n Component: '@payloadcms/ui/rsc#RecentlyViewedWidget',\n fields: await sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: recentlyViewedFields,\n parentIsLocalized: false,\n richTextSanitizationPromises,\n validRelationships,\n }),\n label: ({ t }) => t('dashboard:widgetRecentlyViewedTitle'),\n minWidth: 'x-small',\n })\n dashboard.defaultLayout ??= [\n {\n widgetSlug: 'collections',\n width: 'full',\n } satisfies WidgetInstance,\n ]\n}\n\nexport const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedConfig> => {\n const configWithDefaults = addDefaultsToConfig(incomingConfig)\n\n const config: Partial<SanitizedConfig> = sanitizeAdminConfig(configWithDefaults)\n\n if (!config.endpoints) {\n config.endpoints = []\n }\n\n if (\n configWithDefaults.collections?.some(\n ({ upload }) => typeof upload === 'object' && upload.uploadInstructions,\n )\n ) {\n config.endpoints.push(uploadInstructionsEndpoint)\n }\n\n for (const endpoint of authRootEndpoints) {\n config.endpoints.push(endpoint)\n }\n\n if (config.localization && config.localization.locales?.length > 0) {\n // clone localization config so to not break everything\n const firstLocale = config.localization.locales[0]\n if (typeof firstLocale === 'string') {\n config.localization.localeCodes = [\n ...(config.localization as unknown as LocalizationConfigWithNoLabels).locales,\n ]\n\n // is string[], so convert to Locale[]\n config.localization.locales = (\n config.localization as unknown as LocalizationConfigWithNoLabels\n ).locales.map((locale) => ({\n code: locale,\n label: locale,\n rtl: false,\n toString: () => locale,\n }))\n } else {\n // is Locale[], so convert to string[] for localeCodes\n config.localization.localeCodes = config.localization.locales.map((locale) => locale.code)\n\n config.localization.locales = (\n config.localization as LocalizationConfigWithLabels\n ).locales.map((locale) => ({\n ...locale,\n toString: () => locale.code,\n }))\n }\n\n // Default fallback to true if not provided\n config.localization.fallback = config.localization?.fallback ?? true\n }\n\n const i18nConfig: SanitizedConfig['i18n'] = {\n fallbackLanguage: 'en',\n supportedLanguages: {\n en,\n },\n translations: {},\n }\n\n if (incomingConfig?.i18n) {\n i18nConfig.supportedLanguages =\n incomingConfig.i18n?.supportedLanguages || i18nConfig.supportedLanguages\n\n const supportedLangKeys = <AcceptedLanguages[]>Object.keys(i18nConfig.supportedLanguages)\n const fallbackLang = incomingConfig.i18n?.fallbackLanguage || i18nConfig.fallbackLanguage\n\n i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang)\n ? fallbackLang\n : supportedLangKeys[0]!\n i18nConfig.translations =\n (incomingConfig.i18n?.translations as SanitizedConfig['i18n']['translations']) ||\n i18nConfig.translations\n }\n\n config.i18n = i18nConfig\n\n const richTextSanitizationPromises: Array<(config: SanitizedConfig) => Promise<void>> = []\n\n const schedulePublishCollections: CollectionSlug[] = []\n\n const queryPresetsCollections: CollectionSlug[] = []\n\n const schedulePublishGlobals: GlobalSlug[] = []\n\n const collectionSlugs = new Set<CollectionSlug>()\n\n const validRelationships = [\n ...(config.collections?.map((c) => c.slug) ?? []),\n jobsCollectionSlug,\n lockedDocumentsCollectionSlug,\n preferencesCollectionSlug,\n ]\n\n const dashboardWidgets = config.admin?.dashboard?.widgets ?? ([] as Widget[])\n\n for (const widget of dashboardWidgets) {\n if (widget.fields?.length) {\n widget.fields = await sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: widget.fields,\n parentIsLocalized: false,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n }\n\n /**\n * Blocks sanitization needs to happen before collections, as collection/global join field sanitization needs config.blocks\n * to be populated with the sanitized blocks\n */\n config.blocks = []\n\n if (incomingConfig.blocks?.length) {\n for (const block of incomingConfig.blocks) {\n const sanitizedBlock = block\n\n if (sanitizedBlock._sanitized === true) {\n continue\n }\n sanitizedBlock._sanitized = true\n\n sanitizedBlock.fields = sanitizedBlock.fields.concat(baseBlockFields)\n\n sanitizedBlock.labels = !sanitizedBlock.labels\n ? formatLabels(sanitizedBlock.slug)\n : sanitizedBlock.labels\n\n sanitizedBlock.fields = await sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: sanitizedBlock.fields,\n parentIsLocalized: false,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n const flattenedSanitizedBlock = flattenBlock({ block })\n\n config.blocks.push(flattenedSanitizedBlock)\n }\n }\n\n // Track orderable join fields during sanitization\n const orderableJoins: OrderableJoinInfo[] = []\n\n for (let i = 0; i < config.collections!.length; i++) {\n if (collectionSlugs.has(config.collections![i]!.slug)) {\n throw new DuplicateCollection('slug', config.collections![i]!.slug)\n }\n\n collectionSlugs.add(config.collections![i]!.slug)\n\n const draftsConfig = config.collections![i]?.versions?.drafts\n\n if (typeof draftsConfig === 'object' && draftsConfig.schedulePublish) {\n schedulePublishCollections.push(config.collections![i]!.slug)\n }\n\n if (config.collections![i]!.enableQueryPresets) {\n queryPresetsCollections.push(config.collections![i]!.slug)\n\n if (!validRelationships.includes(queryPresetsCollectionSlug)) {\n validRelationships.push(queryPresetsCollectionSlug)\n }\n }\n\n config.collections![i] = await sanitizeCollection(\n config as unknown as Config,\n config.collections![i]!,\n richTextSanitizationPromises,\n validRelationships,\n orderableJoins,\n )\n }\n\n // Process orderable features after all collections are sanitized\n const fieldsToAdd = new Map<SanitizedCollectionConfig, string[]>()\n const joinFieldPathsByCollection = new Map<string, Map<string, string>>()\n\n // Handle collection.orderable\n for (const collection of config.collections!) {\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\n // Handle orderable join fields (tracked during sanitization)\n for (const joinInfo of orderableJoins) {\n const targetCollection = config.collections!.find(\n (c) => c.slug === joinInfo.targetCollectionSlug,\n )\n if (targetCollection) {\n const currentFields = fieldsToAdd.get(targetCollection) || []\n fieldsToAdd.set(targetCollection, [...currentFields, joinInfo.orderFieldName])\n\n const currentJoinFieldPaths =\n joinFieldPathsByCollection.get(targetCollection.slug) || new Map<string, string>()\n currentJoinFieldPaths.set(joinInfo.orderFieldName, joinInfo.joinFieldOn)\n joinFieldPathsByCollection.set(targetCollection.slug, currentJoinFieldPaths)\n }\n }\n\n // Add fields, hooks, and update flattenedFields\n for (const [collection, orderableFields] of fieldsToAdd) {\n await addOrderableFieldsAndHook(\n collection,\n config as unknown as Config,\n orderableFields,\n joinFieldPathsByCollection,\n )\n // Regenerate flattenedFields since we added new fields\n collection.flattenedFields = flattenAllFields({ fields: collection.fields })\n }\n\n // Add endpoint if any orderable features exist\n if (fieldsToAdd.size > 0) {\n addOrderableEndpoint(config as SanitizedConfig, joinFieldPathsByCollection)\n }\n\n if (config.globals!.length > 0) {\n for (let i = 0; i < config.globals!.length; i++) {\n if (hasScheduledPublishEnabled(config.globals![i]!)) {\n schedulePublishGlobals.push(config.globals![i]!.slug)\n }\n\n config.globals![i] = await sanitizeGlobal(\n config as unknown as Config,\n config.globals![i]!,\n richTextSanitizationPromises,\n validRelationships,\n )\n }\n }\n\n // Resolve hierarchy relationships across collections (also adds sidebar tabs)\n resolveHierarchyCollections(config as unknown as Config)\n\n if (schedulePublishCollections.length || schedulePublishGlobals.length) {\n ;((config.jobs ??= {} as SanitizedJobsConfig).tasks ??= []).push(\n getSchedulePublishTask({\n adminUserSlug: config.admin!.user,\n collections: schedulePublishCollections,\n globals: schedulePublishGlobals,\n }),\n )\n }\n\n ;(config.jobs ??= {} as SanitizedJobsConfig).enabled = Boolean(\n (Array.isArray(configWithDefaults.jobs?.tasks) && configWithDefaults.jobs?.tasks?.length) ||\n (Array.isArray(configWithDefaults.jobs?.workflows) &&\n configWithDefaults.jobs?.workflows?.length),\n )\n\n // Need to add default jobs collection before locked documents collections\n if (config.jobs.enabled) {\n // Check for schedule property in both tasks and workflows\n const hasScheduleProperty =\n (config?.jobs?.tasks?.length && config.jobs.tasks.some((task) => task.schedule)) ||\n (config?.jobs?.workflows?.length &&\n config.jobs.workflows.some((workflow) => workflow.schedule))\n\n if (hasScheduleProperty) {\n config.jobs.scheduling = true\n // Add payload-jobs-stats global for tracking when a job of a specific slug was last run\n ;(config.globals ??= []).push(\n await sanitizeGlobal(\n config as unknown as Config,\n getJobStatsGlobal(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n config.jobs.stats = true\n }\n\n let defaultJobsCollection = getDefaultJobsCollection(config.jobs)\n\n if (typeof config.jobs.jobsCollectionOverrides === 'function') {\n defaultJobsCollection = config.jobs.jobsCollectionOverrides({\n defaultJobsCollection,\n })\n }\n const sanitizedJobsCollection = await sanitizeCollection(\n config as unknown as Config,\n defaultJobsCollection,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n ;(config.collections ??= []).push(sanitizedJobsCollection)\n }\n\n const lockedDocumentsCollection = getLockedDocumentsCollection(config as unknown as Config)\n\n if (lockedDocumentsCollection) {\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n lockedDocumentsCollection,\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n }\n\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getPreferencesCollection(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n const migrations = await sanitizeCollection(\n config as unknown as Config,\n migrationsCollection,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n // @ts-expect-error indexSortableFields is only valid for @payloadcms/db-mongodb\n if (config?.db?.indexSortableFields) {\n migrations.indexes = [\n {\n fields: ['batch', 'name'],\n unique: false,\n },\n ]\n }\n configWithDefaults.collections!.push(migrations)\n\n if (queryPresetsCollections.length > 0) {\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getQueryPresetsConfig(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n }\n\n await addDefaultDashboardWidgets({\n config,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n if (config.serverURL !== '') {\n config.csrf!.push(config.serverURL!)\n }\n\n if (!config.storage) {\n config.storage = []\n }\n\n if (!config.upload) {\n config.upload = { adapters: [] }\n }\n\n config.upload.adapters = Array.from(\n new Set(config.collections!.map((c) => c.upload?.adapter).filter(Boolean) as string[]),\n )\n\n // Pass through the email config as is so adapters don't break\n if (incomingConfig.email) {\n config.email = incomingConfig.email\n }\n\n /*\n Execute richText sanitization\n */\n if (typeof incomingConfig.editor === 'function') {\n config.editor = await incomingConfig.editor({\n config: config as SanitizedConfig,\n isRoot: true,\n parentIsLocalized: false,\n })\n }\n\n const promises: Promise<void>[] = []\n\n for (const sanitizeFunction of richTextSanitizationPromises) {\n promises.push(sanitizeFunction(config as SanitizedConfig))\n }\n\n await Promise.all(promises)\n\n return config as SanitizedConfig\n}\n"],"names":["en","defaultUserCollection","authRootEndpoints","sanitizeCollection","migrationsCollection","DuplicateCollection","InvalidConfiguration","defaultTimezones","sanitizeGlobal","resolveHierarchyCollections","baseBlockFields","formatLabels","sanitizeFields","getLockedDocumentsCollection","lockedDocumentsCollectionSlug","getPreferencesCollection","preferencesCollectionSlug","getQueryPresetsConfig","queryPresetsCollectionSlug","getDefaultJobsCollection","jobsCollectionSlug","getJobStatsGlobal","uploadInstructionsEndpoint","flattenAllFields","flattenBlock","hasScheduledPublishEnabled","validateTimezones","getSchedulePublishTask","addDefaultsToConfig","addOrderableEndpoint","addOrderableFieldsAndHook","sanitizeAdminConfig","configToSanitize","sanitizedConfig","loggingLevels","Forbidden","Locked","MissingFile","NotFound","ValidationError","admin","user","firstCollectionWithAuth","collections","find","auth","Boolean","slug","push","userCollection","timezones","supportedTimezones","source","addDefaultDashboardWidgets","config","richTextSanitizationPromises","validRelationships","collectionQueryFields","name","type","label","t","options","filter","collection","hidden","map","labels","plural","value","required","components","Field","defaultValue","max","min","recentlyViewedFields","hasMany","adminConfig","dashboard","widgets","Component","minWidth","fields","existingFieldNames","Set","parentIsLocalized","defaultLayout","widgetSlug","width","sanitizeConfig","incomingConfig","configWithDefaults","endpoints","some","upload","uploadInstructions","endpoint","localization","locales","length","firstLocale","localeCodes","locale","code","rtl","toString","fallback","i18nConfig","fallbackLanguage","supportedLanguages","translations","i18n","supportedLangKeys","Object","keys","fallbackLang","includes","schedulePublishCollections","queryPresetsCollections","schedulePublishGlobals","collectionSlugs","c","dashboardWidgets","widget","blocks","block","sanitizedBlock","_sanitized","concat","flattenedSanitizedBlock","orderableJoins","i","has","add","draftsConfig","versions","drafts","schedulePublish","enableQueryPresets","fieldsToAdd","Map","joinFieldPathsByCollection","orderable","currentFields","get","set","defaultSort","joinInfo","targetCollection","targetCollectionSlug","orderFieldName","currentJoinFieldPaths","joinFieldOn","orderableFields","flattenedFields","size","globals","jobs","tasks","adminUserSlug","enabled","Array","isArray","workflows","hasScheduleProperty","task","schedule","workflow","scheduling","stats","defaultJobsCollection","jobsCollectionOverrides","sanitizedJobsCollection","lockedDocumentsCollection","migrations","db","indexSortableFields","indexes","unique","serverURL","csrf","storage","adapters","from","adapter","email","editor","isRoot","promises","sanitizeFunction","Promise","all"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/config/sanitize.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\n\nimport { en } from '@payloadcms/translations/languages/en'\n\nimport type { OrderableJoinInfo } from '../fields/config/sanitizeJoinField.js'\nimport type { CollectionSlug, GlobalSlug, SanitizedCollectionConfig } from '../index.js'\nimport type { SanitizedJobsConfig } from '../queues/config/types/index.js'\nimport type {\n Config,\n DashboardConfig,\n LocalizationConfigWithLabels,\n LocalizationConfigWithNoLabels,\n SanitizedConfig,\n Timezone,\n Widget,\n WidgetInstance,\n} from './types.js'\n\nimport { defaultUserCollection } from '../auth/defaultUser.js'\nimport { authRootEndpoints } from '../auth/endpoints/index.js'\nimport { sanitizeCollection } from '../collections/config/sanitize.js'\nimport { migrationsCollection } from '../database/migrations/migrationsCollection.js'\nimport { DuplicateCollection, InvalidConfiguration } from '../errors/index.js'\nimport { defaultTimezones } from '../fields/baseFields/timezone/defaultTimezones.js'\nimport { sanitizeGlobal } from '../globals/config/sanitize.js'\nimport { resolveHierarchyCollections } from '../hierarchy/resolveHierarchyCollections.js'\nimport { baseBlockFields, formatLabels, sanitizeFields } from '../index.js'\nimport {\n getLockedDocumentsCollection,\n lockedDocumentsCollectionSlug,\n} from '../locked-documents/config.js'\nimport { getPreferencesCollection, preferencesCollectionSlug } from '../preferences/config.js'\nimport { getQueryPresetsConfig, queryPresetsCollectionSlug } from '../query-presets/config.js'\nimport { getDefaultJobsCollection, jobsCollectionSlug } from '../queues/config/collection.js'\nimport { getJobStatsGlobal } from '../queues/config/global.js'\nimport {\n stagedUploadEndpoints,\n uploadInstructionsEndpoint,\n} from '../uploads/endpoints/uploadInstructions.js'\nimport { flattenAllFields, flattenBlock } from '../utilities/flattenAllFields.js'\nimport { hasScheduledPublishEnabled } from '../utilities/getVersionsConfig.js'\nimport { validateTimezones } from '../utilities/validateTimezones.js'\nimport { getSchedulePublishTask } from '../versions/schedule/job.js'\nimport { addDefaultsToConfig } from './defaults.js'\nimport { addOrderableEndpoint, addOrderableFieldsAndHook } from './orderable/index.js'\n\nconst sanitizeAdminConfig = (configToSanitize: Config): Partial<SanitizedConfig> => {\n const sanitizedConfig = { ...configToSanitize }\n\n // default logging level will be 'error' if not provided\n sanitizedConfig.loggingLevels = {\n Forbidden: 'info',\n Locked: 'info',\n MissingFile: 'info',\n NotFound: 'info',\n ValidationError: 'info',\n ...(sanitizedConfig.loggingLevels || {}),\n }\n // add default user collection if none provided\n if (!sanitizedConfig?.admin?.user) {\n const firstCollectionWithAuth = sanitizedConfig.collections!.find(({ auth }) => Boolean(auth))\n\n if (firstCollectionWithAuth) {\n sanitizedConfig.admin!.user = firstCollectionWithAuth.slug\n } else {\n sanitizedConfig.admin!.user = defaultUserCollection.slug\n sanitizedConfig.collections!.push(defaultUserCollection)\n }\n }\n\n const userCollection = sanitizedConfig.collections!.find(\n ({ slug }) => slug === sanitizedConfig.admin!.user,\n )\n\n if (!userCollection || !userCollection.auth) {\n throw new InvalidConfiguration(\n `${sanitizedConfig.admin!.user} is not a valid admin user collection`,\n )\n }\n\n if (sanitizedConfig?.admin?.timezones) {\n if (typeof configToSanitize?.admin?.timezones?.supportedTimezones === 'function') {\n sanitizedConfig.admin.timezones.supportedTimezones =\n configToSanitize.admin.timezones.supportedTimezones({ defaultTimezones })\n }\n\n if (!sanitizedConfig?.admin?.timezones?.supportedTimezones) {\n sanitizedConfig.admin.timezones.supportedTimezones = defaultTimezones\n }\n } else {\n sanitizedConfig.admin!.timezones = {\n supportedTimezones: defaultTimezones,\n }\n }\n\n validateTimezones({\n source: 'admin.timezones.supportedTimezones',\n timezones: sanitizedConfig.admin!.timezones.supportedTimezones as Timezone[],\n })\n\n return sanitizedConfig as unknown as Partial<SanitizedConfig>\n}\n\nconst addDefaultDashboardWidgets = ({\n config,\n validRelationships,\n}: {\n config: Partial<SanitizedConfig>\n validRelationships: string[]\n}): void => {\n const collectionQueryFields: NonNullable<Widget['fields']> = [\n {\n name: 'title',\n type: 'text',\n label: ({ t }) => t('dashboard:widgetTitleLabel'),\n },\n {\n name: 'relatedCollection',\n type: 'select',\n label: ({ t }) => t('general:collection'),\n // Only offer collections that are visible in the admin UI. Collections hidden via a function\n // are kept since they may still be visible for some users.\n options: (config.collections ?? [])\n .filter((collection) => collection.admin?.hidden !== true)\n .map((collection) => ({\n label: collection.labels?.plural || collection.slug,\n value: collection.slug,\n })),\n required: true,\n },\n {\n name: 'where',\n type: 'json',\n admin: {\n components: {\n Field: '@payloadcms/ui#QueryPresetsWhereField',\n },\n },\n label: ({ t }) => t('general:filters'),\n },\n {\n name: 'sortField',\n type: 'text',\n admin: {\n components: {\n Field: '@payloadcms/ui#CollectionQuerySortField',\n },\n },\n label: ({ t }) => t('dashboard:widgetSortFieldLabel'),\n },\n {\n name: 'sortDirection',\n type: 'select',\n defaultValue: 'desc',\n label: ({ t }) => t('dashboard:widgetSortDirectionLabel'),\n options: [\n {\n label: ({ t }) => t('general:ascending'),\n value: 'asc',\n },\n {\n label: ({ t }) => t('general:descending'),\n value: 'desc',\n },\n ],\n },\n {\n name: 'limit',\n type: 'number',\n defaultValue: 5,\n label: ({ t }) => t('dashboard:widgetLimitLabel'),\n max: 25,\n min: 1,\n },\n ]\n\n const recentlyViewedFields: NonNullable<Widget['fields']> = [\n {\n name: 'excludedCollections',\n type: 'select',\n admin: {\n components: {\n // Presents an inclusion filter (all collections checked by default) while persisting the\n // inverse as an exclusion list, so collections added later stay visible by default.\n Field: '@payloadcms/ui#RecentlyViewedCollectionsField',\n },\n },\n hasMany: true,\n label: ({ t }) => t('general:collections'),\n // Exclusion list, so an empty value shows every collection and newly added collections are\n // included by default. Hidden collections are never offered as options.\n options: (config.collections ?? [])\n .filter((collection) => collection.admin?.hidden !== true)\n .map((collection) => ({\n label: collection.labels?.plural || collection.slug,\n value: collection.slug,\n })),\n },\n ]\n\n const adminConfig: NonNullable<Config['admin']> = config.admin ?? { dashboard: { widgets: [] } }\n const dashboard: DashboardConfig = (adminConfig.dashboard ??= { widgets: [] })\n\n dashboard.widgets.push({\n slug: 'collections',\n Component: '@payloadcms/ui/rsc#CollectionCards',\n minWidth: 'full',\n })\n dashboard.widgets.push({\n slug: 'collection-query',\n Component: '@payloadcms/ui/rsc#CollectionQueryWidget',\n fields: sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: collectionQueryFields,\n parentIsLocalized: false,\n validRelationships,\n }),\n minWidth: 'x-small',\n })\n dashboard.widgets.push({\n slug: 'activity',\n Component: '@payloadcms/ui/rsc#RecentlyViewedWidget',\n fields: sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: recentlyViewedFields,\n parentIsLocalized: false,\n validRelationships,\n }),\n label: ({ t }) => t('dashboard:widgetRecentlyViewedTitle'),\n minWidth: 'x-small',\n })\n dashboard.defaultLayout ??= [\n {\n widgetSlug: 'collections',\n width: 'full',\n } satisfies WidgetInstance,\n ]\n}\n\nexport const sanitizeConfig = (incomingConfig: Config): SanitizedConfig => {\n const configWithDefaults = addDefaultsToConfig(incomingConfig)\n const { duration, safetyBuffer } = configWithDefaults.jobs!.processingLease!\n if (!(safetyBuffer! >= 0 && safetyBuffer! < duration!)) {\n throw new InvalidConfiguration(\n '`jobs.processingLease.safetyBuffer` must be non-negative and less than `jobs.processingLease.duration`.',\n )\n }\n\n const config: Partial<SanitizedConfig> = sanitizeAdminConfig(configWithDefaults)\n\n if (!config.endpoints) {\n config.endpoints = []\n }\n\n if (configWithDefaults.collections?.some(({ upload }) => upload)) {\n config.endpoints.push(uploadInstructionsEndpoint, ...stagedUploadEndpoints)\n }\n\n for (const endpoint of authRootEndpoints) {\n config.endpoints.push(endpoint)\n }\n\n if (config.localization && config.localization.locales?.length > 0) {\n // clone localization config so to not break everything\n const firstLocale = config.localization.locales[0]\n if (typeof firstLocale === 'string') {\n config.localization.localeCodes = [\n ...(config.localization as unknown as LocalizationConfigWithNoLabels).locales,\n ]\n\n // is string[], so convert to Locale[]\n config.localization.locales = (\n config.localization as unknown as LocalizationConfigWithNoLabels\n ).locales.map((locale) => ({\n code: locale,\n label: locale,\n rtl: false,\n toString: () => locale,\n }))\n } else {\n // is Locale[], so convert to string[] for localeCodes\n config.localization.localeCodes = config.localization.locales.map((locale) => locale.code)\n\n config.localization.locales = (\n config.localization as LocalizationConfigWithLabels\n ).locales.map((locale) => ({\n ...locale,\n toString: () => locale.code,\n }))\n }\n\n // Default fallback to true if not provided\n config.localization.fallback = config.localization?.fallback ?? true\n }\n\n const i18nConfig: SanitizedConfig['i18n'] = {\n fallbackLanguage: 'en',\n supportedLanguages: {\n en,\n },\n translations: {},\n }\n\n if (incomingConfig?.i18n) {\n i18nConfig.supportedLanguages =\n incomingConfig.i18n?.supportedLanguages || i18nConfig.supportedLanguages\n\n const supportedLangKeys = <AcceptedLanguages[]>Object.keys(i18nConfig.supportedLanguages)\n const fallbackLang = incomingConfig.i18n?.fallbackLanguage || i18nConfig.fallbackLanguage\n\n i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang)\n ? fallbackLang\n : supportedLangKeys[0]!\n i18nConfig.translations =\n (incomingConfig.i18n?.translations as SanitizedConfig['i18n']['translations']) ||\n i18nConfig.translations\n }\n\n config.i18n = i18nConfig\n\n if (typeof incomingConfig.editor === 'function') {\n config.editor = incomingConfig.editor({\n config: config as SanitizedConfig,\n isRoot: true,\n parentIsLocalized: false,\n })\n }\n\n const schedulePublishCollections: CollectionSlug[] = []\n\n const queryPresetsCollections: CollectionSlug[] = []\n\n const schedulePublishGlobals: GlobalSlug[] = []\n\n const collectionSlugs = new Set<CollectionSlug>()\n\n const validRelationships = [\n ...(config.collections?.map((c) => c.slug) ?? []),\n jobsCollectionSlug,\n lockedDocumentsCollectionSlug,\n preferencesCollectionSlug,\n ]\n\n const dashboardWidgets = config.admin?.dashboard?.widgets ?? ([] as Widget[])\n\n for (const widget of dashboardWidgets) {\n if (widget.fields?.length) {\n widget.fields = sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: widget.fields,\n parentIsLocalized: false,\n validRelationships,\n })\n }\n }\n\n /**\n * Blocks sanitization needs to happen before collections, as collection/global join field sanitization needs config.blocks\n * to be populated with the sanitized blocks\n */\n config.blocks = []\n\n if (incomingConfig.blocks?.length) {\n for (const block of incomingConfig.blocks) {\n const sanitizedBlock = block\n\n if (sanitizedBlock._sanitized === true) {\n continue\n }\n sanitizedBlock._sanitized = true\n\n sanitizedBlock.fields = sanitizedBlock.fields.concat(baseBlockFields)\n\n sanitizedBlock.labels = !sanitizedBlock.labels\n ? formatLabels(sanitizedBlock.slug)\n : sanitizedBlock.labels\n\n sanitizedBlock.fields = sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: sanitizedBlock.fields,\n parentIsLocalized: false,\n validRelationships,\n })\n\n const flattenedSanitizedBlock = flattenBlock({ block })\n\n config.blocks.push(flattenedSanitizedBlock)\n }\n }\n\n // Track orderable join fields during sanitization\n const orderableJoins: OrderableJoinInfo[] = []\n\n for (let i = 0; i < config.collections!.length; i++) {\n if (collectionSlugs.has(config.collections![i]!.slug)) {\n throw new DuplicateCollection('slug', config.collections![i]!.slug)\n }\n\n collectionSlugs.add(config.collections![i]!.slug)\n\n const draftsConfig = config.collections![i]?.versions?.drafts\n\n if (typeof draftsConfig === 'object' && draftsConfig.schedulePublish) {\n schedulePublishCollections.push(config.collections![i]!.slug)\n }\n\n if (config.collections![i]!.enableQueryPresets) {\n queryPresetsCollections.push(config.collections![i]!.slug)\n\n if (!validRelationships.includes(queryPresetsCollectionSlug)) {\n validRelationships.push(queryPresetsCollectionSlug)\n }\n }\n\n config.collections![i] = sanitizeCollection(\n config as unknown as Config,\n config.collections![i]!,\n validRelationships,\n orderableJoins,\n )\n }\n\n // Process orderable features after all collections are sanitized\n const fieldsToAdd = new Map<SanitizedCollectionConfig, string[]>()\n const joinFieldPathsByCollection = new Map<string, Map<string, string>>()\n\n // Handle collection.orderable\n for (const collection of config.collections!) {\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\n // Handle orderable join fields (tracked during sanitization)\n for (const joinInfo of orderableJoins) {\n const targetCollection = config.collections!.find(\n (c) => c.slug === joinInfo.targetCollectionSlug,\n )\n if (targetCollection) {\n const currentFields = fieldsToAdd.get(targetCollection) || []\n fieldsToAdd.set(targetCollection, [...currentFields, joinInfo.orderFieldName])\n\n const currentJoinFieldPaths =\n joinFieldPathsByCollection.get(targetCollection.slug) || new Map<string, string>()\n currentJoinFieldPaths.set(joinInfo.orderFieldName, joinInfo.joinFieldOn)\n joinFieldPathsByCollection.set(targetCollection.slug, currentJoinFieldPaths)\n }\n }\n\n // Add fields, hooks, and update flattenedFields\n for (const [collection, orderableFields] of fieldsToAdd) {\n addOrderableFieldsAndHook(\n collection,\n config as unknown as Config,\n orderableFields,\n joinFieldPathsByCollection,\n )\n // Regenerate flattenedFields since we added new fields\n collection.flattenedFields = flattenAllFields({ fields: collection.fields })\n }\n\n // Add endpoint if any orderable features exist\n if (fieldsToAdd.size > 0) {\n addOrderableEndpoint(config as SanitizedConfig, joinFieldPathsByCollection)\n }\n\n if (config.globals!.length > 0) {\n for (let i = 0; i < config.globals!.length; i++) {\n if (hasScheduledPublishEnabled(config.globals![i]!)) {\n schedulePublishGlobals.push(config.globals![i]!.slug)\n }\n\n config.globals![i] = sanitizeGlobal(\n config as unknown as Config,\n config.globals![i]!,\n validRelationships,\n )\n }\n }\n\n // Resolve hierarchy relationships across collections (also adds sidebar tabs)\n resolveHierarchyCollections(config as unknown as Config)\n\n if (schedulePublishCollections.length || schedulePublishGlobals.length) {\n ;((config.jobs ??= {} as SanitizedJobsConfig).tasks ??= []).push(\n getSchedulePublishTask({\n adminUserSlug: config.admin!.user,\n collections: schedulePublishCollections,\n globals: schedulePublishGlobals,\n }),\n )\n }\n\n ;(config.jobs ??= {} as SanitizedJobsConfig).enabled = Boolean(\n (Array.isArray(configWithDefaults.jobs?.tasks) && configWithDefaults.jobs?.tasks?.length) ||\n (Array.isArray(configWithDefaults.jobs?.workflows) &&\n configWithDefaults.jobs?.workflows?.length),\n )\n config.jobs.hasConcurrency = Boolean(\n config.jobs.tasks?.some((task) => task.concurrency) ||\n config.jobs.workflows?.some((workflow) => workflow.concurrency),\n )\n\n // Need to add default jobs collection before locked documents collections\n if (config.jobs.enabled) {\n // Check for schedule property in both tasks and workflows\n const hasScheduleProperty =\n (config?.jobs?.tasks?.length && config.jobs.tasks.some((task) => task.schedule)) ||\n (config?.jobs?.workflows?.length &&\n config.jobs.workflows.some((workflow) => workflow.schedule))\n\n if (hasScheduleProperty) {\n config.jobs.scheduling = true\n }\n\n // Add payload-jobs-stats global for tracking job system metadata.\n ;(config.globals ??= []).push(\n sanitizeGlobal(config as unknown as Config, getJobStatsGlobal(), validRelationships),\n )\n\n let defaultJobsCollection = getDefaultJobsCollection(config.jobs)\n\n if (typeof config.jobs.jobsCollectionOverrides === 'function') {\n defaultJobsCollection = config.jobs.jobsCollectionOverrides({\n defaultJobsCollection,\n })\n }\n const sanitizedJobsCollection = sanitizeCollection(\n config as unknown as Config,\n defaultJobsCollection,\n validRelationships,\n )\n\n ;(config.collections ??= []).push(sanitizedJobsCollection)\n }\n\n const lockedDocumentsCollection = getLockedDocumentsCollection(config as unknown as Config)\n\n if (lockedDocumentsCollection) {\n configWithDefaults.collections!.push(\n sanitizeCollection(\n config as unknown as Config,\n lockedDocumentsCollection,\n validRelationships,\n ),\n )\n }\n\n configWithDefaults.collections!.push(\n sanitizeCollection(\n config as unknown as Config,\n getPreferencesCollection(config as unknown as Config),\n validRelationships,\n ),\n )\n\n const migrations = sanitizeCollection(\n config as unknown as Config,\n migrationsCollection,\n validRelationships,\n )\n\n // @ts-expect-error indexSortableFields is only valid for @payloadcms/db-mongodb\n if (config?.db?.indexSortableFields) {\n migrations.indexes = [\n {\n fields: ['batch', 'name'],\n unique: false,\n },\n ]\n }\n configWithDefaults.collections!.push(migrations)\n\n if (queryPresetsCollections.length > 0) {\n configWithDefaults.collections!.push(\n sanitizeCollection(\n config as unknown as Config,\n getQueryPresetsConfig(config as unknown as Config),\n validRelationships,\n ),\n )\n }\n\n addDefaultDashboardWidgets({\n config,\n validRelationships,\n })\n\n if (config.serverURL !== '') {\n config.csrf!.push(config.serverURL!)\n }\n\n if (!config.storage) {\n config.storage = []\n }\n\n if (!config.upload) {\n config.upload = { adapters: [] }\n }\n\n config.upload.adapters = Array.from(\n new Set(config.collections!.map((c) => c.upload?.adapter).filter(Boolean) as string[]),\n )\n\n // Pass through the email config as is so adapters don't break\n if (incomingConfig.email) {\n config.email = incomingConfig.email\n }\n\n return config as SanitizedConfig\n}\n"],"names":["en","defaultUserCollection","authRootEndpoints","sanitizeCollection","migrationsCollection","DuplicateCollection","InvalidConfiguration","defaultTimezones","sanitizeGlobal","resolveHierarchyCollections","baseBlockFields","formatLabels","sanitizeFields","getLockedDocumentsCollection","lockedDocumentsCollectionSlug","getPreferencesCollection","preferencesCollectionSlug","getQueryPresetsConfig","queryPresetsCollectionSlug","getDefaultJobsCollection","jobsCollectionSlug","getJobStatsGlobal","stagedUploadEndpoints","uploadInstructionsEndpoint","flattenAllFields","flattenBlock","hasScheduledPublishEnabled","validateTimezones","getSchedulePublishTask","addDefaultsToConfig","addOrderableEndpoint","addOrderableFieldsAndHook","sanitizeAdminConfig","configToSanitize","sanitizedConfig","loggingLevels","Forbidden","Locked","MissingFile","NotFound","ValidationError","admin","user","firstCollectionWithAuth","collections","find","auth","Boolean","slug","push","userCollection","timezones","supportedTimezones","source","addDefaultDashboardWidgets","config","validRelationships","collectionQueryFields","name","type","label","t","options","filter","collection","hidden","map","labels","plural","value","required","components","Field","defaultValue","max","min","recentlyViewedFields","hasMany","adminConfig","dashboard","widgets","Component","minWidth","fields","existingFieldNames","Set","parentIsLocalized","defaultLayout","widgetSlug","width","sanitizeConfig","incomingConfig","configWithDefaults","duration","safetyBuffer","jobs","processingLease","endpoints","some","upload","endpoint","localization","locales","length","firstLocale","localeCodes","locale","code","rtl","toString","fallback","i18nConfig","fallbackLanguage","supportedLanguages","translations","i18n","supportedLangKeys","Object","keys","fallbackLang","includes","editor","isRoot","schedulePublishCollections","queryPresetsCollections","schedulePublishGlobals","collectionSlugs","c","dashboardWidgets","widget","blocks","block","sanitizedBlock","_sanitized","concat","flattenedSanitizedBlock","orderableJoins","i","has","add","draftsConfig","versions","drafts","schedulePublish","enableQueryPresets","fieldsToAdd","Map","joinFieldPathsByCollection","orderable","currentFields","get","set","defaultSort","joinInfo","targetCollection","targetCollectionSlug","orderFieldName","currentJoinFieldPaths","joinFieldOn","orderableFields","flattenedFields","size","globals","tasks","adminUserSlug","enabled","Array","isArray","workflows","hasConcurrency","task","concurrency","workflow","hasScheduleProperty","schedule","scheduling","defaultJobsCollection","jobsCollectionOverrides","sanitizedJobsCollection","lockedDocumentsCollection","migrations","db","indexSortableFields","indexes","unique","serverURL","csrf","storage","adapters","from","adapter","email"],"mappings":"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"}
|