payload 4.0.0-beta.3 → 4.0.0-beta.4
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/adapters/router.d.ts +1 -1
- package/dist/admin/adapters/router.d.ts.map +1 -1
- package/dist/admin/adapters/router.js.map +1 -1
- package/dist/admin/initAdminContext.js.map +1 -1
- package/dist/auth/getFieldsToSign.js.map +1 -1
- package/dist/auth/loginWithCookie.js.map +1 -1
- package/dist/auth/serverFunctions/cookies.js.map +1 -1
- package/dist/auth/serverFunctions/login.js.map +1 -1
- package/dist/cli/defineCLICommand.js +1 -1
- package/dist/cli/defineCLICommand.js.map +1 -1
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/operations/findByID.js.map +1 -1
- package/dist/collections/operations/findVersionByID.js.map +1 -1
- package/dist/collections/operations/findVersions.js.map +1 -1
- package/dist/collections/operations/local/findDistinct.js.map +1 -1
- package/dist/collections/operations/renameFile.js +1 -1
- package/dist/collections/operations/renameFile.js.map +1 -1
- package/dist/collections/operations/utilities/update.js +1 -1
- package/dist/collections/operations/utilities/update.js.map +1 -1
- package/dist/collections/operations/validate.js +4 -4
- package/dist/collections/operations/validate.js.map +1 -1
- package/dist/config/definePlugin.js.map +1 -1
- package/dist/config/sanitize.js +2 -2
- package/dist/config/sanitize.js.map +1 -1
- package/dist/exports/build-config.d.ts +9 -0
- package/dist/exports/build-config.d.ts.map +1 -0
- package/dist/exports/build-config.js +38 -0
- package/dist/exports/build-config.js.map +1 -0
- package/dist/fields/config/client.js.map +1 -1
- package/dist/fields/hooks/afterChange/promise.js.map +1 -1
- package/dist/fields/validations.d.ts.map +1 -1
- package/dist/fields/validations.js +4 -1
- package/dist/fields/validations.js.map +1 -1
- package/dist/globals/operations/local/findOne.js.map +1 -1
- package/dist/globals/operations/local/update.js.map +1 -1
- package/dist/globals/operations/restoreVersion.d.ts +2 -3
- package/dist/globals/operations/restoreVersion.d.ts.map +1 -1
- package/dist/globals/operations/restoreVersion.js +22 -15
- package/dist/globals/operations/restoreVersion.js.map +1 -1
- package/dist/globals/operations/validate.js +1 -1
- package/dist/globals/operations/validate.js.map +1 -1
- package/dist/hierarchy/createFolderField.js.map +1 -1
- package/dist/hierarchy/resolveHierarchyCollections.js +2 -2
- package/dist/hierarchy/resolveHierarchyCollections.js.map +1 -1
- package/dist/hierarchy/utils/computePaths.d.ts.map +1 -1
- package/dist/hierarchy/utils/computePaths.js.map +1 -1
- package/dist/index.bundled.d.ts +12 -3
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +1 -1
- package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
- package/dist/uploads/fileVersioning/archive.js.map +1 -1
- package/dist/uploads/fileVersioning/resolveHistoricalFile.js.map +1 -1
- package/dist/uploads/generateFileData.d.ts.map +1 -1
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getFileFromUploadInstructions.js.map +1 -1
- package/dist/uploads/safeFetch.js.map +1 -1
- package/dist/uploads/stagedUpload.js.map +1 -1
- package/dist/uploads/transformers/handleDynamicFileRequest.js +11 -2
- package/dist/uploads/transformers/handleDynamicFileRequest.js.map +1 -1
- package/dist/utilities/addSelectGenericsToGeneretedTypes.d.ts.map +1 -1
- package/dist/utilities/addSelectGenericsToGeneretedTypes.js +0 -1
- package/dist/utilities/addSelectGenericsToGeneretedTypes.js.map +1 -1
- package/dist/utilities/appendDateTimezoneSelectFields.js.map +1 -1
- package/dist/utilities/cloneValidationRequest.js.map +1 -1
- package/dist/utilities/createPayloadRequest.js.map +1 -1
- package/dist/utilities/deepCopyObject.js.map +1 -1
- package/dist/utilities/documentMatchingWhereExists.js +1 -1
- package/dist/utilities/documentMatchingWhereExists.js.map +1 -1
- package/dist/utilities/filterDataToSelectedLocales.js.map +1 -1
- package/dist/utilities/getEntityPermissions/getEntityPermissions.d.ts.map +1 -1
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js +1 -0
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js.map +1 -1
- package/dist/utilities/getEntityPermissions/populateFieldPermissions.js.map +1 -1
- package/dist/utilities/parseParams/index.js.map +1 -1
- package/dist/utilities/parseValidationLocale.js.map +1 -1
- package/dist/utilities/sanitizePopulateParam.js.map +1 -1
- package/dist/utilities/telemetry/featureInfo/getFeatureInfo.js.map +1 -1
- package/dist/versions/allLocalesPublicationStatus.js.map +1 -1
- package/package.json +11 -9
- package/skills/payload/reference/PLUGIN-DEVELOPMENT.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utilities/getEntityPermissions/getEntityPermissions.ts"],"sourcesContent":["import { isDeepStrictEqual } from 'util'\n\nimport type {\n BlockPermissions,\n CollectionPermission,\n FieldsPermissions,\n GlobalPermission,\n Permission,\n} from '../../auth/types.js'\nimport type { SanitizedCollectionConfig, TypeWithID } from '../../collections/config/types.js'\nimport type { SanitizedGlobalConfig } from '../../globals/config/types.js'\nimport type { BlockSlug, DefaultDocumentIDType } from '../../index.js'\nimport type { AllOperations, JsonObject, PayloadRequest, Where } from '../../types/index.js'\n\nimport { getAccessOperationRequest } from '../getAccessOperationRequest.js'\nimport { entityDocExists } from './entityDocExists.js'\nimport { populateFieldPermissions } from './populateFieldPermissions.js'\n\ntype WhereQueryCache = { result: Promise<boolean>; where: Where }[]\n\nexport type BlockReferencesPermissions = Record<\n BlockSlug,\n BlockPermissions | Promise<BlockPermissions>\n>\n\nexport type EntityDoc = JsonObject | TypeWithID\n\ntype ReturnType<TEntityType extends 'collection' | 'global'> = TEntityType extends 'global'\n ? GlobalPermission\n : CollectionPermission\n\ntype Args<TEntityType extends 'collection' | 'global'> = {\n blockReferencesPermissions: BlockReferencesPermissions\n /**\n * If the document data is passed, it will be used to check access instead of fetching the document from the database.\n */\n data?: JsonObject\n entity: TEntityType extends 'collection' ? SanitizedCollectionConfig : SanitizedGlobalConfig\n entityType: TEntityType\n /**\n * Operations to check access for\n */\n operations: AllOperations[]\n req: PayloadRequest\n} & (\n | {\n fetchData: false\n id?: never\n }\n | {\n fetchData: true\n id: TEntityType extends 'collection' ? DefaultDocumentIDType : undefined\n }\n)\n\nconst topLevelCollectionPermissions = [\n 'create',\n 'delete',\n 'read',\n 'readVersions',\n 'update',\n 'validate',\n 'unlock',\n]\nconst topLevelGlobalPermissions = ['read', 'readVersions', 'update', 'validate']\n\n/**\n * Build up permissions object for an entity (collection or global).\n * This is not run during any update and reflects the current state of the entity data => doc and data is the same.\n *\n * When `fetchData` is false:\n * - returned `Where` are not run and evaluated as \"does not have permission\".\n * - If req.data is passed: `data` and `doc` is passed to access functions.\n * - If req.data is not passed: `data` and `doc` is not passed to access functions.\n *\n * When `fetchData` is true:\n * - `Where` are run and evaluated as \"has permission\" or \"does not have permission\".\n * - `data` and `doc` are always passed to access functions.\n * - Error is thrown if `entityType` is 'collection' and `id` is not passed.\n *\n * In both cases:\n * We cannot include siblingData or blockData here, as we do not have siblingData available once we reach block or array\n * rows, as we're calculating schema permissions, which do not include individual rows.\n * For consistency, it's thus better to never include the siblingData and blockData\n *\n * @internal\n */\nexport async function getEntityPermissions<TEntityType extends 'collection' | 'global'>(\n args: Args<TEntityType>,\n): Promise<ReturnType<TEntityType>> {\n const {\n id,\n blockReferencesPermissions,\n data: _data,\n entity,\n entityType,\n fetchData,\n operations,\n req,\n } = args\n const { locale: _locale, user } = req\n\n const locale = _locale ? _locale : undefined\n\n if (fetchData && entityType === 'collection' && !id) {\n throw new Error('ID is required when fetching data for a collection')\n }\n\n const hasData = _data && Object.keys(_data).length > 0\n const data: JsonObject | undefined = hasData\n ? _data\n : fetchData\n ? await (async () => {\n if (entityType === 'global') {\n return req.payload.findGlobal({\n slug: entity.slug,\n depth: 0,\n fallbackLocale: null,\n locale,\n overrideAccess: true,\n req,\n })\n }\n\n if (entityType === 'collection') {\n return req.payload.findByID({\n id: id!,\n collection: entity.slug,\n depth: 0,\n fallbackLocale: null,\n locale,\n overrideAccess: true,\n req,\n trash: true,\n })\n }\n })()\n : undefined\n\n const isLoggedIn = !!user\n\n const fieldsPermissions: FieldsPermissions = {}\n\n const entityPermissions: ReturnType<TEntityType> = {\n fields: fieldsPermissions,\n } as ReturnType<TEntityType>\n\n const promises: Promise<void>[] = []\n\n // Phase 1: Resolve all access functions to get where queries\n const accessResults: {\n operation: keyof typeof entity.access\n result: Promise<boolean | Where>\n }[] = []\n\n for (const _operation of operations) {\n const operation = _operation as keyof typeof entity.access\n const accessFunction = entity.access[operation]\n\n if (\n (entityType === 'collection' && topLevelCollectionPermissions.includes(operation)) ||\n (entityType === 'global' && topLevelGlobalPermissions.includes(operation))\n ) {\n if (typeof accessFunction === 'function') {\n accessResults.push({\n operation,\n result: Promise.resolve(\n accessFunction({\n id,\n slug: entity.slug,\n data,\n req:\n _operation === 'readVersions' || _operation === 'unlock'\n ? req\n : getAccessOperationRequest({\n operation: _operation,\n req,\n }),\n }),\n ) as Promise<boolean | Where>,\n })\n } else {\n entityPermissions[operation] = {\n permission: isLoggedIn,\n }\n }\n }\n }\n\n // Await all access functions in parallel\n const resolvedAccessResults = await Promise.all(\n accessResults.map(async (item) => ({\n operation: item.operation,\n result: await item.result,\n })),\n )\n\n // Phase 2: Process where queries with cache and resolve in parallel\n const whereQueryCache: WhereQueryCache = []\n const wherePromises: Promise<void>[] = []\n\n for (const { operation, result: accessResult } of resolvedAccessResults) {\n if (typeof accessResult === 'object') {\n processWhereQuery({\n id,\n slug: entity.slug,\n accessResult,\n entityPermissions,\n entityType,\n fetchData,\n locale,\n operation,\n req,\n wherePromises,\n whereQueryCache,\n })\n } else if (entityPermissions[operation]?.permission !== false) {\n entityPermissions[operation] = { permission: !!accessResult }\n }\n }\n\n // Await all where query DB calls in parallel\n await Promise.all(wherePromises)\n\n populateFieldPermissions({\n blockReferencesPermissions,\n collection: entityType === 'collection' ? (entity as SanitizedCollectionConfig) : null,\n data,\n fields: entity.fields,\n global: entityType === 'global' ? (entity as SanitizedGlobalConfig) : null,\n operations,\n parentPermissionsObject: entityPermissions,\n permissionsObject: fieldsPermissions,\n promises,\n req,\n })\n\n /**\n * Await all promises in parallel.\n * A promise can add more promises to the promises array (group of fields calls populateFieldPermissions again in their own promise), which will not be\n * awaited in the first run.\n * This is why we need to loop again to process the new promises, until there are no more promises left.\n */\n let iterations = 0\n while (promises.length > 0) {\n const currentPromises = promises.splice(0, promises.length)\n\n await Promise.all(currentPromises)\n\n iterations++\n if (iterations >= 100) {\n throw new Error('Infinite getEntityPermissions promise loop detected.')\n }\n }\n\n return entityPermissions\n}\n\nconst processWhereQuery = ({\n id,\n slug,\n accessResult,\n entityPermissions,\n entityType,\n fetchData,\n locale,\n operation,\n req,\n wherePromises,\n whereQueryCache,\n}: {\n accessResult: Where\n entityPermissions: CollectionPermission | GlobalPermission\n entityType: 'collection' | 'global'\n fetchData: boolean\n id?: DefaultDocumentIDType\n locale?: string\n operation: Extract<keyof (CollectionPermission | GlobalPermission), AllOperations>\n req: PayloadRequest\n slug: string\n wherePromises: Promise<void>[]\n whereQueryCache: WhereQueryCache\n}): void => {\n if (fetchData) {\n // Check cache for identical where query using deep comparison\n let cached = whereQueryCache.find((entry) => isDeepStrictEqual(entry.where, accessResult))\n\n if (!cached) {\n // Cache miss - start DB query (don't await)\n cached = {\n result: entityDocExists({\n id,\n slug,\n entityType,\n locale,\n operation,\n req,\n where: accessResult,\n }),\n where: accessResult,\n }\n whereQueryCache.push(cached)\n }\n\n // Defer resolution to Promise.all (cache hits reuse same promise)\n wherePromises.push(\n cached.result.then((hasPermission) => {\n entityPermissions[operation] = {\n permission: hasPermission,\n where: accessResult,\n } as Permission\n }),\n )\n } else {\n // TODO: 4.0: Investigate defaulting to `false` here, if where query is returned but ignored as we don't\n // have the document data available. This seems more secure.\n // Alternatively, we could set permission to a third state, like 'unknown'.\n // Even after calling sanitizePermissions, the permissions will still be true if the where query is returned but ignored as we don't have the document data available.\n entityPermissions[operation] = { permission: true, where: accessResult } as Permission\n }\n}\n"],"names":["isDeepStrictEqual","getAccessOperationRequest","entityDocExists","populateFieldPermissions","topLevelCollectionPermissions","topLevelGlobalPermissions","getEntityPermissions","args","id","blockReferencesPermissions","data","_data","entity","entityType","fetchData","operations","req","locale","_locale","user","undefined","Error","hasData","Object","keys","length","payload","findGlobal","slug","depth","fallbackLocale","overrideAccess","findByID","collection","trash","isLoggedIn","fieldsPermissions","entityPermissions","fields","promises","accessResults","_operation","operation","accessFunction","access","includes","push","result","Promise","resolve","permission","resolvedAccessResults","all","map","item","whereQueryCache","wherePromises","accessResult","processWhereQuery","global","parentPermissionsObject","permissionsObject","iterations","currentPromises","splice","cached","find","entry","where","then","hasPermission"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/utilities/getEntityPermissions/getEntityPermissions.ts"],"sourcesContent":["import { isDeepStrictEqual } from 'util'\n\nimport type {\n BlockPermissions,\n CollectionPermission,\n FieldsPermissions,\n GlobalPermission,\n Permission,\n} from '../../auth/types.js'\nimport type { SanitizedCollectionConfig, TypeWithID } from '../../collections/config/types.js'\nimport type { SanitizedGlobalConfig } from '../../globals/config/types.js'\nimport type { BlockSlug, DefaultDocumentIDType } from '../../index.js'\nimport type { AllOperations, JsonObject, PayloadRequest, Where } from '../../types/index.js'\n\nimport { getAccessOperationRequest } from '../getAccessOperationRequest.js'\nimport { entityDocExists } from './entityDocExists.js'\nimport { populateFieldPermissions } from './populateFieldPermissions.js'\n\ntype WhereQueryCache = { result: Promise<boolean>; where: Where }[]\n\nexport type BlockReferencesPermissions = Record<\n BlockSlug,\n BlockPermissions | Promise<BlockPermissions>\n>\n\nexport type EntityDoc = JsonObject | TypeWithID\n\ntype ReturnType<TEntityType extends 'collection' | 'global'> = TEntityType extends 'global'\n ? GlobalPermission\n : CollectionPermission\n\ntype Args<TEntityType extends 'collection' | 'global'> = {\n blockReferencesPermissions: BlockReferencesPermissions\n /**\n * If the document data is passed, it will be used to check access instead of fetching the document from the database.\n */\n data?: JsonObject\n entity: TEntityType extends 'collection' ? SanitizedCollectionConfig : SanitizedGlobalConfig\n entityType: TEntityType\n /**\n * Operations to check access for\n */\n operations: AllOperations[]\n req: PayloadRequest\n} & (\n | {\n fetchData: false\n id?: never\n }\n | {\n fetchData: true\n id: TEntityType extends 'collection' ? DefaultDocumentIDType : undefined\n }\n)\n\nconst topLevelCollectionPermissions = [\n 'create',\n 'delete',\n 'read',\n 'readVersions',\n 'update',\n 'validate',\n 'unlock',\n]\nconst topLevelGlobalPermissions = ['read', 'readVersions', 'update', 'validate']\n\n/**\n * Build up permissions object for an entity (collection or global).\n * This is not run during any update and reflects the current state of the entity data => doc and data is the same.\n *\n * When `fetchData` is false:\n * - returned `Where` are not run and evaluated as \"does not have permission\".\n * - If req.data is passed: `data` and `doc` is passed to access functions.\n * - If req.data is not passed: `data` and `doc` is not passed to access functions.\n *\n * When `fetchData` is true:\n * - `Where` are run and evaluated as \"has permission\" or \"does not have permission\".\n * - `data` and `doc` are always passed to access functions.\n * - Error is thrown if `entityType` is 'collection' and `id` is not passed.\n *\n * In both cases:\n * We cannot include siblingData or blockData here, as we do not have siblingData available once we reach block or array\n * rows, as we're calculating schema permissions, which do not include individual rows.\n * For consistency, it's thus better to never include the siblingData and blockData\n *\n * @internal\n */\nexport async function getEntityPermissions<TEntityType extends 'collection' | 'global'>(\n args: Args<TEntityType>,\n): Promise<ReturnType<TEntityType>> {\n const {\n id,\n blockReferencesPermissions,\n data: _data,\n entity,\n entityType,\n fetchData,\n operations,\n req,\n } = args\n const { locale: _locale, user } = req\n\n const locale = _locale ? _locale : undefined\n\n if (fetchData && entityType === 'collection' && !id) {\n throw new Error('ID is required when fetching data for a collection')\n }\n\n const hasData = _data && Object.keys(_data).length > 0\n const data: JsonObject | undefined = hasData\n ? _data\n : fetchData\n ? await (async () => {\n if (entityType === 'global') {\n return req.payload.findGlobal({\n slug: entity.slug,\n depth: 0,\n fallbackLocale: null,\n locale,\n overrideAccess: true,\n req,\n })\n }\n\n if (entityType === 'collection') {\n return req.payload.findByID({\n id: id!,\n collection: entity.slug,\n depth: 0,\n fallbackLocale: null,\n locale,\n overrideAccess: true,\n req,\n trash: true,\n })\n }\n })()\n : undefined\n\n const isLoggedIn = !!user\n\n const fieldsPermissions: FieldsPermissions = {}\n\n const entityPermissions: ReturnType<TEntityType> = {\n fields: fieldsPermissions,\n }\n\n const promises: Promise<void>[] = []\n\n // Phase 1: Resolve all access functions to get where queries\n const accessResults: {\n operation: keyof typeof entity.access\n result: Promise<boolean | Where>\n }[] = []\n\n for (const _operation of operations) {\n const operation = _operation as keyof typeof entity.access\n const accessFunction = entity.access[operation]\n\n if (\n (entityType === 'collection' && topLevelCollectionPermissions.includes(operation)) ||\n (entityType === 'global' && topLevelGlobalPermissions.includes(operation))\n ) {\n if (typeof accessFunction === 'function') {\n accessResults.push({\n operation,\n result: Promise.resolve(\n accessFunction({\n id,\n slug: entity.slug,\n data,\n req:\n _operation === 'readVersions' || _operation === 'unlock'\n ? req\n : getAccessOperationRequest({\n operation: _operation,\n req,\n }),\n }),\n ),\n })\n } else {\n entityPermissions[operation] = {\n permission: isLoggedIn,\n }\n }\n }\n }\n\n // Await all access functions in parallel\n const resolvedAccessResults = await Promise.all(\n accessResults.map(async (item) => ({\n operation: item.operation,\n result: await item.result,\n })),\n )\n\n // Phase 2: Process where queries with cache and resolve in parallel\n const whereQueryCache: WhereQueryCache = []\n const wherePromises: Promise<void>[] = []\n\n for (const { operation, result: accessResult } of resolvedAccessResults) {\n if (typeof accessResult === 'object') {\n processWhereQuery({\n id,\n slug: entity.slug,\n accessResult,\n entityPermissions,\n entityType,\n fetchData,\n locale,\n operation,\n req,\n wherePromises,\n whereQueryCache,\n })\n } else if (entityPermissions[operation]?.permission !== false) {\n entityPermissions[operation] = { permission: !!accessResult }\n }\n }\n\n // Await all where query DB calls in parallel\n await Promise.all(wherePromises)\n\n populateFieldPermissions({\n id,\n blockReferencesPermissions,\n collection: entityType === 'collection' ? (entity as SanitizedCollectionConfig) : null,\n data,\n fields: entity.fields,\n global: entityType === 'global' ? (entity as SanitizedGlobalConfig) : null,\n operations,\n parentPermissionsObject: entityPermissions,\n permissionsObject: fieldsPermissions,\n promises,\n req,\n })\n\n /**\n * Await all promises in parallel.\n * A promise can add more promises to the promises array (group of fields calls populateFieldPermissions again in their own promise), which will not be\n * awaited in the first run.\n * This is why we need to loop again to process the new promises, until there are no more promises left.\n */\n let iterations = 0\n while (promises.length > 0) {\n const currentPromises = promises.splice(0, promises.length)\n\n await Promise.all(currentPromises)\n\n iterations++\n if (iterations >= 100) {\n throw new Error('Infinite getEntityPermissions promise loop detected.')\n }\n }\n\n return entityPermissions\n}\n\nconst processWhereQuery = ({\n id,\n slug,\n accessResult,\n entityPermissions,\n entityType,\n fetchData,\n locale,\n operation,\n req,\n wherePromises,\n whereQueryCache,\n}: {\n accessResult: Where\n entityPermissions: CollectionPermission | GlobalPermission\n entityType: 'collection' | 'global'\n fetchData: boolean\n id?: DefaultDocumentIDType\n locale?: string\n operation: Extract<keyof (CollectionPermission | GlobalPermission), AllOperations>\n req: PayloadRequest\n slug: string\n wherePromises: Promise<void>[]\n whereQueryCache: WhereQueryCache\n}): void => {\n if (fetchData) {\n // Check cache for identical where query using deep comparison\n let cached = whereQueryCache.find((entry) => isDeepStrictEqual(entry.where, accessResult))\n\n if (!cached) {\n // Cache miss - start DB query (don't await)\n cached = {\n result: entityDocExists({\n id,\n slug,\n entityType,\n locale,\n operation,\n req,\n where: accessResult,\n }),\n where: accessResult,\n }\n whereQueryCache.push(cached)\n }\n\n // Defer resolution to Promise.all (cache hits reuse same promise)\n wherePromises.push(\n cached.result.then((hasPermission) => {\n entityPermissions[operation] = {\n permission: hasPermission,\n where: accessResult,\n }\n }),\n )\n } else {\n // TODO: 4.0: Investigate defaulting to `false` here, if where query is returned but ignored as we don't\n // have the document data available. This seems more secure.\n // Alternatively, we could set permission to a third state, like 'unknown'.\n // Even after calling sanitizePermissions, the permissions will still be true if the where query is returned but ignored as we don't have the document data available.\n entityPermissions[operation] = { permission: true, where: accessResult }\n }\n}\n"],"names":["isDeepStrictEqual","getAccessOperationRequest","entityDocExists","populateFieldPermissions","topLevelCollectionPermissions","topLevelGlobalPermissions","getEntityPermissions","args","id","blockReferencesPermissions","data","_data","entity","entityType","fetchData","operations","req","locale","_locale","user","undefined","Error","hasData","Object","keys","length","payload","findGlobal","slug","depth","fallbackLocale","overrideAccess","findByID","collection","trash","isLoggedIn","fieldsPermissions","entityPermissions","fields","promises","accessResults","_operation","operation","accessFunction","access","includes","push","result","Promise","resolve","permission","resolvedAccessResults","all","map","item","whereQueryCache","wherePromises","accessResult","processWhereQuery","global","parentPermissionsObject","permissionsObject","iterations","currentPromises","splice","cached","find","entry","where","then","hasPermission"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utilities/getEntityPermissions/populateFieldPermissions.ts"],"sourcesContent":["import type {\n BlockPermissions,\n BlocksPermissions,\n CollectionPermission,\n FieldPermissions,\n FieldsPermissions,\n GlobalPermission,\n Permission,\n} from '../../auth/types.js'\nimport type { SanitizedCollectionConfig } from '../../collections/config/types.js'\nimport type { SanitizedGlobalConfig } from '../../globals/config/types.js'\nimport type { DefaultDocumentIDType } from '../../index.js'\nimport type { AllOperations, JsonObject, PayloadRequest } from '../../types/index.js'\nimport type { BlockReferencesPermissions } from './getEntityPermissions.js'\n\nimport { type Field, tabHasName } from '../../fields/config/types.js'\nimport { getAccessOperationRequest } from '../getAccessOperationRequest.js'\n\nconst isThenable = (value: unknown): value is Promise<unknown> =>\n value != null && typeof (value as { then?: unknown }).then === 'function'\n\n/**\n * Helper to set a permission value that might be a promise.\n * If it's a promise, creates a chained promise that resolves to update the target,\n * stores the promise temporarily, and adds it to the promises array for later resolution.\n */\nconst setPermission = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n target: any,\n operation: AllOperations,\n value: boolean | Promise<boolean> | undefined,\n promises: Promise<void>[],\n): void => {\n if (isThenable(value)) {\n // Create a single permission object that will be mutated in place\n // This ensures all references (including cached blocks) see the resolved value\n const permissionObj = { permission: value as any }\n target[operation] = permissionObj\n\n const permissionPromise = value.then((result) => {\n // Mutate the permission property in place so all references see the update\n permissionObj.permission = result\n })\n\n promises.push(permissionPromise)\n } else {\n target[operation] = { permission: value }\n }\n}\n\n/**\n * Build up permissions object and run access functions for each field of an entity\n * This function is synchronous and collects all async work into the promises array\n */\nexport const populateFieldPermissions = ({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields,\n global,\n operations,\n parentPermissionsObject,\n permissionsObject,\n promises,\n req,\n}: {\n blockReferencesPermissions: BlockReferencesPermissions\n /** The collection which the fields belong to. If the fields belong to a global, this will be null. */\n collection: null | SanitizedCollectionConfig\n data: JsonObject | undefined\n fields: Field[]\n /** The global which the fields belong to. If the fields belong to a collection, this will be null. */\n global: null | SanitizedGlobalConfig\n id?: DefaultDocumentIDType\n /**\n * Operations to check access for\n */\n operations: AllOperations[]\n parentPermissionsObject: CollectionPermission | FieldPermissions | GlobalPermission\n permissionsObject: FieldsPermissions\n promises: Promise<void>[]\n req: PayloadRequest\n}): void => {\n for (const field of fields) {\n // Set up permissions for all operations\n for (const operation of operations) {\n const parentPermissionForOperation = (\n parentPermissionsObject[operation as keyof typeof parentPermissionsObject] as Permission\n )?.permission\n\n // Fields don't have all operations of a collection\n if (operation === 'delete' || operation === 'readVersions' || operation === 'unlock') {\n continue\n }\n\n if ('name' in field && field.name) {\n if (!permissionsObject[field.name]) {\n permissionsObject[field.name] = {} as FieldPermissions\n }\n const fieldPermissions: FieldPermissions = permissionsObject[field.name]!\n\n if ('access' in field && field.access && typeof field.access[operation] === 'function') {\n const accessResult = field.access[operation](\n collection\n ? {\n id,\n collection,\n data,\n doc: data,\n req: getAccessOperationRequest({\n operation,\n req,\n }),\n // We cannot include siblingData or blockData here, as we do not have siblingData/blockData available once we reach block or array\n // rows, as we're calculating schema permissions, which do not include individual rows.\n // For consistency, it's thus better to never include the siblingData and blockData\n }\n : {\n id,\n data,\n doc: data,\n global: global!,\n req: getAccessOperationRequest({\n operation,\n req,\n }),\n // We cannot include siblingData or blockData here, as we do not have siblingData/blockData available once we reach block or array\n // rows, as we're calculating schema permissions, which do not include individual rows.\n // For consistency, it's thus better to never include the siblingData and blockData\n },\n )\n\n // Handle both sync and async access results\n if (isThenable(accessResult)) {\n const booleanPromise = accessResult.then((result) => Boolean(result))\n setPermission(fieldPermissions, operation, booleanPromise, promises)\n } else {\n setPermission(fieldPermissions, operation, Boolean(accessResult), promises)\n }\n } else {\n // Inherit from parent (which might be a promise)\n setPermission(fieldPermissions, operation, parentPermissionForOperation, promises)\n }\n }\n }\n\n // Handle named fields with nested content\n if ('name' in field && field.name) {\n const fieldPermissions: FieldPermissions = permissionsObject[field.name]!\n\n if ('fields' in field && field.fields) {\n if (!fieldPermissions.fields) {\n fieldPermissions.fields = {}\n }\n\n populateFieldPermissions({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields: field.fields,\n global,\n operations,\n parentPermissionsObject: fieldPermissions,\n permissionsObject: fieldPermissions.fields,\n promises,\n req,\n })\n }\n\n if ('blocks' in field && field.blocks?.length) {\n if (!fieldPermissions.blocks) {\n fieldPermissions.blocks = {}\n }\n const blocksPermissions: BlocksPermissions = fieldPermissions.blocks\n\n // Set up permissions for all operations for all blocks\n for (const operation of operations) {\n // Fields don't have all operations of a collection\n if (operation === 'delete' || operation === 'readVersions' || operation === 'unlock') {\n continue\n }\n\n const parentPermissionForOperation = (\n parentPermissionsObject[operation as keyof typeof parentPermissionsObject] as Permission\n )?.permission\n\n for (const _block of field.blocks) {\n const block = typeof _block === 'string' ? req.payload.blocks[_block] : _block\n\n // Skip if block doesn't exist (invalid block reference)\n if (!block) {\n continue\n }\n\n // Handle block references - check if we've seen this block before\n if (typeof _block === 'string') {\n const blockReferencePermissions = blockReferencesPermissions[_block]\n if (blockReferencePermissions) {\n // Reference the cached permissions (may be a promise or resolved object)\n blocksPermissions[block.slug] = blockReferencePermissions as BlockPermissions\n continue\n }\n }\n\n // Initialize block permissions object if needed\n if (!blocksPermissions[block.slug]) {\n blocksPermissions[block.slug] = {} as BlockPermissions\n }\n\n const blockPermission = blocksPermissions[block.slug]!\n\n // Set permission for this operation\n if (!blockPermission[operation]) {\n const fieldPermission =\n fieldPermissions[operation]?.permission ?? parentPermissionForOperation\n\n // Inherit from field permission (which might be a promise)\n setPermission(blockPermission, operation, fieldPermission, promises)\n }\n }\n }\n\n // Process nested content for each unique block (once per block, not once per operation)\n const processedBlocks = new Set<string>()\n for (const _block of field.blocks) {\n const block = typeof _block === 'string' ? req.payload.blocks[_block] : _block\n\n // Skip if block doesn't exist (invalid block reference)\n if (!block || processedBlocks.has(block.slug)) {\n continue\n }\n processedBlocks.add(block.slug)\n\n const blockPermission = blocksPermissions[block.slug]\n if (!blockPermission) {\n continue\n }\n\n if (!blockPermission.fields) {\n blockPermission.fields = {}\n }\n\n // Handle block references with caching - store as promise that will be resolved later\n if (typeof _block === 'string' && !blockReferencesPermissions[_block]) {\n // Mark this block as being processed by storing a reference\n blockReferencesPermissions[_block] = blockPermission\n }\n\n // Recursively process block fields synchronously\n populateFieldPermissions({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields: block.fields,\n global,\n operations,\n parentPermissionsObject: blockPermission,\n permissionsObject: blockPermission.fields,\n promises,\n req,\n })\n }\n }\n }\n\n // Handle unnamed group fields\n if ('fields' in field && field.fields && !('name' in field && field.name)) {\n // Field does not have a name => same parentPermissionsObject\n populateFieldPermissions({\n id,\n collection,\n data,\n fields: field.fields,\n global,\n operations,\n // Field does not have a name here => use parent permissions object\n blockReferencesPermissions,\n parentPermissionsObject,\n permissionsObject,\n promises,\n req,\n })\n }\n\n // Handle tabs fields\n if (field.type === 'tabs') {\n // Process tabs for all operations\n for (const operation of operations) {\n // Fields don't have all operations of a collection\n if (operation === 'delete' || operation === 'readVersions' || operation === 'unlock') {\n continue\n }\n\n const parentPermissionForOperation = (\n parentPermissionsObject[operation as keyof typeof parentPermissionsObject] as Permission\n )?.permission\n\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n if (!permissionsObject[tab.name]) {\n permissionsObject[tab.name] = { fields: {} } as FieldPermissions\n }\n\n const tabPermissions = permissionsObject[tab.name]!\n if (!tabPermissions[operation]) {\n // Inherit from parent (which might be a promise)\n setPermission(tabPermissions, operation, parentPermissionForOperation, promises)\n }\n }\n }\n }\n\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n const tabPermissions: FieldPermissions = permissionsObject[tab.name]!\n\n if (!tabPermissions.fields) {\n tabPermissions.fields = {}\n }\n\n populateFieldPermissions({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields: tab.fields,\n global,\n operations,\n parentPermissionsObject: tabPermissions,\n permissionsObject: tabPermissions.fields,\n promises,\n req,\n })\n } else {\n // Tab does not have a name => same parentPermissionsObject\n populateFieldPermissions({\n id,\n collection,\n data,\n fields: tab.fields,\n global,\n operations,\n // Tab does not have a name here => use parent permissions object\n blockReferencesPermissions,\n parentPermissionsObject,\n permissionsObject,\n promises,\n req,\n })\n }\n }\n }\n }\n}\n"],"names":["tabHasName","getAccessOperationRequest","isThenable","value","then","setPermission","target","operation","promises","permissionObj","permission","permissionPromise","result","push","populateFieldPermissions","id","blockReferencesPermissions","collection","data","fields","global","operations","parentPermissionsObject","permissionsObject","req","field","parentPermissionForOperation","name","fieldPermissions","access","accessResult","doc","booleanPromise","Boolean","blocks","length","blocksPermissions","_block","block","payload","blockReferencePermissions","slug","blockPermission","fieldPermission","processedBlocks","Set","has","add","type","tab","tabs","tabPermissions"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/utilities/getEntityPermissions/populateFieldPermissions.ts"],"sourcesContent":["import type {\n BlockPermissions,\n BlocksPermissions,\n CollectionPermission,\n FieldPermissions,\n FieldsPermissions,\n GlobalPermission,\n Permission,\n} from '../../auth/types.js'\nimport type { SanitizedCollectionConfig } from '../../collections/config/types.js'\nimport type { SanitizedGlobalConfig } from '../../globals/config/types.js'\nimport type { DefaultDocumentIDType } from '../../index.js'\nimport type { AllOperations, JsonObject, PayloadRequest } from '../../types/index.js'\nimport type { BlockReferencesPermissions } from './getEntityPermissions.js'\n\nimport { type Field, tabHasName } from '../../fields/config/types.js'\nimport { getAccessOperationRequest } from '../getAccessOperationRequest.js'\n\nconst isThenable = (value: unknown): value is Promise<unknown> =>\n value != null && typeof (value as { then?: unknown }).then === 'function'\n\n/**\n * Helper to set a permission value that might be a promise.\n * If it's a promise, creates a chained promise that resolves to update the target,\n * stores the promise temporarily, and adds it to the promises array for later resolution.\n */\nconst setPermission = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n target: any,\n operation: AllOperations,\n value: boolean | Promise<boolean> | undefined,\n promises: Promise<void>[],\n): void => {\n if (isThenable(value)) {\n // Create a single permission object that will be mutated in place\n // This ensures all references (including cached blocks) see the resolved value\n const permissionObj = { permission: value as any }\n target[operation] = permissionObj\n\n const permissionPromise = value.then((result) => {\n // Mutate the permission property in place so all references see the update\n permissionObj.permission = result\n })\n\n promises.push(permissionPromise)\n } else {\n target[operation] = { permission: value }\n }\n}\n\n/**\n * Build up permissions object and run access functions for each field of an entity\n * This function is synchronous and collects all async work into the promises array\n */\nexport const populateFieldPermissions = ({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields,\n global,\n operations,\n parentPermissionsObject,\n permissionsObject,\n promises,\n req,\n}: {\n blockReferencesPermissions: BlockReferencesPermissions\n /** The collection which the fields belong to. If the fields belong to a global, this will be null. */\n collection: null | SanitizedCollectionConfig\n data: JsonObject | undefined\n fields: Field[]\n /** The global which the fields belong to. If the fields belong to a collection, this will be null. */\n global: null | SanitizedGlobalConfig\n id?: DefaultDocumentIDType\n /**\n * Operations to check access for\n */\n operations: AllOperations[]\n parentPermissionsObject: CollectionPermission | FieldPermissions | GlobalPermission\n permissionsObject: FieldsPermissions\n promises: Promise<void>[]\n req: PayloadRequest\n}): void => {\n for (const field of fields) {\n // Set up permissions for all operations\n for (const operation of operations) {\n const parentPermissionForOperation = (\n parentPermissionsObject[operation as keyof typeof parentPermissionsObject] as Permission\n )?.permission\n\n // Fields don't have all operations of a collection\n if (operation === 'delete' || operation === 'readVersions' || operation === 'unlock') {\n continue\n }\n\n if ('name' in field && field.name) {\n if (!permissionsObject[field.name]) {\n permissionsObject[field.name] = {}\n }\n const fieldPermissions: FieldPermissions = permissionsObject[field.name]!\n\n if ('access' in field && field.access && typeof field.access[operation] === 'function') {\n const accessResult = field.access[operation](\n collection\n ? {\n id,\n collection,\n data,\n doc: data,\n req: getAccessOperationRequest({\n operation,\n req,\n }),\n // We cannot include siblingData or blockData here, as we do not have siblingData/blockData available once we reach block or array\n // rows, as we're calculating schema permissions, which do not include individual rows.\n // For consistency, it's thus better to never include the siblingData and blockData\n }\n : {\n id,\n data,\n doc: data,\n global: global!,\n req: getAccessOperationRequest({\n operation,\n req,\n }),\n // We cannot include siblingData or blockData here, as we do not have siblingData/blockData available once we reach block or array\n // rows, as we're calculating schema permissions, which do not include individual rows.\n // For consistency, it's thus better to never include the siblingData and blockData\n },\n )\n\n // Handle both sync and async access results\n if (isThenable(accessResult)) {\n const booleanPromise = accessResult.then((result) => Boolean(result))\n setPermission(fieldPermissions, operation, booleanPromise, promises)\n } else {\n setPermission(fieldPermissions, operation, Boolean(accessResult), promises)\n }\n } else {\n // Inherit from parent (which might be a promise)\n setPermission(fieldPermissions, operation, parentPermissionForOperation, promises)\n }\n }\n }\n\n // Handle named fields with nested content\n if ('name' in field && field.name) {\n const fieldPermissions: FieldPermissions = permissionsObject[field.name]!\n\n if ('fields' in field && field.fields) {\n if (!fieldPermissions.fields) {\n fieldPermissions.fields = {}\n }\n\n populateFieldPermissions({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields: field.fields,\n global,\n operations,\n parentPermissionsObject: fieldPermissions,\n permissionsObject: fieldPermissions.fields,\n promises,\n req,\n })\n }\n\n if ('blocks' in field && field.blocks?.length) {\n if (!fieldPermissions.blocks) {\n fieldPermissions.blocks = {}\n }\n const blocksPermissions: BlocksPermissions = fieldPermissions.blocks\n\n // Set up permissions for all operations for all blocks\n for (const operation of operations) {\n // Fields don't have all operations of a collection\n if (operation === 'delete' || operation === 'readVersions' || operation === 'unlock') {\n continue\n }\n\n const parentPermissionForOperation = (\n parentPermissionsObject[operation as keyof typeof parentPermissionsObject] as Permission\n )?.permission\n\n for (const _block of field.blocks) {\n const block = typeof _block === 'string' ? req.payload.blocks[_block] : _block\n\n // Skip if block doesn't exist (invalid block reference)\n if (!block) {\n continue\n }\n\n // Handle block references - check if we've seen this block before\n if (typeof _block === 'string') {\n const blockReferencePermissions = blockReferencesPermissions[_block]\n if (blockReferencePermissions) {\n // Reference the cached permissions (may be a promise or resolved object)\n blocksPermissions[block.slug] = blockReferencePermissions as BlockPermissions\n continue\n }\n }\n\n // Initialize block permissions object if needed\n if (!blocksPermissions[block.slug]) {\n blocksPermissions[block.slug] = {} as BlockPermissions\n }\n\n const blockPermission = blocksPermissions[block.slug]!\n\n // Set permission for this operation\n if (!blockPermission[operation]) {\n const fieldPermission =\n fieldPermissions[operation]?.permission ?? parentPermissionForOperation\n\n // Inherit from field permission (which might be a promise)\n setPermission(blockPermission, operation, fieldPermission, promises)\n }\n }\n }\n\n // Process nested content for each unique block (once per block, not once per operation)\n const processedBlocks = new Set<string>()\n for (const _block of field.blocks) {\n const block = typeof _block === 'string' ? req.payload.blocks[_block] : _block\n\n // Skip if block doesn't exist (invalid block reference)\n if (!block || processedBlocks.has(block.slug)) {\n continue\n }\n processedBlocks.add(block.slug)\n\n const blockPermission = blocksPermissions[block.slug]\n if (!blockPermission) {\n continue\n }\n\n if (!blockPermission.fields) {\n blockPermission.fields = {}\n }\n\n // Handle block references with caching - store as promise that will be resolved later\n if (typeof _block === 'string' && !blockReferencesPermissions[_block]) {\n // Mark this block as being processed by storing a reference\n blockReferencesPermissions[_block] = blockPermission\n }\n\n // Recursively process block fields synchronously\n populateFieldPermissions({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields: block.fields,\n global,\n operations,\n parentPermissionsObject: blockPermission,\n permissionsObject: blockPermission.fields,\n promises,\n req,\n })\n }\n }\n }\n\n // Handle unnamed group fields\n if ('fields' in field && field.fields && !('name' in field && field.name)) {\n // Field does not have a name => same parentPermissionsObject\n populateFieldPermissions({\n id,\n collection,\n data,\n fields: field.fields,\n global,\n operations,\n // Field does not have a name here => use parent permissions object\n blockReferencesPermissions,\n parentPermissionsObject,\n permissionsObject,\n promises,\n req,\n })\n }\n\n // Handle tabs fields\n if (field.type === 'tabs') {\n // Process tabs for all operations\n for (const operation of operations) {\n // Fields don't have all operations of a collection\n if (operation === 'delete' || operation === 'readVersions' || operation === 'unlock') {\n continue\n }\n\n const parentPermissionForOperation = (\n parentPermissionsObject[operation as keyof typeof parentPermissionsObject] as Permission\n )?.permission\n\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n if (!permissionsObject[tab.name]) {\n permissionsObject[tab.name] = { fields: {} }\n }\n\n const tabPermissions = permissionsObject[tab.name]!\n if (!tabPermissions[operation]) {\n // Inherit from parent (which might be a promise)\n setPermission(tabPermissions, operation, parentPermissionForOperation, promises)\n }\n }\n }\n }\n\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n const tabPermissions: FieldPermissions = permissionsObject[tab.name]!\n\n if (!tabPermissions.fields) {\n tabPermissions.fields = {}\n }\n\n populateFieldPermissions({\n id,\n blockReferencesPermissions,\n collection,\n data,\n fields: tab.fields,\n global,\n operations,\n parentPermissionsObject: tabPermissions,\n permissionsObject: tabPermissions.fields,\n promises,\n req,\n })\n } else {\n // Tab does not have a name => same parentPermissionsObject\n populateFieldPermissions({\n id,\n collection,\n data,\n fields: tab.fields,\n global,\n operations,\n // Tab does not have a name here => use parent permissions object\n blockReferencesPermissions,\n parentPermissionsObject,\n permissionsObject,\n promises,\n req,\n })\n }\n }\n }\n }\n}\n"],"names":["tabHasName","getAccessOperationRequest","isThenable","value","then","setPermission","target","operation","promises","permissionObj","permission","permissionPromise","result","push","populateFieldPermissions","id","blockReferencesPermissions","collection","data","fields","global","operations","parentPermissionsObject","permissionsObject","req","field","parentPermissionForOperation","name","fieldPermissions","access","accessResult","doc","booleanPromise","Boolean","blocks","length","blocksPermissions","_block","block","payload","blockReferencePermissions","slug","blockPermission","fieldPermission","processedBlocks","Set","has","add","type","tab","tabs","tabPermissions"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utilities/parseParams/index.ts"],"sourcesContent":["import type { JoinQuery, PopulateType, SelectType, Where } from '../../types/index.js'\nimport type { JoinParams } from '../sanitizeJoinParams.js'\n\nimport { isNumber } from '../isNumber.js'\nimport { parseBooleanString } from '../parseBooleanString.js'\nimport { sanitizeJoinParams } from '../sanitizeJoinParams.js'\nimport { sanitizePopulateParam } from '../sanitizePopulateParam.js'\nimport { sanitizeSelectParam } from '../sanitizeSelectParam.js'\nimport { sanitizeSortParams } from '../sanitizeSortParams.js'\n\nexport type RawParams = {\n [key: string]: unknown\n autosave?: string\n data?: string\n depth?: string\n draft?: string\n field?: string\n flattenLocales?: string\n joins?: JoinParams\n limit?: string\n overrideLock?: string\n page?: string\n pagination?: string\n populate?: unknown\n publishAllLocales?: string\n select?: unknown\n selectedLocales?: string\n sort?: string | string[]\n trash?: string\n unpublishAllLocales?: string\n where?: string | Where\n}\n\nexport type ParsedParams = {\n autosave?: boolean\n data?: Record<string, unknown>\n depth?: number\n draft?: boolean\n field?: string\n flattenLocales?: boolean\n joins?: JoinQuery\n limit?: number\n overrideLock?: boolean\n page?: number\n pagination?: boolean\n populate?: PopulateType\n publishAllLocales?: boolean\n select?: SelectType\n selectedLocales?: string[]\n sort?: string[]\n trash?: boolean\n unpublishAllLocales?: boolean\n where?: Where\n} & Record<string, unknown>\n\nexport const booleanParams = [\n 'autosave',\n 'draft',\n 'trash',\n 'overrideLock',\n 'pagination',\n 'flattenLocales',\n 'publishAllLocales',\n 'unpublishAllLocales',\n]\n\nexport const numberParams = ['depth', 'limit', 'page']\n\n/**\n * Takes raw query parameters and parses them into the correct types that Payload expects.\n * Examples:\n * a. `draft` provided as a string of \"true\" is converted to a boolean\n * b. `depth` provided as a string of \"0\" is converted to a number\n * c. `sort` provided as a comma-separated string or array is converted to an array of strings\n */\nexport const parseParams = (params: RawParams): ParsedParams => {\n const parsedParams = (params || {}) as ParsedParams\n\n // iterate through known params to make this very fast\n for (const key of booleanParams) {\n if (key in params) {\n parsedParams[key] = parseBooleanString(params[key] as boolean | string)\n }\n }\n\n for (const key of numberParams) {\n if (key in params) {\n if (isNumber(params[key])) {\n parsedParams[key] = Number(params[key])\n }\n }\n }\n\n if ('populate' in params) {\n parsedParams.populate = sanitizePopulateParam(params.populate)\n }\n\n if ('select' in params) {\n parsedParams.select = sanitizeSelectParam(params.select)\n }\n\n if ('joins' in params) {\n parsedParams.joins = sanitizeJoinParams(params.joins
|
|
1
|
+
{"version":3,"sources":["../../../src/utilities/parseParams/index.ts"],"sourcesContent":["import type { JoinQuery, PopulateType, SelectType, Where } from '../../types/index.js'\nimport type { JoinParams } from '../sanitizeJoinParams.js'\n\nimport { isNumber } from '../isNumber.js'\nimport { parseBooleanString } from '../parseBooleanString.js'\nimport { sanitizeJoinParams } from '../sanitizeJoinParams.js'\nimport { sanitizePopulateParam } from '../sanitizePopulateParam.js'\nimport { sanitizeSelectParam } from '../sanitizeSelectParam.js'\nimport { sanitizeSortParams } from '../sanitizeSortParams.js'\n\nexport type RawParams = {\n [key: string]: unknown\n autosave?: string\n data?: string\n depth?: string\n draft?: string\n field?: string\n flattenLocales?: string\n joins?: JoinParams\n limit?: string\n overrideLock?: string\n page?: string\n pagination?: string\n populate?: unknown\n publishAllLocales?: string\n select?: unknown\n selectedLocales?: string\n sort?: string | string[]\n trash?: string\n unpublishAllLocales?: string\n where?: string | Where\n}\n\nexport type ParsedParams = {\n autosave?: boolean\n data?: Record<string, unknown>\n depth?: number\n draft?: boolean\n field?: string\n flattenLocales?: boolean\n joins?: JoinQuery\n limit?: number\n overrideLock?: boolean\n page?: number\n pagination?: boolean\n populate?: PopulateType\n publishAllLocales?: boolean\n select?: SelectType\n selectedLocales?: string[]\n sort?: string[]\n trash?: boolean\n unpublishAllLocales?: boolean\n where?: Where\n} & Record<string, unknown>\n\nexport const booleanParams = [\n 'autosave',\n 'draft',\n 'trash',\n 'overrideLock',\n 'pagination',\n 'flattenLocales',\n 'publishAllLocales',\n 'unpublishAllLocales',\n]\n\nexport const numberParams = ['depth', 'limit', 'page']\n\n/**\n * Takes raw query parameters and parses them into the correct types that Payload expects.\n * Examples:\n * a. `draft` provided as a string of \"true\" is converted to a boolean\n * b. `depth` provided as a string of \"0\" is converted to a number\n * c. `sort` provided as a comma-separated string or array is converted to an array of strings\n */\nexport const parseParams = (params: RawParams): ParsedParams => {\n const parsedParams = (params || {}) as ParsedParams\n\n // iterate through known params to make this very fast\n for (const key of booleanParams) {\n if (key in params) {\n parsedParams[key] = parseBooleanString(params[key] as boolean | string)\n }\n }\n\n for (const key of numberParams) {\n if (key in params) {\n if (isNumber(params[key])) {\n parsedParams[key] = Number(params[key])\n }\n }\n }\n\n if ('populate' in params) {\n parsedParams.populate = sanitizePopulateParam(params.populate)\n }\n\n if ('select' in params) {\n parsedParams.select = sanitizeSelectParam(params.select)\n }\n\n if ('joins' in params) {\n parsedParams.joins = sanitizeJoinParams(params.joins)\n }\n\n if ('sort' in params) {\n parsedParams.sort = sanitizeSortParams(params.sort)\n }\n\n if ('data' in params && typeof params.data === 'string' && params.data.length > 0) {\n parsedParams.data = JSON.parse(params.data)\n }\n\n if ('where' in params && typeof params.where === 'string' && params.where.length > 0) {\n parsedParams.where = JSON.parse(params.where) as Where\n }\n\n return parsedParams\n}\n"],"names":["isNumber","parseBooleanString","sanitizeJoinParams","sanitizePopulateParam","sanitizeSelectParam","sanitizeSortParams","booleanParams","numberParams","parseParams","params","parsedParams","key","Number","populate","select","joins","sort","data","length","JSON","parse","where"],"mappings":"AAGA,SAASA,QAAQ,QAAQ,iBAAgB;AACzC,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,kBAAkB,QAAQ,2BAA0B;AAC7D,SAASC,qBAAqB,QAAQ,8BAA6B;AACnE,SAASC,mBAAmB,QAAQ,4BAA2B;AAC/D,SAASC,kBAAkB,QAAQ,2BAA0B;AA+C7D,OAAO,MAAMC,gBAAgB;IAC3B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,CAAA;AAED,OAAO,MAAMC,eAAe;IAAC;IAAS;IAAS;CAAO,CAAA;AAEtD;;;;;;CAMC,GACD,OAAO,MAAMC,cAAc,CAACC;IAC1B,MAAMC,eAAgBD,UAAU,CAAC;IAEjC,sDAAsD;IACtD,KAAK,MAAME,OAAOL,cAAe;QAC/B,IAAIK,OAAOF,QAAQ;YACjBC,YAAY,CAACC,IAAI,GAAGV,mBAAmBQ,MAAM,CAACE,IAAI;QACpD;IACF;IAEA,KAAK,MAAMA,OAAOJ,aAAc;QAC9B,IAAII,OAAOF,QAAQ;YACjB,IAAIT,SAASS,MAAM,CAACE,IAAI,GAAG;gBACzBD,YAAY,CAACC,IAAI,GAAGC,OAAOH,MAAM,CAACE,IAAI;YACxC;QACF;IACF;IAEA,IAAI,cAAcF,QAAQ;QACxBC,aAAaG,QAAQ,GAAGV,sBAAsBM,OAAOI,QAAQ;IAC/D;IAEA,IAAI,YAAYJ,QAAQ;QACtBC,aAAaI,MAAM,GAAGV,oBAAoBK,OAAOK,MAAM;IACzD;IAEA,IAAI,WAAWL,QAAQ;QACrBC,aAAaK,KAAK,GAAGb,mBAAmBO,OAAOM,KAAK;IACtD;IAEA,IAAI,UAAUN,QAAQ;QACpBC,aAAaM,IAAI,GAAGX,mBAAmBI,OAAOO,IAAI;IACpD;IAEA,IAAI,UAAUP,UAAU,OAAOA,OAAOQ,IAAI,KAAK,YAAYR,OAAOQ,IAAI,CAACC,MAAM,GAAG,GAAG;QACjFR,aAAaO,IAAI,GAAGE,KAAKC,KAAK,CAACX,OAAOQ,IAAI;IAC5C;IAEA,IAAI,WAAWR,UAAU,OAAOA,OAAOY,KAAK,KAAK,YAAYZ,OAAOY,KAAK,CAACH,MAAM,GAAG,GAAG;QACpFR,aAAaW,KAAK,GAAGF,KAAKC,KAAK,CAACX,OAAOY,KAAK;IAC9C;IAEA,OAAOX;AACT,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/parseValidationLocale.ts"],"sourcesContent":["import type { TypedLocale } from '../index.js'\nimport type { ValidationLocaleSelector } from './resolveValidationLocales.js'\n\nimport { APIError } from '../errors/index.js'\nimport { httpStatus } from './httpStatus.js'\n\n/**\n * Parses a REST `locale` query value. Repeated query parameters are represented as an array and\n * `locale=all` selects all locales.\n */\nexport function parseValidationLocaleSelector(locale: unknown): ValidationLocaleSelector {\n if (typeof locale === 'string') {\n if (locale.length === 0) {\n throw new APIError('Validation requires a locale.', httpStatus.BAD_REQUEST)\n }\n\n if (locale === 'all') {\n return 'all'\n }\n\n return locale
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/parseValidationLocale.ts"],"sourcesContent":["import type { TypedLocale } from '../index.js'\nimport type { ValidationLocaleSelector } from './resolveValidationLocales.js'\n\nimport { APIError } from '../errors/index.js'\nimport { httpStatus } from './httpStatus.js'\n\n/**\n * Parses a REST `locale` query value. Repeated query parameters are represented as an array and\n * `locale=all` selects all locales.\n */\nexport function parseValidationLocaleSelector(locale: unknown): ValidationLocaleSelector {\n if (typeof locale === 'string') {\n if (locale.length === 0) {\n throw new APIError('Validation requires a locale.', httpStatus.BAD_REQUEST)\n }\n\n if (locale === 'all') {\n return 'all'\n }\n\n return locale\n }\n\n if (\n Array.isArray(locale) &&\n locale.length > 0 &&\n locale.every((value) => typeof value === 'string')\n ) {\n if (locale.some((value) => value.length === 0)) {\n throw new APIError('Validation requires a locale.', httpStatus.BAD_REQUEST)\n }\n\n return locale as [TypedLocale, ...TypedLocale[]]\n }\n\n throw new APIError('Validation requires a locale.', httpStatus.BAD_REQUEST)\n}\n\n/** Ensures a REST validation request body is a non-null JSON object. */\nexport function assertValidationData(data: unknown): asserts data is Record<string, unknown> {\n if (!data || Array.isArray(data) || typeof data !== 'object') {\n throw new APIError('Validation data must be an object.', httpStatus.BAD_REQUEST)\n }\n}\n"],"names":["APIError","httpStatus","parseValidationLocaleSelector","locale","length","BAD_REQUEST","Array","isArray","every","value","some","assertValidationData","data"],"mappings":"AAGA,SAASA,QAAQ,QAAQ,qBAAoB;AAC7C,SAASC,UAAU,QAAQ,kBAAiB;AAE5C;;;CAGC,GACD,OAAO,SAASC,8BAA8BC,MAAe;IAC3D,IAAI,OAAOA,WAAW,UAAU;QAC9B,IAAIA,OAAOC,MAAM,KAAK,GAAG;YACvB,MAAM,IAAIJ,SAAS,iCAAiCC,WAAWI,WAAW;QAC5E;QAEA,IAAIF,WAAW,OAAO;YACpB,OAAO;QACT;QAEA,OAAOA;IACT;IAEA,IACEG,MAAMC,OAAO,CAACJ,WACdA,OAAOC,MAAM,GAAG,KAChBD,OAAOK,KAAK,CAAC,CAACC,QAAU,OAAOA,UAAU,WACzC;QACA,IAAIN,OAAOO,IAAI,CAAC,CAACD,QAAUA,MAAML,MAAM,KAAK,IAAI;YAC9C,MAAM,IAAIJ,SAAS,iCAAiCC,WAAWI,WAAW;QAC5E;QAEA,OAAOF;IACT;IAEA,MAAM,IAAIH,SAAS,iCAAiCC,WAAWI,WAAW;AAC5E;AAEA,sEAAsE,GACtE,OAAO,SAASM,qBAAqBC,IAAa;IAChD,IAAI,CAACA,QAAQN,MAAMC,OAAO,CAACK,SAAS,OAAOA,SAAS,UAAU;QAC5D,MAAM,IAAIZ,SAAS,sCAAsCC,WAAWI,WAAW;IACjF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/sanitizePopulateParam.ts"],"sourcesContent":["import type { PopulateType } from '../types/index.js'\n\nimport { sanitizeSelectParam } from './sanitizeSelectParam.js'\n\n/**\n * Sanitizes REST populate query to PopulateType\n */\nexport const sanitizePopulateParam = (unsanitizedPopulate: unknown): PopulateType | undefined => {\n if (!unsanitizedPopulate || typeof unsanitizedPopulate !== 'object') {\n return\n }\n\n for (const k in unsanitizedPopulate) {\n ;(unsanitizedPopulate as Record<string, any>)[k] = sanitizeSelectParam(\n unsanitizedPopulate[k as keyof typeof unsanitizedPopulate],\n )\n }\n\n return unsanitizedPopulate
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/sanitizePopulateParam.ts"],"sourcesContent":["import type { PopulateType } from '../types/index.js'\n\nimport { sanitizeSelectParam } from './sanitizeSelectParam.js'\n\n/**\n * Sanitizes REST populate query to PopulateType\n */\nexport const sanitizePopulateParam = (unsanitizedPopulate: unknown): PopulateType | undefined => {\n if (!unsanitizedPopulate || typeof unsanitizedPopulate !== 'object') {\n return\n }\n\n for (const k in unsanitizedPopulate) {\n ;(unsanitizedPopulate as Record<string, any>)[k] = sanitizeSelectParam(\n unsanitizedPopulate[k as keyof typeof unsanitizedPopulate],\n )\n }\n\n return unsanitizedPopulate\n}\n"],"names":["sanitizeSelectParam","sanitizePopulateParam","unsanitizedPopulate","k"],"mappings":"AAEA,SAASA,mBAAmB,QAAQ,2BAA0B;AAE9D;;CAEC,GACD,OAAO,MAAMC,wBAAwB,CAACC;IACpC,IAAI,CAACA,uBAAuB,OAAOA,wBAAwB,UAAU;QACnE;IACF;IAEA,IAAK,MAAMC,KAAKD,oBAAqB;;QACjCA,mBAA2C,CAACC,EAAE,GAAGH,oBACjDE,mBAAmB,CAACC,EAAsC;IAE9D;IAEA,OAAOD;AACT,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/utilities/telemetry/featureInfo/getFeatureInfo.ts"],"sourcesContent":["import type { SanitizedConfig } from '../../../config/types.js'\nimport type { IncomingDrafts } from '../../../versions/types.js'\nimport type { FeatureInfo, RichTextFeature } from './types.js'\n\nimport { defaultUserCollection } from '../../../auth/defaultUser.js'\nimport { isUserMenuSettingsGroup } from '../../../config/types.js'\n\nexport const getFeatureInfo = (config: SanitizedConfig): FeatureInfo => {\n const telemetryConfig = sanitizeTelemetryConfig(config)\n\n return Object.assign(\n {},\n ...[\n collectAdminCustomization,\n collectAuthentication,\n collectBasicDenominators,\n collectHierarchy,\n collectI18n,\n collectJobsAndQueues,\n collectOrdering,\n collectPreviewAndLivePreview,\n collectQueryPresets,\n collectTrash,\n collectUploadAndMedia,\n collectVersionsAndDrafts,\n collectRichTextFeatures,\n ].map((collect) => safelyCollect(() => collect(telemetryConfig))),\n )\n}\n\nconst safelyCollect = (collect: () => FeatureInfo): FeatureInfo => {\n try {\n return collect()\n } catch (_) {\n return {}\n }\n}\n\n// sanitization adds 4 system widgets that we need to account for\nconst SYSTEM_WIDGET_COUNT = 4\nconst SYSTEM_COLLECTION_SLUGS = [\n 'payload-llm-instructions',\n 'payload-locked-documents',\n 'payload-migrations',\n 'payload-preferences',\n 'payload-query-presets',\n]\nconst SYSTEM_GLOBAL_SLUGS = new Set(['payload-jobs-stats'])\n\n/**\n * Payload adds internal collections, globals and tasks during config sanitization.\n * Remove them from the telemetry view so feature metrics represent user config.\n */\nconst sanitizeTelemetryConfig = (config: SanitizedConfig): SanitizedConfig => {\n try {\n const collections = config.collections ?? []\n const systemCollectionSlugs = new Set(SYSTEM_COLLECTION_SLUGS)\n const kvCollectionSlug = config.kv?.kvCollection?.slug\n\n if (kvCollectionSlug) {\n systemCollectionSlugs.add(kvCollectionSlug)\n }\n\n if (config.jobs?.enabled) {\n // uses SYSTEM_COLLECTION_SLUGS (not the Set) to exclude kv slug from position detection\n const firstCollectionAfterJobs = collections.findIndex(({ slug }) =>\n SYSTEM_COLLECTION_SLUGS.includes(slug),\n )\n\n if (firstCollectionAfterJobs > 0) {\n systemCollectionSlugs.add(collections[firstCollectionAfterJobs - 1]!.slug)\n } else {\n systemCollectionSlugs.add('payload-jobs')\n }\n }\n\n const tasks = [...(config.jobs?.tasks ?? [])]\n\n if (getDraftEntities(config).some(hasScheduledPublishing)) {\n for (let index = tasks.length - 1; index >= 0; index--) {\n if (tasks[index]?.slug === 'schedulePublish') {\n tasks.splice(index, 1)\n break\n }\n }\n }\n\n return {\n ...config,\n collections: collections.filter(\n (collection) =>\n collection !== defaultUserCollection && !systemCollectionSlugs.has(collection.slug),\n ),\n globals: (config.globals ?? []).filter(({ slug }) => !SYSTEM_GLOBAL_SLUGS.has(slug)),\n jobs: {\n ...config.jobs,\n tasks,\n },\n }\n } catch (_) {\n return config\n }\n}\n\nconst collectAdminCustomization = (config: SanitizedConfig): FeatureInfo => ({\n adminCustomization: {\n customAdminComponentCount: countRootAdminComponents(config),\n customAdminViewCount: Object.keys(config.admin?.components?.views ?? {}).length,\n customDashboardWidgetCount: Math.max(\n 0,\n (config.admin?.dashboard?.widgets?.length ?? 0) - SYSTEM_WIDGET_COUNT,\n ),\n },\n})\n\nconst collectAuthentication = (config: SanitizedConfig): FeatureInfo => {\n const authCollections = (config.collections ?? []).filter(({ auth }) => Boolean(auth))\n\n return {\n authentication: {\n apiKeyCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.useAPIKey),\n ).length,\n authCollectionCount: authCollections.length,\n customAuthStrategyCount: authCollections.reduce(\n (count, { auth }) =>\n count + (isObject(auth) && Array.isArray(auth.strategies) ? auth.strategies.length : 0),\n 0,\n ),\n localAuthDisabledCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.disableLocalStrategy),\n ).length,\n sessionsDisabledCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && auth.useSessions === false,\n ).length,\n usernameCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.loginWithUsername),\n ).length,\n verifiedCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.verify),\n ).length,\n },\n }\n}\n\nconst collectBasicDenominators = (config: SanitizedConfig): FeatureInfo => ({\n basicDenominators: {\n collectionCount: config.collections?.length ?? 0,\n globalCount: config.globals?.length ?? 0,\n },\n})\n\nconst collectHierarchy = (config: SanitizedConfig): FeatureInfo => ({\n hierarchyCollectionCount: (config.collections ?? []).filter(({ hierarchy }) => Boolean(hierarchy))\n .length,\n})\n\nconst collectI18n = (config: SanitizedConfig): FeatureInfo => ({\n i18n: {\n hasCustomAdminTranslations: Object.keys(config.i18n?.translations ?? {}).length > 0,\n supportedAdminLanguageCount: config.i18n?.supportedLanguages\n ? Object.keys(config.i18n.supportedLanguages).length\n : 1,\n },\n})\n\nconst collectJobsAndQueues = (config: SanitizedConfig): FeatureInfo => {\n const tasks = Array.isArray(config.jobs?.tasks) ? config.jobs.tasks : []\n const workflows = Array.isArray(config.jobs?.workflows) ? config.jobs.workflows : []\n const tasksAndWorkflows = [...tasks, ...workflows]\n const scheduledPublishingEntityCount =\n getDraftEntities(config).filter(hasScheduledPublishing).length\n\n return {\n jobsAndQueues: {\n jobsAutoRunConfigured: config.jobs?.autoRun !== undefined,\n jobsConcurrencyEnabled: tasksAndWorkflows.some(({ concurrency }) => Boolean(concurrency)),\n jobsEnabled: tasks.length > 0 || workflows.length > 0 || scheduledPublishingEntityCount > 0,\n jobsSchedulingEnabled: tasksAndWorkflows.some(({ schedule }) => Boolean(schedule)),\n taskCount: tasks.length,\n workflowCount: workflows.length,\n },\n }\n}\n\nconst collectOrdering = (config: SanitizedConfig): FeatureInfo => ({\n orderableCollectionCount: (config.collections ?? []).filter(({ orderable }) => Boolean(orderable))\n .length,\n})\n\nconst collectPreviewAndLivePreview = (config: SanitizedConfig): FeatureInfo => {\n const collections = config.collections ?? []\n const globals = config.globals ?? []\n const livePreviewCollections = new Set([\n ...(config.admin?.livePreview?.collections ?? []),\n ...collections.filter((c) => c.admin?.livePreview).map((c) => c.slug),\n ])\n const livePreviewGlobals = new Set([\n ...(config.admin?.livePreview?.globals ?? []),\n ...globals.filter((g) => g.admin?.livePreview).map((g) => g.slug),\n ])\n\n return {\n previewAndLivePreview: {\n livePreviewCollectionCount: collections.filter(({ slug }) => livePreviewCollections.has(slug))\n .length,\n livePreviewGlobalCount: globals.filter(({ slug }) => livePreviewGlobals.has(slug)).length,\n previewCollectionCount: collections.filter(({ admin }) => Boolean(admin?.preview)).length,\n previewGlobalCount: globals.filter(({ admin }) => Boolean(admin?.preview)).length,\n },\n }\n}\n\nconst collectQueryPresets = (config: SanitizedConfig): FeatureInfo => ({\n queryPresetCollectionCount: (config.collections ?? []).filter(({ enableQueryPresets }) =>\n Boolean(enableQueryPresets),\n ).length,\n})\n\nconst collectRichTextFeatures = (config: SanitizedConfig): FeatureInfo => {\n const editor: unknown = config.editor\n const features =\n isObject(editor) && isObject(editor.editorConfig) ? editor.editorConfig.features : undefined\n const raw =\n isObject(features) && Array.isArray(features.enabledFeatures) ? features.enabledFeatures : []\n const featureSet = new Set(raw.filter((f): f is string => typeof f === 'string'))\n // per-field editor overrides are not checked; root editor covers the vast majority of projects\n return {\n richTextFeatures: (['blocks', 'table', 'upload', 'relationship'] as const).filter((f) =>\n featureSet.has(f),\n ) as RichTextFeature[],\n }\n}\n\nconst collectTrash = (config: SanitizedConfig): FeatureInfo => ({\n trashCollectionCount: (config.collections ?? []).filter(({ trash }) => Boolean(trash)).length,\n})\n\nconst collectUploadAndMedia = (config: SanitizedConfig): FeatureInfo => {\n const collections = config.collections ?? []\n\n return {\n uploadAndMedia: {\n cropDisabledCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && upload.crop === false,\n ).length,\n focalPointDisabledCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && upload.focalPoint === false,\n ).length,\n imageSizesCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && Boolean(upload.variants?.length),\n ).length,\n mimeRestrictedCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && Boolean(upload.mimeTypes?.length),\n ).length,\n uploadCollectionCount: collections.filter(({ upload }) => Boolean(upload)).length,\n },\n }\n}\n\nconst collectVersionsAndDrafts = (config: SanitizedConfig): FeatureInfo => {\n const collections = config.collections ?? []\n const globals = config.globals ?? []\n const draftCollections = collections.filter(hasDrafts)\n const draftGlobals = globals.filter(hasDrafts)\n const draftEntities = [...draftCollections, ...draftGlobals]\n\n return {\n versionsAndDrafts: {\n autosaveEntityCount: draftEntities.filter(hasAutosave).length,\n draftCollectionCount: draftCollections.length,\n draftGlobalCount: draftGlobals.length,\n scheduledPublishingEntityCount: draftEntities.filter(hasScheduledPublishing).length,\n versionsDisabledCollectionCount: collections.filter(({ versions }) => !versions).length,\n versionsDisabledGlobalCount: globals.filter(({ versions }) => !versions).length,\n },\n }\n}\n\nconst getDraftEntities = (config: SanitizedConfig) => [\n ...(config.collections ?? []).filter(hasDrafts),\n ...(config.globals ?? []).filter(hasDrafts),\n]\n\nconst hasDrafts = ({ versions }: { versions?: { drafts?: unknown } | boolean }): boolean =>\n isObject(versions) && Boolean(versions.drafts)\n\nconst getDraftOptions = ({\n versions,\n}: {\n versions?: { drafts?: boolean | IncomingDrafts } | boolean\n}): IncomingDrafts | undefined =>\n isObject(versions) && isObject(versions.drafts) ? versions.drafts : undefined\n\nconst hasAutosave = (entity: Parameters<typeof getDraftOptions>[0]): boolean =>\n Boolean(getDraftOptions(entity)?.autosave)\n\nconst hasScheduledPublishing = (entity: Parameters<typeof getDraftOptions>[0]): boolean =>\n Boolean(getDraftOptions(entity)?.schedulePublish)\n\nconst countRootAdminComponents = (config: SanitizedConfig): number => {\n const admin = config.admin\n const customAvatarCount = Number(\n Boolean(admin?.avatar && typeof admin.avatar === 'object' && admin.avatar.Component),\n )\n const components = admin?.components\n\n if (!components) {\n return customAvatarCount\n }\n\n const componentArrays = [\n components.actions,\n components.afterDashboard,\n components.afterLogin,\n components.afterNav,\n components.afterNavLinks,\n components.beforeDashboard,\n components.beforeLogin,\n components.beforeNav,\n components.beforeNavLinks,\n components.header,\n components.providers,\n components.settingsMenu,\n ]\n const directComponents = [\n components.graphics?.Icon,\n components.graphics?.Logo,\n components.logout?.Button,\n components.Nav,\n ]\n const hierarchyTabSlugs = new Set(\n (config.collections ?? [])\n .filter(({ hierarchy }) => Boolean(hierarchy))\n .map(({ slug }) => `hierarchy-${slug}`),\n )\n const sidebarTabComponentCount =\n components.sidebar?.tabs?.reduce((count, tab) => {\n if (hierarchyTabSlugs.has(tab.slug)) {\n return count\n }\n\n return count + Number(Boolean(tab.components.Content)) + Number(Boolean(tab.components.Icon))\n }, 0) ?? 0\n const userMenuComponentCount =\n components.userMenuSettingsItems?.reduce(\n (count, item) => count + (isUserMenuSettingsGroup(item) ? item.items.length : 1),\n 0,\n ) ?? 0\n\n return (\n customAvatarCount +\n componentArrays.reduce((count, items) => count + (items?.length ?? 0), 0) +\n directComponents.filter(Boolean).length +\n sidebarTabComponentCount +\n userMenuComponentCount\n )\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object'\n"],"names":["defaultUserCollection","isUserMenuSettingsGroup","getFeatureInfo","config","telemetryConfig","sanitizeTelemetryConfig","Object","assign","collectAdminCustomization","collectAuthentication","collectBasicDenominators","collectHierarchy","collectI18n","collectJobsAndQueues","collectOrdering","collectPreviewAndLivePreview","collectQueryPresets","collectTrash","collectUploadAndMedia","collectVersionsAndDrafts","collectRichTextFeatures","map","collect","safelyCollect","_","SYSTEM_WIDGET_COUNT","SYSTEM_COLLECTION_SLUGS","SYSTEM_GLOBAL_SLUGS","Set","collections","systemCollectionSlugs","kvCollectionSlug","kv","kvCollection","slug","add","jobs","enabled","firstCollectionAfterJobs","findIndex","includes","tasks","getDraftEntities","some","hasScheduledPublishing","index","length","splice","filter","collection","has","globals","adminCustomization","customAdminComponentCount","countRootAdminComponents","customAdminViewCount","keys","admin","components","views","customDashboardWidgetCount","Math","max","dashboard","widgets","authCollections","auth","Boolean","authentication","apiKeyCollectionCount","isObject","useAPIKey","authCollectionCount","customAuthStrategyCount","reduce","count","Array","isArray","strategies","localAuthDisabledCollectionCount","disableLocalStrategy","sessionsDisabledCollectionCount","useSessions","usernameCollectionCount","loginWithUsername","verifiedCollectionCount","verify","basicDenominators","collectionCount","globalCount","hierarchyCollectionCount","hierarchy","i18n","hasCustomAdminTranslations","translations","supportedAdminLanguageCount","supportedLanguages","workflows","tasksAndWorkflows","scheduledPublishingEntityCount","jobsAndQueues","jobsAutoRunConfigured","autoRun","undefined","jobsConcurrencyEnabled","concurrency","jobsEnabled","jobsSchedulingEnabled","schedule","taskCount","workflowCount","orderableCollectionCount","orderable","livePreviewCollections","livePreview","c","livePreviewGlobals","g","previewAndLivePreview","livePreviewCollectionCount","livePreviewGlobalCount","previewCollectionCount","preview","previewGlobalCount","queryPresetCollectionCount","enableQueryPresets","editor","features","editorConfig","raw","enabledFeatures","featureSet","f","richTextFeatures","trashCollectionCount","trash","uploadAndMedia","cropDisabledCollectionCount","upload","crop","focalPointDisabledCollectionCount","focalPoint","imageSizesCollectionCount","variants","mimeRestrictedCollectionCount","mimeTypes","uploadCollectionCount","draftCollections","hasDrafts","draftGlobals","draftEntities","versionsAndDrafts","autosaveEntityCount","hasAutosave","draftCollectionCount","draftGlobalCount","versionsDisabledCollectionCount","versions","versionsDisabledGlobalCount","drafts","getDraftOptions","entity","autosave","schedulePublish","customAvatarCount","Number","avatar","Component","componentArrays","actions","afterDashboard","afterLogin","afterNav","afterNavLinks","beforeDashboard","beforeLogin","beforeNav","beforeNavLinks","header","providers","settingsMenu","directComponents","graphics","Icon","Logo","logout","Button","Nav","hierarchyTabSlugs","sidebarTabComponentCount","sidebar","tabs","tab","Content","userMenuComponentCount","userMenuSettingsItems","item","items","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/utilities/telemetry/featureInfo/getFeatureInfo.ts"],"sourcesContent":["import type { SanitizedConfig } from '../../../config/types.js'\nimport type { IncomingDrafts } from '../../../versions/types.js'\nimport type { FeatureInfo, RichTextFeature } from './types.js'\n\nimport { defaultUserCollection } from '../../../auth/defaultUser.js'\nimport { isUserMenuSettingsGroup } from '../../../config/types.js'\n\nexport const getFeatureInfo = (config: SanitizedConfig): FeatureInfo => {\n const telemetryConfig = sanitizeTelemetryConfig(config)\n\n return Object.assign(\n {},\n ...[\n collectAdminCustomization,\n collectAuthentication,\n collectBasicDenominators,\n collectHierarchy,\n collectI18n,\n collectJobsAndQueues,\n collectOrdering,\n collectPreviewAndLivePreview,\n collectQueryPresets,\n collectTrash,\n collectUploadAndMedia,\n collectVersionsAndDrafts,\n collectRichTextFeatures,\n ].map((collect) => safelyCollect(() => collect(telemetryConfig))),\n )\n}\n\nconst safelyCollect = (collect: () => FeatureInfo): FeatureInfo => {\n try {\n return collect()\n } catch (_) {\n return {}\n }\n}\n\n// sanitization adds 4 system widgets that we need to account for\nconst SYSTEM_WIDGET_COUNT = 4\nconst SYSTEM_COLLECTION_SLUGS = [\n 'payload-llm-instructions',\n 'payload-locked-documents',\n 'payload-migrations',\n 'payload-preferences',\n 'payload-query-presets',\n]\nconst SYSTEM_GLOBAL_SLUGS = new Set(['payload-jobs-stats'])\n\n/**\n * Payload adds internal collections, globals and tasks during config sanitization.\n * Remove them from the telemetry view so feature metrics represent user config.\n */\nconst sanitizeTelemetryConfig = (config: SanitizedConfig): SanitizedConfig => {\n try {\n const collections = config.collections ?? []\n const systemCollectionSlugs = new Set(SYSTEM_COLLECTION_SLUGS)\n const kvCollectionSlug = config.kv?.kvCollection?.slug\n\n if (kvCollectionSlug) {\n systemCollectionSlugs.add(kvCollectionSlug)\n }\n\n if (config.jobs?.enabled) {\n // uses SYSTEM_COLLECTION_SLUGS (not the Set) to exclude kv slug from position detection\n const firstCollectionAfterJobs = collections.findIndex(({ slug }) =>\n SYSTEM_COLLECTION_SLUGS.includes(slug),\n )\n\n if (firstCollectionAfterJobs > 0) {\n systemCollectionSlugs.add(collections[firstCollectionAfterJobs - 1]!.slug)\n } else {\n systemCollectionSlugs.add('payload-jobs')\n }\n }\n\n const tasks = [...(config.jobs?.tasks ?? [])]\n\n if (getDraftEntities(config).some(hasScheduledPublishing)) {\n for (let index = tasks.length - 1; index >= 0; index--) {\n if (tasks[index]?.slug === 'schedulePublish') {\n tasks.splice(index, 1)\n break\n }\n }\n }\n\n return {\n ...config,\n collections: collections.filter(\n (collection) =>\n collection !== defaultUserCollection && !systemCollectionSlugs.has(collection.slug),\n ),\n globals: (config.globals ?? []).filter(({ slug }) => !SYSTEM_GLOBAL_SLUGS.has(slug)),\n jobs: {\n ...config.jobs,\n tasks,\n },\n }\n } catch (_) {\n return config\n }\n}\n\nconst collectAdminCustomization = (config: SanitizedConfig): FeatureInfo => ({\n adminCustomization: {\n customAdminComponentCount: countRootAdminComponents(config),\n customAdminViewCount: Object.keys(config.admin?.components?.views ?? {}).length,\n customDashboardWidgetCount: Math.max(\n 0,\n (config.admin?.dashboard?.widgets?.length ?? 0) - SYSTEM_WIDGET_COUNT,\n ),\n },\n})\n\nconst collectAuthentication = (config: SanitizedConfig): FeatureInfo => {\n const authCollections = (config.collections ?? []).filter(({ auth }) => Boolean(auth))\n\n return {\n authentication: {\n apiKeyCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.useAPIKey),\n ).length,\n authCollectionCount: authCollections.length,\n customAuthStrategyCount: authCollections.reduce(\n (count, { auth }) =>\n count + (isObject(auth) && Array.isArray(auth.strategies) ? auth.strategies.length : 0),\n 0,\n ),\n localAuthDisabledCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.disableLocalStrategy),\n ).length,\n sessionsDisabledCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && auth.useSessions === false,\n ).length,\n usernameCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.loginWithUsername),\n ).length,\n verifiedCollectionCount: authCollections.filter(\n ({ auth }) => isObject(auth) && Boolean(auth.verify),\n ).length,\n },\n }\n}\n\nconst collectBasicDenominators = (config: SanitizedConfig): FeatureInfo => ({\n basicDenominators: {\n collectionCount: config.collections?.length ?? 0,\n globalCount: config.globals?.length ?? 0,\n },\n})\n\nconst collectHierarchy = (config: SanitizedConfig): FeatureInfo => ({\n hierarchyCollectionCount: (config.collections ?? []).filter(({ hierarchy }) => Boolean(hierarchy))\n .length,\n})\n\nconst collectI18n = (config: SanitizedConfig): FeatureInfo => ({\n i18n: {\n hasCustomAdminTranslations: Object.keys(config.i18n?.translations ?? {}).length > 0,\n supportedAdminLanguageCount: config.i18n?.supportedLanguages\n ? Object.keys(config.i18n.supportedLanguages).length\n : 1,\n },\n})\n\nconst collectJobsAndQueues = (config: SanitizedConfig): FeatureInfo => {\n const tasks = Array.isArray(config.jobs?.tasks) ? config.jobs.tasks : []\n const workflows = Array.isArray(config.jobs?.workflows) ? config.jobs.workflows : []\n const tasksAndWorkflows = [...tasks, ...workflows]\n const scheduledPublishingEntityCount =\n getDraftEntities(config).filter(hasScheduledPublishing).length\n\n return {\n jobsAndQueues: {\n jobsAutoRunConfigured: config.jobs?.autoRun !== undefined,\n jobsConcurrencyEnabled: tasksAndWorkflows.some(({ concurrency }) => Boolean(concurrency)),\n jobsEnabled: tasks.length > 0 || workflows.length > 0 || scheduledPublishingEntityCount > 0,\n jobsSchedulingEnabled: tasksAndWorkflows.some(({ schedule }) => Boolean(schedule)),\n taskCount: tasks.length,\n workflowCount: workflows.length,\n },\n }\n}\n\nconst collectOrdering = (config: SanitizedConfig): FeatureInfo => ({\n orderableCollectionCount: (config.collections ?? []).filter(({ orderable }) => Boolean(orderable))\n .length,\n})\n\nconst collectPreviewAndLivePreview = (config: SanitizedConfig): FeatureInfo => {\n const collections = config.collections ?? []\n const globals = config.globals ?? []\n const livePreviewCollections = new Set([\n ...(config.admin?.livePreview?.collections ?? []),\n ...collections.filter((c) => c.admin?.livePreview).map((c) => c.slug),\n ])\n const livePreviewGlobals = new Set([\n ...(config.admin?.livePreview?.globals ?? []),\n ...globals.filter((g) => g.admin?.livePreview).map((g) => g.slug),\n ])\n\n return {\n previewAndLivePreview: {\n livePreviewCollectionCount: collections.filter(({ slug }) => livePreviewCollections.has(slug))\n .length,\n livePreviewGlobalCount: globals.filter(({ slug }) => livePreviewGlobals.has(slug)).length,\n previewCollectionCount: collections.filter(({ admin }) => Boolean(admin?.preview)).length,\n previewGlobalCount: globals.filter(({ admin }) => Boolean(admin?.preview)).length,\n },\n }\n}\n\nconst collectQueryPresets = (config: SanitizedConfig): FeatureInfo => ({\n queryPresetCollectionCount: (config.collections ?? []).filter(({ enableQueryPresets }) =>\n Boolean(enableQueryPresets),\n ).length,\n})\n\nconst collectRichTextFeatures = (config: SanitizedConfig): FeatureInfo => {\n const editor: unknown = config.editor\n const features =\n isObject(editor) && isObject(editor.editorConfig) ? editor.editorConfig.features : undefined\n const raw =\n isObject(features) && Array.isArray(features.enabledFeatures) ? features.enabledFeatures : []\n const featureSet = new Set(raw.filter((f): f is string => typeof f === 'string'))\n // per-field editor overrides are not checked; root editor covers the vast majority of projects\n return {\n richTextFeatures: (['blocks', 'table', 'upload', 'relationship'] as const).filter((f) =>\n featureSet.has(f),\n ),\n }\n}\n\nconst collectTrash = (config: SanitizedConfig): FeatureInfo => ({\n trashCollectionCount: (config.collections ?? []).filter(({ trash }) => Boolean(trash)).length,\n})\n\nconst collectUploadAndMedia = (config: SanitizedConfig): FeatureInfo => {\n const collections = config.collections ?? []\n\n return {\n uploadAndMedia: {\n cropDisabledCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && upload.crop === false,\n ).length,\n focalPointDisabledCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && upload.focalPoint === false,\n ).length,\n imageSizesCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && Boolean(upload.variants?.length),\n ).length,\n mimeRestrictedCollectionCount: collections.filter(\n ({ upload }) => isObject(upload) && Boolean(upload.mimeTypes?.length),\n ).length,\n uploadCollectionCount: collections.filter(({ upload }) => Boolean(upload)).length,\n },\n }\n}\n\nconst collectVersionsAndDrafts = (config: SanitizedConfig): FeatureInfo => {\n const collections = config.collections ?? []\n const globals = config.globals ?? []\n const draftCollections = collections.filter(hasDrafts)\n const draftGlobals = globals.filter(hasDrafts)\n const draftEntities = [...draftCollections, ...draftGlobals]\n\n return {\n versionsAndDrafts: {\n autosaveEntityCount: draftEntities.filter(hasAutosave).length,\n draftCollectionCount: draftCollections.length,\n draftGlobalCount: draftGlobals.length,\n scheduledPublishingEntityCount: draftEntities.filter(hasScheduledPublishing).length,\n versionsDisabledCollectionCount: collections.filter(({ versions }) => !versions).length,\n versionsDisabledGlobalCount: globals.filter(({ versions }) => !versions).length,\n },\n }\n}\n\nconst getDraftEntities = (config: SanitizedConfig) => [\n ...(config.collections ?? []).filter(hasDrafts),\n ...(config.globals ?? []).filter(hasDrafts),\n]\n\nconst hasDrafts = ({ versions }: { versions?: { drafts?: unknown } | boolean }): boolean =>\n isObject(versions) && Boolean(versions.drafts)\n\nconst getDraftOptions = ({\n versions,\n}: {\n versions?: { drafts?: boolean | IncomingDrafts } | boolean\n}): IncomingDrafts | undefined =>\n isObject(versions) && isObject(versions.drafts) ? versions.drafts : undefined\n\nconst hasAutosave = (entity: Parameters<typeof getDraftOptions>[0]): boolean =>\n Boolean(getDraftOptions(entity)?.autosave)\n\nconst hasScheduledPublishing = (entity: Parameters<typeof getDraftOptions>[0]): boolean =>\n Boolean(getDraftOptions(entity)?.schedulePublish)\n\nconst countRootAdminComponents = (config: SanitizedConfig): number => {\n const admin = config.admin\n const customAvatarCount = Number(\n Boolean(admin?.avatar && typeof admin.avatar === 'object' && admin.avatar.Component),\n )\n const components = admin?.components\n\n if (!components) {\n return customAvatarCount\n }\n\n const componentArrays = [\n components.actions,\n components.afterDashboard,\n components.afterLogin,\n components.afterNav,\n components.afterNavLinks,\n components.beforeDashboard,\n components.beforeLogin,\n components.beforeNav,\n components.beforeNavLinks,\n components.header,\n components.providers,\n components.settingsMenu,\n ]\n const directComponents = [\n components.graphics?.Icon,\n components.graphics?.Logo,\n components.logout?.Button,\n components.Nav,\n ]\n const hierarchyTabSlugs = new Set(\n (config.collections ?? [])\n .filter(({ hierarchy }) => Boolean(hierarchy))\n .map(({ slug }) => `hierarchy-${slug}`),\n )\n const sidebarTabComponentCount =\n components.sidebar?.tabs?.reduce((count, tab) => {\n if (hierarchyTabSlugs.has(tab.slug)) {\n return count\n }\n\n return count + Number(Boolean(tab.components.Content)) + Number(Boolean(tab.components.Icon))\n }, 0) ?? 0\n const userMenuComponentCount =\n components.userMenuSettingsItems?.reduce(\n (count, item) => count + (isUserMenuSettingsGroup(item) ? item.items.length : 1),\n 0,\n ) ?? 0\n\n return (\n customAvatarCount +\n componentArrays.reduce((count, items) => count + (items?.length ?? 0), 0) +\n directComponents.filter(Boolean).length +\n sidebarTabComponentCount +\n userMenuComponentCount\n )\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object'\n"],"names":["defaultUserCollection","isUserMenuSettingsGroup","getFeatureInfo","config","telemetryConfig","sanitizeTelemetryConfig","Object","assign","collectAdminCustomization","collectAuthentication","collectBasicDenominators","collectHierarchy","collectI18n","collectJobsAndQueues","collectOrdering","collectPreviewAndLivePreview","collectQueryPresets","collectTrash","collectUploadAndMedia","collectVersionsAndDrafts","collectRichTextFeatures","map","collect","safelyCollect","_","SYSTEM_WIDGET_COUNT","SYSTEM_COLLECTION_SLUGS","SYSTEM_GLOBAL_SLUGS","Set","collections","systemCollectionSlugs","kvCollectionSlug","kv","kvCollection","slug","add","jobs","enabled","firstCollectionAfterJobs","findIndex","includes","tasks","getDraftEntities","some","hasScheduledPublishing","index","length","splice","filter","collection","has","globals","adminCustomization","customAdminComponentCount","countRootAdminComponents","customAdminViewCount","keys","admin","components","views","customDashboardWidgetCount","Math","max","dashboard","widgets","authCollections","auth","Boolean","authentication","apiKeyCollectionCount","isObject","useAPIKey","authCollectionCount","customAuthStrategyCount","reduce","count","Array","isArray","strategies","localAuthDisabledCollectionCount","disableLocalStrategy","sessionsDisabledCollectionCount","useSessions","usernameCollectionCount","loginWithUsername","verifiedCollectionCount","verify","basicDenominators","collectionCount","globalCount","hierarchyCollectionCount","hierarchy","i18n","hasCustomAdminTranslations","translations","supportedAdminLanguageCount","supportedLanguages","workflows","tasksAndWorkflows","scheduledPublishingEntityCount","jobsAndQueues","jobsAutoRunConfigured","autoRun","undefined","jobsConcurrencyEnabled","concurrency","jobsEnabled","jobsSchedulingEnabled","schedule","taskCount","workflowCount","orderableCollectionCount","orderable","livePreviewCollections","livePreview","c","livePreviewGlobals","g","previewAndLivePreview","livePreviewCollectionCount","livePreviewGlobalCount","previewCollectionCount","preview","previewGlobalCount","queryPresetCollectionCount","enableQueryPresets","editor","features","editorConfig","raw","enabledFeatures","featureSet","f","richTextFeatures","trashCollectionCount","trash","uploadAndMedia","cropDisabledCollectionCount","upload","crop","focalPointDisabledCollectionCount","focalPoint","imageSizesCollectionCount","variants","mimeRestrictedCollectionCount","mimeTypes","uploadCollectionCount","draftCollections","hasDrafts","draftGlobals","draftEntities","versionsAndDrafts","autosaveEntityCount","hasAutosave","draftCollectionCount","draftGlobalCount","versionsDisabledCollectionCount","versions","versionsDisabledGlobalCount","drafts","getDraftOptions","entity","autosave","schedulePublish","customAvatarCount","Number","avatar","Component","componentArrays","actions","afterDashboard","afterLogin","afterNav","afterNavLinks","beforeDashboard","beforeLogin","beforeNav","beforeNavLinks","header","providers","settingsMenu","directComponents","graphics","Icon","Logo","logout","Button","Nav","hierarchyTabSlugs","sidebarTabComponentCount","sidebar","tabs","tab","Content","userMenuComponentCount","userMenuSettingsItems","item","items","value"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/versions/allLocalesPublicationStatus.ts"],"sourcesContent":["import type { JsonObject } from '../types/index.js'\n\nimport { APIError } from '../errors/index.js'\nimport { httpStatus } from '../utilities/httpStatus.js'\n\nexport type AllLocalesPublicationStatus = 'draft' | 'published'\n\ntype AllLocalesPublicationIntent = {\n hadStatus: boolean\n previousStatus: unknown\n status: AllLocalesPublicationStatus\n}\n\nexport const buildAllLocalesPublicationHookDoc = <TDoc extends JsonObject>({\n doc,\n docWithLocales,\n status,\n}: {\n doc: TDoc\n docWithLocales: JsonObject\n status: AllLocalesPublicationStatus | undefined\n}): TDoc => {\n if (status && typeof docWithLocales._status === 'object' && docWithLocales._status !== null) {\n return {\n ...doc,\n _status: { ...(docWithLocales._status as JsonObject) },\n }
|
|
1
|
+
{"version":3,"sources":["../../src/versions/allLocalesPublicationStatus.ts"],"sourcesContent":["import type { JsonObject } from '../types/index.js'\n\nimport { APIError } from '../errors/index.js'\nimport { httpStatus } from '../utilities/httpStatus.js'\n\nexport type AllLocalesPublicationStatus = 'draft' | 'published'\n\ntype AllLocalesPublicationIntent = {\n hadStatus: boolean\n previousStatus: unknown\n status: AllLocalesPublicationStatus\n}\n\nexport const buildAllLocalesPublicationHookDoc = <TDoc extends JsonObject>({\n doc,\n docWithLocales,\n status,\n}: {\n doc: TDoc\n docWithLocales: JsonObject\n status: AllLocalesPublicationStatus | undefined\n}): TDoc => {\n if (status && typeof docWithLocales._status === 'object' && docWithLocales._status !== null) {\n return {\n ...doc,\n _status: { ...(docWithLocales._status as JsonObject) },\n }\n }\n\n return doc\n}\n\nexport const getAllLocalesPublicationStatus = ({\n hasLocalizedStatus,\n publishAllLocales,\n unpublishAllLocales,\n}: {\n hasLocalizedStatus: boolean\n publishAllLocales: boolean\n unpublishAllLocales: boolean\n}): AllLocalesPublicationStatus | undefined => {\n if (!hasLocalizedStatus) {\n return undefined\n }\n\n if (unpublishAllLocales) {\n return 'draft'\n }\n\n if (publishAllLocales) {\n return 'published'\n }\n\n return undefined\n}\n\nexport const hasAuthorizedAllLocalesPublicationStatus = ({\n data,\n fieldAccessDenied,\n fieldValue,\n status,\n}: {\n data: JsonObject\n fieldAccessDenied: boolean\n fieldValue: unknown\n status: AllLocalesPublicationStatus | undefined\n}): boolean => {\n return Boolean(status && !fieldAccessDenied && data._status === status && fieldValue === status)\n}\n\nexport const normalizeAllLocalesPublicationStatus = ({\n data,\n status,\n}: {\n data: JsonObject\n status: AllLocalesPublicationStatus | undefined\n}): AllLocalesPublicationIntent | undefined => {\n if (!status) {\n return undefined\n }\n\n const intent = {\n hadStatus: Object.prototype.hasOwnProperty.call(data, '_status'),\n previousStatus: data._status,\n status,\n }\n\n data._status = status\n\n return intent\n}\n\nexport const reconcileAllLocalesPublicationStatus = ({\n data,\n intent,\n status,\n}: {\n data: JsonObject\n intent: AllLocalesPublicationIntent | undefined\n status: AllLocalesPublicationStatus | undefined\n}): AllLocalesPublicationStatus | undefined => {\n if (intent && intent.status !== status && data._status === intent.status) {\n if (intent.hadStatus) {\n data._status = intent.previousStatus\n } else {\n delete data._status\n }\n }\n\n return status && data._status === status ? status : undefined\n}\n\nexport const validateAllLocalesPublicationFlags = ({\n publishAllLocales,\n unpublishAllLocales,\n}: {\n publishAllLocales?: boolean\n unpublishAllLocales?: boolean\n}): void => {\n if (publishAllLocales && unpublishAllLocales) {\n throw new APIError(\n 'publishAllLocales and unpublishAllLocales cannot both be true.',\n httpStatus.BAD_REQUEST,\n )\n }\n}\n"],"names":["APIError","httpStatus","buildAllLocalesPublicationHookDoc","doc","docWithLocales","status","_status","getAllLocalesPublicationStatus","hasLocalizedStatus","publishAllLocales","unpublishAllLocales","undefined","hasAuthorizedAllLocalesPublicationStatus","data","fieldAccessDenied","fieldValue","Boolean","normalizeAllLocalesPublicationStatus","intent","hadStatus","Object","prototype","hasOwnProperty","call","previousStatus","reconcileAllLocalesPublicationStatus","validateAllLocalesPublicationFlags","BAD_REQUEST"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,qBAAoB;AAC7C,SAASC,UAAU,QAAQ,6BAA4B;AAUvD,OAAO,MAAMC,oCAAoC,CAA0B,EACzEC,GAAG,EACHC,cAAc,EACdC,MAAM,EAKP;IACC,IAAIA,UAAU,OAAOD,eAAeE,OAAO,KAAK,YAAYF,eAAeE,OAAO,KAAK,MAAM;QAC3F,OAAO;YACL,GAAGH,GAAG;YACNG,SAAS;gBAAE,GAAIF,eAAeE,OAAO;YAAgB;QACvD;IACF;IAEA,OAAOH;AACT,EAAC;AAED,OAAO,MAAMI,iCAAiC,CAAC,EAC7CC,kBAAkB,EAClBC,iBAAiB,EACjBC,mBAAmB,EAKpB;IACC,IAAI,CAACF,oBAAoB;QACvB,OAAOG;IACT;IAEA,IAAID,qBAAqB;QACvB,OAAO;IACT;IAEA,IAAID,mBAAmB;QACrB,OAAO;IACT;IAEA,OAAOE;AACT,EAAC;AAED,OAAO,MAAMC,2CAA2C,CAAC,EACvDC,IAAI,EACJC,iBAAiB,EACjBC,UAAU,EACVV,MAAM,EAMP;IACC,OAAOW,QAAQX,UAAU,CAACS,qBAAqBD,KAAKP,OAAO,KAAKD,UAAUU,eAAeV;AAC3F,EAAC;AAED,OAAO,MAAMY,uCAAuC,CAAC,EACnDJ,IAAI,EACJR,MAAM,EAIP;IACC,IAAI,CAACA,QAAQ;QACX,OAAOM;IACT;IAEA,MAAMO,SAAS;QACbC,WAAWC,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACV,MAAM;QACtDW,gBAAgBX,KAAKP,OAAO;QAC5BD;IACF;IAEAQ,KAAKP,OAAO,GAAGD;IAEf,OAAOa;AACT,EAAC;AAED,OAAO,MAAMO,uCAAuC,CAAC,EACnDZ,IAAI,EACJK,MAAM,EACNb,MAAM,EAKP;IACC,IAAIa,UAAUA,OAAOb,MAAM,KAAKA,UAAUQ,KAAKP,OAAO,KAAKY,OAAOb,MAAM,EAAE;QACxE,IAAIa,OAAOC,SAAS,EAAE;YACpBN,KAAKP,OAAO,GAAGY,OAAOM,cAAc;QACtC,OAAO;YACL,OAAOX,KAAKP,OAAO;QACrB;IACF;IAEA,OAAOD,UAAUQ,KAAKP,OAAO,KAAKD,SAASA,SAASM;AACtD,EAAC;AAED,OAAO,MAAMe,qCAAqC,CAAC,EACjDjB,iBAAiB,EACjBC,mBAAmB,EAIpB;IACC,IAAID,qBAAqBC,qBAAqB;QAC5C,MAAM,IAAIV,SACR,kEACAC,WAAW0B,WAAW;IAE1B;AACF,EAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.4",
|
|
4
4
|
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"admin panel",
|
|
@@ -57,6 +57,11 @@
|
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
"exports": {
|
|
60
|
+
"./build-config": {
|
|
61
|
+
"types": "./dist/exports/build-config.d.ts",
|
|
62
|
+
"import": "./dist/exports/build-config.js",
|
|
63
|
+
"default": "./dist/exports/build-config.js"
|
|
64
|
+
},
|
|
60
65
|
".": {
|
|
61
66
|
"types": "./dist/index.d.ts",
|
|
62
67
|
"browser": "./dist/exports/shared.js",
|
|
@@ -113,6 +118,7 @@
|
|
|
113
118
|
},
|
|
114
119
|
"dependencies": {
|
|
115
120
|
"@next/env": "16.4.2",
|
|
121
|
+
"@payloadcms/translations": "4.0.0-beta.4",
|
|
116
122
|
"@standard-schema/spec": "1.1.0",
|
|
117
123
|
"@types/busboy": "1.5.4",
|
|
118
124
|
"bson-objectid": "2.0.4",
|
|
@@ -141,11 +147,10 @@
|
|
|
141
147
|
"sax": "1.6.1",
|
|
142
148
|
"ts-essentials": "10.0.3",
|
|
143
149
|
"tsx": "4.23.15",
|
|
144
|
-
"undici": "7.
|
|
150
|
+
"undici": "7.30.1",
|
|
145
151
|
"uuid": "14.0.0",
|
|
146
152
|
"ws": "^8.16.0",
|
|
147
|
-
"zod": "^4.6.0"
|
|
148
|
-
"@payloadcms/translations": "4.0.0-beta.3"
|
|
153
|
+
"zod": "^4.6.0"
|
|
149
154
|
},
|
|
150
155
|
"devDependencies": {
|
|
151
156
|
"@hyrious/esbuild-plugin-commonjs": "0.2.6",
|
|
@@ -163,14 +168,13 @@
|
|
|
163
168
|
"react-datepicker": "9.1.0",
|
|
164
169
|
"rimraf": "6.0.1",
|
|
165
170
|
"rollup": "4.59.0",
|
|
166
|
-
"rollup-plugin-dts": "6.2.3"
|
|
167
|
-
"@payloadcms/eslint-config": "3.28.0"
|
|
171
|
+
"rollup-plugin-dts": "6.2.3"
|
|
168
172
|
},
|
|
169
173
|
"peerDependencies": {
|
|
170
174
|
"graphql": "^16.8.1"
|
|
171
175
|
},
|
|
172
176
|
"engines": {
|
|
173
|
-
"node": ">=24.
|
|
177
|
+
"node": ">=24.22.1"
|
|
174
178
|
},
|
|
175
179
|
"scripts": {
|
|
176
180
|
"build": "rimraf .dist && rimraf tsconfig.tsbuildinfo && pnpm copyfiles && pnpm build:types && pnpm build:swc && pnpm bundle:types && echo skipping esbuild",
|
|
@@ -182,8 +186,6 @@
|
|
|
182
186
|
"clean": "rimraf -g {dist,*.tsbuildinfo}",
|
|
183
187
|
"clean:cache": "rimraf node_modules/.cache",
|
|
184
188
|
"copyfiles": "copyfiles -u 1 -e \"**/*.spec.*\" \"src/**/*.{html,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
|
|
185
|
-
"lint": "eslint .",
|
|
186
|
-
"lint:fix": "eslint . --fix",
|
|
187
189
|
"pretest": "pnpm build"
|
|
188
190
|
}
|
|
189
191
|
}
|