@depup/payload 3.81.0-depup.0 → 3.82.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/changes.json +3 -3
- package/dist/bin/generateTypes.d.ts.map +1 -1
- package/dist/bin/generateTypes.js +8 -0
- package/dist/bin/generateTypes.js.map +1 -1
- package/dist/collections/config/sanitize.d.ts +2 -1
- package/dist/collections/config/sanitize.d.ts.map +1 -1
- package/dist/collections/config/sanitize.js +4 -1
- package/dist/collections/config/sanitize.js.map +1 -1
- package/dist/collections/operations/utilities/update.d.ts.map +1 -1
- package/dist/collections/operations/utilities/update.js +2 -1
- package/dist/collections/operations/utilities/update.js.map +1 -1
- package/dist/config/orderable/index.d.ts +2 -10
- package/dist/config/orderable/index.d.ts.map +1 -1
- package/dist/config/orderable/index.js +20 -67
- package/dist/config/orderable/index.js.map +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +45 -5
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +20 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/fields/config/sanitize.d.ts +54 -2
- package/dist/fields/config/sanitize.d.ts.map +1 -1
- package/dist/fields/config/sanitize.js +333 -285
- package/dist/fields/config/sanitize.js.map +1 -1
- package/dist/fields/config/sanitize.spec.js +82 -0
- package/dist/fields/config/sanitize.spec.js.map +1 -1
- package/dist/fields/config/sanitizeJoinField.d.ts +15 -1
- package/dist/fields/config/sanitizeJoinField.d.ts.map +1 -1
- package/dist/fields/config/sanitizeJoinField.js +17 -1
- package/dist/fields/config/sanitizeJoinField.js.map +1 -1
- package/dist/globals/operations/findOne.d.ts +1 -0
- package/dist/globals/operations/findOne.d.ts.map +1 -1
- package/dist/globals/operations/findOne.js +10 -3
- package/dist/globals/operations/findOne.js.map +1 -1
- package/dist/globals/operations/local/findOne.d.ts +8 -0
- package/dist/globals/operations/local/findOne.d.ts.map +1 -1
- package/dist/globals/operations/local/findOne.js +2 -1
- package/dist/globals/operations/local/findOne.js.map +1 -1
- package/dist/globals/operations/update.d.ts.map +1 -1
- package/dist/globals/operations/update.js +2 -1
- package/dist/globals/operations/update.js.map +1 -1
- package/dist/index.bundled.d.ts +112 -18
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/uploads/checkFileAccess.d.ts +2 -1
- package/dist/uploads/checkFileAccess.d.ts.map +1 -1
- package/dist/uploads/checkFileAccess.js +25 -14
- package/dist/uploads/checkFileAccess.js.map +1 -1
- package/dist/uploads/checkFileAccess.spec.js +109 -0
- package/dist/uploads/checkFileAccess.spec.js.map +1 -0
- package/dist/uploads/endpoints/getFile.d.ts.map +1 -1
- package/dist/uploads/endpoints/getFile.js +4 -1
- package/dist/uploads/endpoints/getFile.js.map +1 -1
- package/dist/uploads/types.d.ts +2 -1
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/dist/utilities/slugify.d.ts.map +1 -1
- package/dist/utilities/slugify.js +1 -1
- package/dist/utilities/slugify.js.map +1 -1
- package/dist/utilities/validateTimezones.d.ts.map +1 -1
- package/dist/utilities/validateTimezones.js +7 -0
- package/dist/utilities/validateTimezones.js.map +1 -1
- package/dist/versions/types.d.ts +1 -1
- package/dist/versions/types.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/config/sanitize.ts"],"sourcesContent":["import { deepMergeSimple } from '@payloadcms/translations/utilities'\n\nimport type {\n CollectionConfig,\n SanitizedJoin,\n SanitizedJoins,\n} from '../../collections/config/types.js'\nimport type { Config, SanitizedConfig } from '../../config/types.js'\nimport type { GlobalConfig } from '../../globals/config/types.js'\nimport type { Field } from './types.js'\n\nimport {\n DuplicateFieldName,\n InvalidConfiguration,\n InvalidFieldName,\n InvalidFieldRelationship,\n MissingEditorProp,\n MissingFieldType,\n} from '../../errors/index.js'\nimport { ReservedFieldName } from '../../errors/ReservedFieldName.js'\nimport { flattenAllFields } from '../../utilities/flattenAllFields.js'\nimport { formatLabels, toWords } from '../../utilities/formatLabels.js'\nimport { validateTimezones } from '../../utilities/validateTimezones.js'\nimport { baseBlockFields } from '../baseFields/baseBlockFields.js'\nimport { baseIDField } from '../baseFields/baseIDField.js'\nimport { baseTimezoneField } from '../baseFields/timezone/baseField.js'\nimport { defaultTimezones } from '../baseFields/timezone/defaultTimezones.js'\nimport { getFieldPaths } from '../getFieldPaths.js'\nimport { setDefaultBeforeDuplicate } from '../setDefaultBeforeDuplicate.js'\nimport { validations } from '../validations.js'\nimport {\n reservedAPIKeyFieldNames,\n reservedBaseAuthFieldNames,\n reservedBaseUploadFieldNames,\n reservedVerifyFieldNames,\n} from './reservedFieldNames.js'\nimport { sanitizeJoinField } from './sanitizeJoinField.js'\nimport {\n fieldAffectsData as _fieldAffectsData,\n fieldIsLocalized,\n fieldIsVirtual,\n tabHasName,\n} from './types.js'\n\ntype Args = {\n collectionConfig?: CollectionConfig\n config: Config\n existingFieldNames?: Set<string>\n fields: Field[]\n globalConfig?: GlobalConfig\n /**\n * Used to prevent unnecessary sanitization of fields that are not top-level.\n */\n isTopLevelField?: boolean\n joinPath?: string\n /**\n * When not passed in, assume that join are not supported (globals, arrays, blocks)\n */\n joins?: SanitizedJoins\n /**\n * A string of '-' separated indexes representing where\n * to find this field in a given field schema array.\n */\n parentIndexPath?: string\n parentIsLocalized: boolean\n /**\n * Path for parent fields relative to their position in the schema.\n */\n parentSchemaPath?: string\n polymorphicJoins?: SanitizedJoin[]\n /**\n * If true, a richText field will require an editor property to be set, as the sanitizeFields function will not add it from the payload config if not present.\n *\n * @default false\n */\n requireFieldLevelRichTextEditor?: boolean\n /**\n * If this property is set, RichText fields won't be sanitized immediately. Instead, they will be added to this array as promises\n * so that you can sanitize them together, after the config has been sanitized.\n */\n richTextSanitizationPromises?: Array<(config: SanitizedConfig) => Promise<void>>\n /**\n * If not null, will validate that upload and relationship fields do not relate to a collection that is not in this array.\n * This validation will be skipped if validRelationships is null.\n */\n validRelationships: null | string[]\n}\n\nexport const sanitizeFields = async ({\n collectionConfig,\n config,\n existingFieldNames = new Set(),\n fields,\n globalConfig,\n isTopLevelField = true,\n joinPath = '',\n joins,\n parentIndexPath = '',\n parentIsLocalized,\n parentSchemaPath = '',\n polymorphicJoins,\n requireFieldLevelRichTextEditor = false,\n richTextSanitizationPromises,\n validRelationships,\n}: Args): Promise<Field[]> => {\n if (!fields) {\n return []\n }\n\n for (let i = 0; i < fields.length; i++) {\n const field = fields[i]!\n\n if ('_sanitized' in field && field._sanitized === true) {\n continue\n }\n\n if ('_sanitized' in field) {\n field._sanitized = true\n }\n\n if (!field.type) {\n throw new MissingFieldType(field)\n }\n\n const fieldAffectsData = _fieldAffectsData(field)\n\n const { indexPath, schemaPath } = getFieldPaths({\n field,\n index: i,\n parentIndexPath,\n parentSchemaPath,\n })\n\n if (isTopLevelField && fieldAffectsData && field.name) {\n if (collectionConfig && collectionConfig.upload) {\n if (reservedBaseUploadFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n\n if (\n collectionConfig &&\n collectionConfig.auth &&\n typeof collectionConfig.auth === 'object' &&\n !collectionConfig.auth.disableLocalStrategy\n ) {\n if (reservedBaseAuthFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n if (collectionConfig.auth.verify) {\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedAPIKeyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedVerifyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n }\n }\n\n // assert that field names do not contain forbidden characters\n if (fieldAffectsData && field.name.includes('.')) {\n throw new InvalidFieldName(field, field.name)\n }\n\n // Auto-label\n if (\n 'name' in field &&\n field.name &&\n typeof field.label !== 'object' &&\n typeof field.label !== 'string' &&\n typeof field.label !== 'function' &&\n field.label !== false\n ) {\n field.label = toWords(field.name)\n }\n\n if (\n field.type === 'checkbox' &&\n typeof field.defaultValue === 'undefined' &&\n field.required === true\n ) {\n field.defaultValue = false\n }\n\n if (field.type === 'join') {\n sanitizeJoinField({ config, field, joinPath, joins, parentIsLocalized, polymorphicJoins })\n }\n\n if (field.type === 'relationship' || field.type === 'upload') {\n // Validate that relationTo is not empty\n if (Array.isArray(field.relationTo) && field.relationTo.length === 0) {\n throw new Error(\n `Field \"${field.name}\" of type \"${field.type}\" has an empty relationTo array. At least one collection must be specified.`,\n )\n }\n\n if (validRelationships) {\n const relationships = Array.isArray(field.relationTo)\n ? field.relationTo\n : [field.relationTo]\n\n relationships.forEach((relationship: string) => {\n if (!validRelationships.includes(relationship)) {\n throw new InvalidFieldRelationship(field, relationship)\n }\n })\n }\n\n if (field.min && !field.minRows) {\n console.warn(\n `(payload): The \"min\" property is deprecated for the Relationship field \"${field.name}\" and will be removed in a future version. Please use \"minRows\" instead.`,\n )\n field.minRows = field.min\n }\n\n if (field.max && !field.maxRows) {\n console.warn(\n `(payload): The \"max\" property is deprecated for the Relationship field \"${field.name}\" and will be removed in a future version. Please use \"maxRows\" instead.`,\n )\n field.maxRows = field.max\n }\n }\n\n if (field.type === 'upload') {\n if (!field.admin || !('isSortable' in field.admin)) {\n field.admin = {\n isSortable: true,\n ...field.admin,\n }\n }\n }\n\n if (field.type === 'array' && field.fields) {\n const hasCustomID = field.fields.some((f) => 'name' in f && f.name === 'id')\n if (!hasCustomID) {\n field.fields.push(baseIDField)\n }\n }\n\n if ((field.type === 'blocks' || field.type === 'array') && field.label) {\n field.labels = field.labels || formatLabels(field.name)\n }\n\n if (fieldAffectsData) {\n if (existingFieldNames.has(field.name)) {\n throw new DuplicateFieldName(field.name)\n } else if (!['blockName', 'id'].includes(field.name)) {\n existingFieldNames.add(field.name)\n }\n\n if (typeof field.localized !== 'undefined') {\n let shouldDisableLocalized = !config.localization\n\n if (\n process.env.NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized !== 'true' &&\n parentIsLocalized &&\n // @todo PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY=true will be the default in 4.0\n process.env.PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY !== 'true'\n ) {\n shouldDisableLocalized = true\n }\n\n if (shouldDisableLocalized) {\n delete field.localized\n }\n }\n\n if (typeof field.validate === 'undefined') {\n const defaultValidate = validations[field.type as keyof typeof validations]\n if (defaultValidate) {\n field.validate = (val: any, options: any) =>\n defaultValidate(val, { ...field, ...options })\n } else {\n field.validate = (): true => true\n }\n }\n\n if (!field.hooks) {\n field.hooks = {}\n }\n\n if (!field.access) {\n field.access = {}\n }\n\n setDefaultBeforeDuplicate(field, parentIsLocalized)\n }\n\n if (!field.admin) {\n field.admin = {}\n }\n\n // Make sure that the richText field has an editor\n if (field.type === 'richText') {\n const sanitizeRichText = async (_config: SanitizedConfig) => {\n if (!field.editor) {\n if (_config.editor && !requireFieldLevelRichTextEditor) {\n // config.editor should be sanitized at this point\n field.editor = _config.editor\n } else {\n throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor\n }\n }\n\n if (typeof field.editor === 'function') {\n field.editor = await field.editor({\n config: _config,\n isRoot: requireFieldLevelRichTextEditor,\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n })\n }\n\n if (field.editor.i18n && Object.keys(field.editor.i18n).length >= 0) {\n config.i18n!.translations = deepMergeSimple(config.i18n!.translations!, field.editor.i18n)\n }\n }\n if (richTextSanitizationPromises) {\n richTextSanitizationPromises.push(sanitizeRichText)\n } else {\n await sanitizeRichText(config as unknown as SanitizedConfig)\n }\n }\n\n if (field.type === 'blocks' && field.blocks) {\n if (field.blockReferences && field.blocks?.length) {\n throw new Error('You cannot have both blockReferences and blocks in the same blocks field')\n }\n\n const blockSlugs: string[] = []\n\n for (const block of field.blockReferences ?? field.blocks) {\n const blockSlug = typeof block === 'string' ? block : block.slug\n\n if (blockSlugs.includes(blockSlug)) {\n throw new DuplicateFieldName(blockSlug)\n }\n\n blockSlugs.push(blockSlug)\n\n if (typeof block === 'string') {\n continue\n }\n\n if (block._sanitized === true) {\n continue\n }\n\n block._sanitized = true\n block.fields = block.fields.concat(baseBlockFields)\n block.labels = !block.labels ? formatLabels(block.slug) : block.labels\n\n block.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: new Set(),\n fields: block.fields,\n isTopLevelField: false,\n parentIndexPath: '',\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n parentSchemaPath: schemaPath + '.' + block.slug,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n }\n\n if ('fields' in field && field.fields) {\n field.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: fieldAffectsData ? new Set() : existingFieldNames,\n fields: field.fields,\n isTopLevelField: isTopLevelField && !fieldAffectsData,\n joinPath: fieldAffectsData ? `${joinPath ? joinPath + '.' : ''}${field.name}` : joinPath,\n joins,\n parentIndexPath: fieldAffectsData ? '' : indexPath,\n parentIsLocalized: parentIsLocalized || fieldIsLocalized(field),\n parentSchemaPath: schemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n\n if (field.type === 'tabs') {\n for (let j = 0; j < field.tabs.length; j++) {\n const tab = field.tabs[j]!\n\n const isNamedTab = tabHasName(tab)\n\n if (isNamedTab && typeof tab.label === 'undefined') {\n tab.label = toWords(tab.name)\n }\n\n const { indexPath: tabIndexPath, schemaPath: tabSchemaPath } = getFieldPaths({\n field: tab,\n index: j,\n parentIndexPath: indexPath,\n parentSchemaPath: schemaPath,\n })\n\n if (\n 'admin' in tab &&\n tab.admin?.condition &&\n typeof tab.admin.condition === 'function' &&\n !tab.id\n ) {\n tab.id = tabSchemaPath\n }\n\n tab.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: isNamedTab ? new Set() : existingFieldNames,\n fields: tab.fields,\n isTopLevelField: isTopLevelField && !isNamedTab,\n joinPath: isNamedTab ? `${joinPath ? joinPath + '.' : ''}${tab.name}` : joinPath,\n joins,\n parentIndexPath: isNamedTab ? '' : tabIndexPath,\n parentIsLocalized: parentIsLocalized || (isNamedTab && tab.localized)!,\n parentSchemaPath: tabSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n field.tabs[j] = tab\n }\n }\n\n if (field.type === 'ui' && typeof field.admin.disableBulkEdit === 'undefined') {\n field.admin.disableBulkEdit = true\n }\n\n fields[i] = field\n\n // Insert our field after assignment\n if (field.type === 'date' && field.timezone) {\n const name = field.name + '_tz'\n\n let defaultTimezone =\n field.timezone && typeof field.timezone === 'object'\n ? field.timezone.defaultTimezone\n : config.admin?.timezones?.defaultTimezone\n\n const required =\n field.required ||\n (field.timezone && typeof field.timezone === 'object' && field.timezone.required)\n\n const supportedTimezones =\n field.timezone && typeof field.timezone === 'object' && field.timezone.supportedTimezones\n ? field.timezone.supportedTimezones\n : config.admin?.timezones?.supportedTimezones\n\n const options =\n typeof supportedTimezones === 'function'\n ? supportedTimezones({ defaultTimezones })\n : supportedTimezones\n\n validateTimezones({\n source: `field \"${field.name}\" timezone.supportedTimezones`,\n timezones: options,\n })\n\n if (options && options.length === 1 && options[0]?.value) {\n defaultTimezone = options[0].value\n }\n\n // Generate label for timezone field\n // Use parent field's label + ' Tz' if it's a simple string, otherwise fallback to name\n const timezoneLabel = typeof field.label === 'string' ? `${field.label} Tz` : toWords(name)\n\n // Need to set the options here manually so that any database enums are generated correctly\n // The UI component will import the options from the config\n const baseField = baseTimezoneField({\n name,\n defaultValue: defaultTimezone,\n label: timezoneLabel,\n options,\n required,\n })\n\n // Apply override if provided\n const timezoneField =\n typeof field.timezone === 'object' && typeof field.timezone.override === 'function'\n ? field.timezone.override({ baseField })\n : baseField\n\n fields.splice(++i, 0, timezoneField)\n }\n\n if ('virtual' in field && typeof field.virtual === 'string') {\n const virtualField = field\n const fields = (collectionConfig || globalConfig)?.fields\n if (fields) {\n let flattenFields = flattenAllFields({ fields })\n const paths = field.virtual.split('.')\n let isHasMany = false\n\n for (const [i, segment] of paths.entries()) {\n const field = flattenFields.find((e) => e.name === segment)\n if (!field) {\n break\n }\n\n if (field.type === 'group' || field.type === 'tab' || field.type === 'array') {\n flattenFields = field.flattenedFields\n } else if (\n (field.type === 'relationship' || field.type === 'upload') &&\n i !== paths.length - 1 &&\n typeof field.relationTo === 'string'\n ) {\n if (\n field.hasMany &&\n (virtualField.type === 'text' ||\n virtualField.type === 'number' ||\n virtualField.type === 'select')\n ) {\n if (isHasMany) {\n throw new InvalidConfiguration(\n `Virtual field ${virtualField.name} in ${globalConfig ? `global ${globalConfig.slug}` : `collection ${collectionConfig?.slug}`} references 2 or more hasMany relationships on the path ${virtualField.virtual} which is not allowed.`,\n )\n }\n\n isHasMany = true\n virtualField.hasMany = true\n }\n const relatedCollection = config.collections?.find((e) => e.slug === field.relationTo)\n if (relatedCollection) {\n flattenFields = flattenAllFields({ fields: relatedCollection.fields })\n }\n }\n }\n }\n }\n }\n\n return fields\n}\n"],"names":["deepMergeSimple","DuplicateFieldName","InvalidConfiguration","InvalidFieldName","InvalidFieldRelationship","MissingEditorProp","MissingFieldType","ReservedFieldName","flattenAllFields","formatLabels","toWords","validateTimezones","baseBlockFields","baseIDField","baseTimezoneField","defaultTimezones","getFieldPaths","setDefaultBeforeDuplicate","validations","reservedAPIKeyFieldNames","reservedBaseAuthFieldNames","reservedBaseUploadFieldNames","reservedVerifyFieldNames","sanitizeJoinField","fieldAffectsData","_fieldAffectsData","fieldIsLocalized","tabHasName","sanitizeFields","collectionConfig","config","existingFieldNames","Set","fields","globalConfig","isTopLevelField","joinPath","joins","parentIndexPath","parentIsLocalized","parentSchemaPath","polymorphicJoins","requireFieldLevelRichTextEditor","richTextSanitizationPromises","validRelationships","i","length","field","_sanitized","type","indexPath","schemaPath","index","name","upload","includes","auth","disableLocalStrategy","verify","label","defaultValue","required","Array","isArray","relationTo","Error","relationships","forEach","relationship","min","minRows","console","warn","max","maxRows","admin","isSortable","hasCustomID","some","f","push","labels","has","add","localized","shouldDisableLocalized","localization","process","env","NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized","PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY","validate","defaultValidate","val","options","hooks","access","sanitizeRichText","_config","editor","isRoot","i18n","Object","keys","translations","blocks","blockReferences","blockSlugs","block","blockSlug","slug","concat","j","tabs","tab","isNamedTab","tabIndexPath","tabSchemaPath","condition","id","disableBulkEdit","timezone","defaultTimezone","timezones","supportedTimezones","source","value","timezoneLabel","baseField","timezoneField","override","splice","virtual","virtualField","flattenFields","paths","split","isHasMany","segment","entries","find","e","flattenedFields","hasMany","relatedCollection","collections"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/config/sanitize.ts"],"sourcesContent":["import { deepMergeSimple } from '@payloadcms/translations/utilities'\n\nimport type {\n CollectionConfig,\n SanitizedJoin,\n SanitizedJoins,\n} from '../../collections/config/types.js'\nimport type { Config, SanitizedConfig } from '../../config/types.js'\nimport type { GlobalConfig } from '../../globals/config/types.js'\nimport type { OrderableJoinInfo } from './sanitizeJoinField.js'\nimport type { Field } from './types.js'\n\nimport {\n DuplicateFieldName,\n InvalidConfiguration,\n InvalidFieldName,\n InvalidFieldRelationship,\n MissingEditorProp,\n MissingFieldType,\n} from '../../errors/index.js'\nimport { ReservedFieldName } from '../../errors/ReservedFieldName.js'\nimport { flattenAllFields } from '../../utilities/flattenAllFields.js'\nimport { formatLabels, toWords } from '../../utilities/formatLabels.js'\nimport { validateTimezones } from '../../utilities/validateTimezones.js'\nimport { baseBlockFields } from '../baseFields/baseBlockFields.js'\nimport { baseIDField } from '../baseFields/baseIDField.js'\nimport { baseTimezoneField } from '../baseFields/timezone/baseField.js'\nimport { defaultTimezones } from '../baseFields/timezone/defaultTimezones.js'\nimport { getFieldPaths } from '../getFieldPaths.js'\nimport { setDefaultBeforeDuplicate } from '../setDefaultBeforeDuplicate.js'\nimport { validations } from '../validations.js'\nimport {\n reservedAPIKeyFieldNames,\n reservedBaseAuthFieldNames,\n reservedBaseUploadFieldNames,\n reservedVerifyFieldNames,\n} from './reservedFieldNames.js'\nimport { sanitizeJoinField } from './sanitizeJoinField.js'\nimport { fieldAffectsData as _fieldAffectsData, fieldIsLocalized, tabHasName } from './types.js'\n\ntype SanitizeFieldsArgs = {\n collectionConfig?: CollectionConfig\n config: Config\n existingFieldNames?: Set<string>\n fields: Field[]\n globalConfig?: GlobalConfig\n /**\n * Used to prevent unnecessary sanitization of fields that are not top-level.\n */\n isTopLevelField?: boolean\n joinPath?: string\n /**\n * When not passed in, assume that join are not supported (globals, arrays, blocks)\n */\n joins?: SanitizedJoins\n /**\n * Tracker for orderable join fields - populated during sanitization\n */\n orderableJoins?: OrderableJoinInfo[]\n /**\n * A string of '-' separated indexes representing where\n * to find this field in a given field schema array.\n */\n parentIndexPath?: string\n parentIsLocalized: boolean\n /**\n * Path for parent fields relative to their position in the schema.\n */\n parentSchemaPath?: string\n polymorphicJoins?: SanitizedJoin[]\n /**\n * If true, a richText field will require an editor property to be set, as the sanitizeFields function will not add it from the payload config if not present.\n *\n * @default false\n */\n requireFieldLevelRichTextEditor?: boolean\n /**\n * If this property is set, RichText fields won't be sanitized immediately. Instead, they will be added to this array as promises\n * so that you can sanitize them together, after the config has been sanitized.\n */\n richTextSanitizationPromises?: Array<(config: SanitizedConfig) => Promise<void>>\n /**\n * If not null, will validate that upload and relationship fields do not relate to a collection that is not in this array.\n * This validation will be skipped if validRelationships is null.\n */\n validRelationships: null | string[]\n}\n\nexport type SanitizeFieldArgs = {\n collectionConfig?: CollectionConfig\n config: Config\n existingFieldNames: Set<string>\n field: Field\n globalConfig?: GlobalConfig\n /**\n * The index of this field in the parent fields array\n */\n index: number\n /**\n * Used to prevent unnecessary sanitization of fields that are not top-level.\n */\n isTopLevelField: boolean\n joinPath: string\n /**\n * When not passed in, assume that joins are not supported (globals, arrays, blocks)\n */\n joins?: SanitizedJoins\n /**\n * Tracker for orderable join fields - populated during sanitization\n */\n orderableJoins?: OrderableJoinInfo[]\n parentIndexPath: string\n parentIsLocalized: boolean\n parentSchemaPath: string\n polymorphicJoins?: SanitizedJoin[]\n requireFieldLevelRichTextEditor: boolean\n richTextSanitizationPromises?: Array<(config: SanitizedConfig) => Promise<void>>\n validRelationships: null | string[]\n}\n\ntype SanitizeFieldResult = {\n /**\n * Fields to insert after this field (e.g., timezone field)\n */\n fieldsToInsert?: Field[]\n}\n\n/**\n * Sanitize a single field. Handles all per-field logic including:\n * - Validation setup\n * - Hooks/access/admin defaults\n * - Type-specific handling\n * - Recursive sanitization of nested fields\n *\n * @returns Result containing any fields to insert after this one\n */\nexport const sanitizeField = async ({\n collectionConfig,\n config,\n existingFieldNames,\n field,\n globalConfig,\n index,\n isTopLevelField,\n joinPath,\n joins,\n orderableJoins,\n parentIndexPath,\n parentIsLocalized,\n parentSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n}: SanitizeFieldArgs): Promise<SanitizeFieldResult> => {\n const result: SanitizeFieldResult = {}\n\n if ('_sanitized' in field && field._sanitized === true) {\n return result\n }\n\n if ('_sanitized' in field) {\n field._sanitized = true\n }\n\n if (!field.type) {\n throw new MissingFieldType(field)\n }\n\n const fieldAffectsData = _fieldAffectsData(field)\n\n const { indexPath, schemaPath } = getFieldPaths({\n field,\n index,\n parentIndexPath,\n parentSchemaPath,\n })\n\n // Reserved field name checks\n if (isTopLevelField && fieldAffectsData && field.name) {\n if (collectionConfig && collectionConfig.upload) {\n if (reservedBaseUploadFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n\n if (\n collectionConfig &&\n collectionConfig.auth &&\n typeof collectionConfig.auth === 'object' &&\n !collectionConfig.auth.disableLocalStrategy\n ) {\n if (reservedBaseAuthFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n if (collectionConfig.auth.verify) {\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedAPIKeyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n if (reservedVerifyFieldNames.includes(field.name)) {\n throw new ReservedFieldName(field, field.name)\n }\n }\n }\n }\n\n // Invalid field name check\n if (fieldAffectsData && field.name.includes('.')) {\n throw new InvalidFieldName(field, field.name)\n }\n\n // Auto-label\n if (\n 'name' in field &&\n field.name &&\n typeof field.label !== 'object' &&\n typeof field.label !== 'string' &&\n typeof field.label !== 'function' &&\n field.label !== false\n ) {\n field.label = toWords(field.name)\n }\n\n // Checkbox default\n if (\n field.type === 'checkbox' &&\n typeof field.defaultValue === 'undefined' &&\n field.required === true\n ) {\n field.defaultValue = false\n }\n\n // Join field sanitization\n if (field.type === 'join') {\n sanitizeJoinField({\n config,\n field,\n joinPath,\n joins,\n orderableJoins,\n parentIsLocalized,\n polymorphicJoins,\n })\n }\n\n // Relationship/upload validation\n if (field.type === 'relationship' || field.type === 'upload') {\n if (Array.isArray(field.relationTo) && field.relationTo.length === 0) {\n throw new Error(\n `Field \"${field.name}\" of type \"${field.type}\" has an empty relationTo array. At least one collection must be specified.`,\n )\n }\n\n if (validRelationships) {\n const relationships = Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo]\n\n relationships.forEach((relationship: string) => {\n if (!validRelationships.includes(relationship)) {\n throw new InvalidFieldRelationship(field, relationship)\n }\n })\n }\n\n if (field.min && !field.minRows) {\n console.warn(\n `(payload): The \"min\" property is deprecated for the Relationship field \"${field.name}\" and will be removed in a future version. Please use \"minRows\" instead.`,\n )\n field.minRows = field.min\n }\n\n if (field.max && !field.maxRows) {\n console.warn(\n `(payload): The \"max\" property is deprecated for the Relationship field \"${field.name}\" and will be removed in a future version. Please use \"maxRows\" instead.`,\n )\n field.maxRows = field.max\n }\n }\n\n // Upload isSortable default\n if (field.type === 'upload') {\n if (!field.admin || !('isSortable' in field.admin)) {\n field.admin = {\n isSortable: true,\n ...field.admin,\n }\n }\n }\n\n // Array ID field\n if (field.type === 'array' && field.fields) {\n const hasCustomID = field.fields.some((f) => 'name' in f && f.name === 'id')\n if (!hasCustomID) {\n field.fields.push(baseIDField)\n }\n }\n\n // Blocks/array labels\n if ((field.type === 'blocks' || field.type === 'array') && field.label) {\n field.labels = field.labels || formatLabels(field.name)\n }\n\n if (fieldAffectsData) {\n if (existingFieldNames.has(field.name)) {\n throw new DuplicateFieldName(field.name)\n } else if (!['blockName', 'id'].includes(field.name)) {\n existingFieldNames.add(field.name)\n }\n\n if (typeof field.localized !== 'undefined') {\n let shouldDisableLocalized = !config.localization\n\n if (\n process.env.NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized !== 'true' &&\n parentIsLocalized &&\n // @todo PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY=true will be the default in 4.0\n process.env.PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY !== 'true'\n ) {\n shouldDisableLocalized = true\n }\n\n if (shouldDisableLocalized) {\n delete field.localized\n }\n }\n\n if (typeof field.validate === 'undefined') {\n if ('virtual' in field && field.virtual) {\n field.validate = (): true => true\n } else {\n const defaultValidate = validations[field.type as keyof typeof validations]\n if (defaultValidate) {\n field.validate = (val: any, options: any) =>\n defaultValidate(val, { ...field, ...options })\n } else {\n field.validate = (): true => true\n }\n }\n }\n\n if (!field.hooks) {\n field.hooks = {}\n }\n\n if (!field.access) {\n field.access = {}\n }\n\n setDefaultBeforeDuplicate(field, parentIsLocalized)\n }\n\n if (!field.admin) {\n field.admin = {}\n }\n\n // Make sure that the richText field has an editor\n if (field.type === 'richText') {\n const sanitizeRichText = async (_config: SanitizedConfig) => {\n if (!field.editor) {\n if (_config.editor && !requireFieldLevelRichTextEditor) {\n // config.editor should be sanitized at this point\n field.editor = _config.editor\n } else {\n throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor\n }\n }\n\n if (typeof field.editor === 'function') {\n field.editor = await field.editor({\n config: _config,\n isRoot: requireFieldLevelRichTextEditor,\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n })\n }\n\n if (field.editor.i18n && Object.keys(field.editor.i18n).length >= 0) {\n config.i18n!.translations = deepMergeSimple(config.i18n!.translations!, field.editor.i18n)\n }\n }\n if (richTextSanitizationPromises) {\n richTextSanitizationPromises.push(sanitizeRichText)\n } else {\n await sanitizeRichText(config as unknown as SanitizedConfig)\n }\n }\n\n if (field.type === 'blocks' && field.blocks) {\n if (field.blockReferences && field.blocks?.length) {\n throw new Error('You cannot have both blockReferences and blocks in the same blocks field')\n }\n\n const blockSlugs: string[] = []\n\n for (const block of field.blockReferences ?? field.blocks) {\n const blockSlug = typeof block === 'string' ? block : block.slug\n\n if (blockSlugs.includes(blockSlug)) {\n throw new DuplicateFieldName(blockSlug)\n }\n\n blockSlugs.push(blockSlug)\n\n if (typeof block === 'string') {\n continue\n }\n\n if (block._sanitized === true) {\n continue\n }\n\n block._sanitized = true\n block.fields = block.fields.concat(baseBlockFields)\n block.labels = !block.labels ? formatLabels(block.slug) : block.labels\n\n block.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: new Set(),\n fields: block.fields,\n isTopLevelField: false,\n parentIndexPath: '',\n parentIsLocalized: (parentIsLocalized || field.localized)!,\n parentSchemaPath: schemaPath + '.' + block.slug,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n }\n\n if ('fields' in field && field.fields) {\n field.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: fieldAffectsData ? new Set() : existingFieldNames,\n fields: field.fields,\n isTopLevelField: isTopLevelField && !fieldAffectsData,\n joinPath: fieldAffectsData ? `${joinPath ? joinPath + '.' : ''}${field.name}` : joinPath,\n joins,\n orderableJoins,\n parentIndexPath: fieldAffectsData ? '' : indexPath,\n parentIsLocalized: parentIsLocalized || fieldIsLocalized(field),\n parentSchemaPath: schemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n\n if (field.type === 'tabs') {\n for (let j = 0; j < field.tabs.length; j++) {\n const tab = field.tabs[j]!\n\n const isNamedTab = tabHasName(tab)\n\n if (isNamedTab && typeof tab.label === 'undefined') {\n tab.label = toWords(tab.name)\n }\n\n const { indexPath: tabIndexPath, schemaPath: tabSchemaPath } = getFieldPaths({\n field: tab,\n index: j,\n parentIndexPath: indexPath,\n parentSchemaPath: schemaPath,\n })\n\n if (\n 'admin' in tab &&\n tab.admin?.condition &&\n typeof tab.admin.condition === 'function' &&\n !tab.id\n ) {\n tab.id = tabSchemaPath\n }\n\n tab.fields = await sanitizeFields({\n collectionConfig,\n config,\n existingFieldNames: isNamedTab ? new Set() : existingFieldNames,\n fields: tab.fields,\n isTopLevelField: isTopLevelField && !isNamedTab,\n joinPath: isNamedTab ? `${joinPath ? joinPath + '.' : ''}${tab.name}` : joinPath,\n joins,\n orderableJoins,\n parentIndexPath: isNamedTab ? '' : tabIndexPath,\n parentIsLocalized: parentIsLocalized || (isNamedTab && tab.localized)!,\n parentSchemaPath: tabSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n field.tabs[j] = tab\n }\n }\n\n if (field.type === 'ui' && typeof field.admin.disableBulkEdit === 'undefined') {\n field.admin.disableBulkEdit = true\n }\n\n // Timezone field insertion\n if (field.type === 'date' && field.timezone) {\n const name = field.name + '_tz'\n\n let defaultTimezone =\n field.timezone && typeof field.timezone === 'object'\n ? field.timezone.defaultTimezone\n : config.admin?.timezones?.defaultTimezone\n\n const required =\n field.required ||\n (field.timezone && typeof field.timezone === 'object' && field.timezone.required)\n\n const supportedTimezones =\n field.timezone && typeof field.timezone === 'object' && field.timezone.supportedTimezones\n ? field.timezone.supportedTimezones\n : config.admin?.timezones?.supportedTimezones\n\n const options =\n typeof supportedTimezones === 'function'\n ? supportedTimezones({ defaultTimezones })\n : supportedTimezones\n\n validateTimezones({\n source: `field \"${field.name}\" timezone.supportedTimezones`,\n timezones: options,\n })\n\n if (options && options.length === 1 && options[0]?.value) {\n defaultTimezone = options[0].value\n }\n\n // Generate label for timezone field\n const timezoneLabel = typeof field.label === 'string' ? `${field.label} Tz` : toWords(name)\n\n const baseField = baseTimezoneField({\n name,\n defaultValue: defaultTimezone,\n label: timezoneLabel,\n options,\n required,\n })\n\n // Apply override if provided\n const timezoneField =\n typeof field.timezone === 'object' && typeof field.timezone.override === 'function'\n ? field.timezone.override({ baseField })\n : baseField\n\n result.fieldsToInsert = [timezoneField]\n }\n\n // Virtual field handling\n if ('virtual' in field && typeof field.virtual === 'string') {\n const virtualField = field\n const configFields = (collectionConfig || globalConfig)?.fields\n if (configFields) {\n let flattenFields = flattenAllFields({ fields: configFields })\n const paths = field.virtual.split('.')\n let isHasMany = false\n\n for (const [idx, segment] of paths.entries()) {\n const foundField = flattenFields.find((e) => e.name === segment)\n if (!foundField) {\n break\n }\n\n if (\n foundField.type === 'group' ||\n foundField.type === 'tab' ||\n foundField.type === 'array'\n ) {\n flattenFields = foundField.flattenedFields\n } else if (\n (foundField.type === 'relationship' || foundField.type === 'upload') &&\n idx !== paths.length - 1 &&\n typeof foundField.relationTo === 'string'\n ) {\n if (\n foundField.hasMany &&\n (virtualField.type === 'text' ||\n virtualField.type === 'number' ||\n virtualField.type === 'select')\n ) {\n if (isHasMany) {\n throw new InvalidConfiguration(\n `Virtual field ${virtualField.name} in ${globalConfig ? `global ${globalConfig.slug}` : `collection ${collectionConfig?.slug}`} references 2 or more hasMany relationships on the path ${virtualField.virtual} which is not allowed.`,\n )\n }\n\n isHasMany = true\n virtualField.hasMany = true\n }\n const relatedCollection = config.collections?.find(\n (e) => e.slug === foundField.relationTo,\n )\n if (relatedCollection) {\n flattenFields = flattenAllFields({ fields: relatedCollection.fields })\n }\n }\n }\n }\n }\n\n return result\n}\n\nexport const sanitizeFields = async ({\n collectionConfig,\n config,\n existingFieldNames = new Set(),\n fields,\n globalConfig,\n isTopLevelField = true,\n joinPath = '',\n joins,\n orderableJoins,\n parentIndexPath = '',\n parentIsLocalized,\n parentSchemaPath = '',\n polymorphicJoins,\n requireFieldLevelRichTextEditor = false,\n richTextSanitizationPromises,\n validRelationships,\n}: SanitizeFieldsArgs): Promise<Field[]> => {\n if (!fields) {\n return []\n }\n\n for (let i = 0; i < fields.length; i++) {\n const field = fields[i]!\n\n const result = await sanitizeField({\n collectionConfig,\n config,\n existingFieldNames,\n field,\n globalConfig,\n index: i,\n isTopLevelField,\n joinPath,\n joins,\n orderableJoins,\n parentIndexPath,\n parentIsLocalized,\n parentSchemaPath,\n polymorphicJoins,\n requireFieldLevelRichTextEditor,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n fields[i] = field\n\n if (result.fieldsToInsert?.length) {\n fields.splice(i + 1, 0, ...result.fieldsToInsert)\n i += result.fieldsToInsert.length\n }\n }\n\n return fields\n}\n"],"names":["deepMergeSimple","DuplicateFieldName","InvalidConfiguration","InvalidFieldName","InvalidFieldRelationship","MissingEditorProp","MissingFieldType","ReservedFieldName","flattenAllFields","formatLabels","toWords","validateTimezones","baseBlockFields","baseIDField","baseTimezoneField","defaultTimezones","getFieldPaths","setDefaultBeforeDuplicate","validations","reservedAPIKeyFieldNames","reservedBaseAuthFieldNames","reservedBaseUploadFieldNames","reservedVerifyFieldNames","sanitizeJoinField","fieldAffectsData","_fieldAffectsData","fieldIsLocalized","tabHasName","sanitizeField","collectionConfig","config","existingFieldNames","field","globalConfig","index","isTopLevelField","joinPath","joins","orderableJoins","parentIndexPath","parentIsLocalized","parentSchemaPath","polymorphicJoins","requireFieldLevelRichTextEditor","richTextSanitizationPromises","validRelationships","result","_sanitized","type","indexPath","schemaPath","name","upload","includes","auth","disableLocalStrategy","verify","label","defaultValue","required","Array","isArray","relationTo","length","Error","relationships","forEach","relationship","min","minRows","console","warn","max","maxRows","admin","isSortable","fields","hasCustomID","some","f","push","labels","has","add","localized","shouldDisableLocalized","localization","process","env","NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized","PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY","validate","virtual","defaultValidate","val","options","hooks","access","sanitizeRichText","_config","editor","isRoot","i18n","Object","keys","translations","blocks","blockReferences","blockSlugs","block","blockSlug","slug","concat","sanitizeFields","Set","j","tabs","tab","isNamedTab","tabIndexPath","tabSchemaPath","condition","id","disableBulkEdit","timezone","defaultTimezone","timezones","supportedTimezones","source","value","timezoneLabel","baseField","timezoneField","override","fieldsToInsert","virtualField","configFields","flattenFields","paths","split","isHasMany","idx","segment","entries","foundField","find","e","flattenedFields","hasMany","relatedCollection","collections","i","splice"],"mappings":"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"}
|
|
@@ -592,6 +592,88 @@ describe('sanitizeFields', ()=>{
|
|
|
592
592
|
expect(sanitizedBlock.admin?.disableBlockName).toStrictEqual(undefined);
|
|
593
593
|
});
|
|
594
594
|
});
|
|
595
|
+
describe('virtual fields', ()=>{
|
|
596
|
+
it('should assign a noop validate for virtual: true fields', async ()=>{
|
|
597
|
+
const fields = [
|
|
598
|
+
{
|
|
599
|
+
name: 'virtualText',
|
|
600
|
+
type: 'text',
|
|
601
|
+
virtual: true
|
|
602
|
+
}
|
|
603
|
+
];
|
|
604
|
+
const sanitizedField = (await sanitizeFields({
|
|
605
|
+
config,
|
|
606
|
+
collectionConfig,
|
|
607
|
+
fields,
|
|
608
|
+
validRelationships: []
|
|
609
|
+
}))[0];
|
|
610
|
+
expect(sanitizedField.validate).toBeDefined();
|
|
611
|
+
expect(sanitizedField.validate('', {})).toBe(true);
|
|
612
|
+
expect(sanitizedField.validate(undefined, {})).toBe(true);
|
|
613
|
+
});
|
|
614
|
+
it('should assign a noop validate for virtual: "string" fields', async ()=>{
|
|
615
|
+
const fields = [
|
|
616
|
+
{
|
|
617
|
+
name: 'virtualRef',
|
|
618
|
+
type: 'text',
|
|
619
|
+
virtual: 'post.title'
|
|
620
|
+
}
|
|
621
|
+
];
|
|
622
|
+
const sanitizedField = (await sanitizeFields({
|
|
623
|
+
config,
|
|
624
|
+
collectionConfig,
|
|
625
|
+
fields,
|
|
626
|
+
validRelationships: []
|
|
627
|
+
}))[0];
|
|
628
|
+
expect(sanitizedField.validate).toBeDefined();
|
|
629
|
+
expect(sanitizedField.validate(undefined, {})).toBe(true);
|
|
630
|
+
});
|
|
631
|
+
it('should not override an explicit validate on a virtual field', async ()=>{
|
|
632
|
+
const customValidate = ()=>true;
|
|
633
|
+
const fields = [
|
|
634
|
+
{
|
|
635
|
+
name: 'virtualText',
|
|
636
|
+
type: 'text',
|
|
637
|
+
virtual: true,
|
|
638
|
+
validate: customValidate
|
|
639
|
+
}
|
|
640
|
+
];
|
|
641
|
+
const sanitizedField = (await sanitizeFields({
|
|
642
|
+
config,
|
|
643
|
+
collectionConfig,
|
|
644
|
+
fields,
|
|
645
|
+
validRelationships: []
|
|
646
|
+
}))[0];
|
|
647
|
+
expect(sanitizedField.validate).toBe(customValidate);
|
|
648
|
+
});
|
|
649
|
+
it('should assign default type-based validate for non-virtual fields', async ()=>{
|
|
650
|
+
const fields = [
|
|
651
|
+
{
|
|
652
|
+
name: 'normalText',
|
|
653
|
+
type: 'text'
|
|
654
|
+
}
|
|
655
|
+
];
|
|
656
|
+
const sanitizedField = (await sanitizeFields({
|
|
657
|
+
config,
|
|
658
|
+
collectionConfig,
|
|
659
|
+
fields,
|
|
660
|
+
validRelationships: []
|
|
661
|
+
}))[0];
|
|
662
|
+
expect(sanitizedField.validate).toBeDefined();
|
|
663
|
+
// Non-virtual text field should use the text validator which checks required/minLength/etc.
|
|
664
|
+
// Passing undefined with required should fail
|
|
665
|
+
const result = sanitizedField.validate(undefined, {
|
|
666
|
+
required: true,
|
|
667
|
+
req: {
|
|
668
|
+
payload: {
|
|
669
|
+
config: {}
|
|
670
|
+
},
|
|
671
|
+
t: (v)=>v
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
expect(result).not.toBe(true);
|
|
675
|
+
});
|
|
676
|
+
});
|
|
595
677
|
});
|
|
596
678
|
|
|
597
679
|
//# sourceMappingURL=sanitize.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/config/sanitize.spec.ts"],"sourcesContent":["import type { Config } from '../../config/types.js'\nimport type {\n ArrayField,\n Block,\n BlocksField,\n CheckboxField,\n Field,\n NumberField,\n TextField,\n} from './types.js'\n\nimport {\n DuplicateFieldName,\n InvalidFieldName,\n InvalidFieldRelationship,\n MissingFieldType,\n} from '../../errors/index.js'\nimport { sanitizeFields } from './sanitize.js'\nimport { CollectionConfig } from '../../index.js'\nimport { describe, it, expect } from 'vitest'\n\ndescribe('sanitizeFields', () => {\n const config = {} as Config\n const collectionConfig = {} as CollectionConfig\n\n it('should throw on missing type field', async () => {\n const fields: Field[] = [\n // @ts-expect-error\n {\n name: 'Some Collection',\n label: 'some-collection',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(MissingFieldType)\n })\n\n it('should throw on invalid field name', async () => {\n const fields: Field[] = [\n {\n name: 'some.collection',\n type: 'text',\n label: 'some.collection',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(InvalidFieldName)\n })\n\n it('should throw on duplicate field name', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n label: 'someField',\n },\n {\n name: 'someField',\n type: 'text',\n label: 'someField',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(DuplicateFieldName)\n })\n\n it('should throw on duplicate block slug', async () => {\n const fields: Field[] = [\n {\n name: 'blocks',\n type: 'blocks',\n blocks: [\n {\n slug: 'block',\n fields: [\n {\n name: 'blockField',\n type: 'text',\n },\n ],\n },\n {\n slug: 'block',\n fields: [\n {\n name: 'blockField',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(DuplicateFieldName)\n })\n\n describe('auto-labeling', () => {\n it('should populate label if missing', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.name).toStrictEqual('someField')\n expect(sanitizedField.label).toStrictEqual('Some Field')\n expect(sanitizedField.type).toStrictEqual('text')\n })\n\n it('should allow auto-label override', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n label: 'Do not label',\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.name).toStrictEqual('someField')\n expect(sanitizedField.label).toStrictEqual('Do not label')\n expect(sanitizedField.type).toStrictEqual('text')\n })\n\n describe('opt-out', () => {\n it('should allow label opt-out', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.name).toStrictEqual('someField')\n expect(sanitizedField.label).toStrictEqual(false)\n expect(sanitizedField.type).toStrictEqual('text')\n })\n\n it('should allow label opt-out for arrays', async () => {\n const arrayField: ArrayField = {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'itemName',\n type: 'text',\n },\n ],\n label: false,\n }\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields: [arrayField],\n validRelationships: [],\n })\n )[0] as ArrayField\n\n expect(sanitizedField.name).toStrictEqual('items')\n expect(sanitizedField.label).toStrictEqual(false)\n expect(sanitizedField.type).toStrictEqual('array')\n expect(sanitizedField.labels).toBeUndefined()\n })\n\n it('should allow label opt-out for blocks', async () => {\n const fields: Field[] = [\n {\n name: 'noLabelBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n fields: [\n {\n name: 'testNumber',\n type: 'number',\n },\n ],\n },\n ],\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n expect(sanitizedField.name).toStrictEqual('noLabelBlock')\n expect(sanitizedField.label).toStrictEqual(false)\n expect(sanitizedField.type).toStrictEqual('blocks')\n expect(sanitizedField.labels).toBeUndefined()\n })\n })\n\n it('should label arrays with plural and singular', async () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'itemName',\n type: 'text',\n },\n ],\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as ArrayField\n\n expect(sanitizedField.name).toStrictEqual('items')\n expect(sanitizedField.label).toStrictEqual('Items')\n expect(sanitizedField.type).toStrictEqual('array')\n expect(sanitizedField.labels).toMatchObject({ plural: 'Items', singular: 'Item' })\n })\n\n it('should label blocks with plural and singular', async () => {\n const fields: Field[] = [\n {\n name: 'specialBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n fields: [{ name: 'testNumber', type: 'number' }],\n },\n ],\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n expect(sanitizedField.name).toStrictEqual('specialBlock')\n expect(sanitizedField.label).toStrictEqual('Special Block')\n expect(sanitizedField.type).toStrictEqual('blocks')\n expect(sanitizedField.labels).toMatchObject({\n plural: 'Special Blocks',\n singular: 'Special Block',\n })\n\n expect((sanitizedField.blocks[0].fields[0] as NumberField).label).toStrictEqual('Test Number')\n })\n })\n\n describe('relationships', () => {\n it('should not throw on valid relationship', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'some-collection',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).not.toThrow()\n })\n\n it('should not throw on valid relationship - multiple', async () => {\n const validRelationships = ['some-collection', 'another-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: ['some-collection', 'another-collection'],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).not.toThrow()\n })\n\n it('should not throw on valid relationship inside blocks', async () => {\n const validRelationships = ['some-collection']\n const relationshipBlock: Block = {\n slug: 'relationshipBlock',\n fields: [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'some-collection',\n },\n ],\n }\n\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [relationshipBlock],\n label: 'Layout Blocks',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).not.toThrow()\n })\n\n it('should throw on invalid relationship', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'not-valid',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow(InvalidFieldRelationship)\n })\n\n it('should throw on invalid relationship - multiple', async () => {\n const validRelationships = ['some-collection', 'another-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: ['some-collection', 'not-valid'],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow(InvalidFieldRelationship)\n })\n\n it('should throw on invalid relationship inside blocks', async () => {\n const validRelationships = ['some-collection']\n const relationshipBlock: Block = {\n slug: 'relationshipBlock',\n fields: [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'not-valid',\n },\n ],\n }\n\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [relationshipBlock],\n label: 'Layout Blocks',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow(InvalidFieldRelationship)\n })\n\n it('should throw on empty relationTo array', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: [],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow('has an empty relationTo array')\n })\n\n it('should throw on empty relationTo array for upload field', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Upload',\n type: 'upload',\n label: 'my-upload',\n relationTo: [],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow('has an empty relationTo array')\n })\n\n it('should throw on empty relationTo array inside blocks', async () => {\n const validRelationships = ['some-collection']\n const relationshipBlock: Block = {\n slug: 'relationshipBlock',\n fields: [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: [],\n },\n ],\n }\n\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [relationshipBlock],\n label: 'Layout Blocks',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow('has an empty relationTo array')\n })\n\n it('should defaultValue of checkbox to false if required and undefined', async () => {\n const fields: Field[] = [\n {\n name: 'My Checkbox',\n type: 'checkbox',\n required: true,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as CheckboxField\n\n expect(sanitizedField.defaultValue).toStrictEqual(false)\n })\n\n it('should return empty field array if no fields', async () => {\n const sanitizedFields = await sanitizeFields({\n config,\n collectionConfig,\n fields: [],\n validRelationships: [],\n })\n\n expect(sanitizedFields).toStrictEqual([])\n })\n })\n describe('blocks', () => {\n it('should maintain admin.blockName true after sanitization', async () => {\n const fields: Field[] = [\n {\n name: 'noLabelBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n admin: {\n disableBlockName: true,\n },\n fields: [\n {\n name: 'testNumber',\n type: 'number',\n },\n ],\n },\n ],\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n const sanitizedBlock = sanitizedField.blocks[0]\n\n expect(sanitizedBlock.admin?.disableBlockName).toStrictEqual(true)\n })\n it('should default admin.disableBlockName to true after sanitization', async () => {\n const fields: Field[] = [\n {\n name: 'noLabelBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n fields: [\n {\n name: 'testNumber',\n type: 'number',\n },\n ],\n },\n ],\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n const sanitizedBlock = sanitizedField.blocks[0]\n\n expect(sanitizedBlock.admin?.disableBlockName).toStrictEqual(undefined)\n })\n })\n})\n"],"names":["DuplicateFieldName","InvalidFieldName","InvalidFieldRelationship","MissingFieldType","sanitizeFields","describe","it","expect","config","collectionConfig","fields","name","label","validRelationships","rejects","toThrow","type","blocks","slug","sanitizedField","toStrictEqual","arrayField","labels","toBeUndefined","toMatchObject","plural","singular","relationTo","not","relationshipBlock","required","defaultValue","sanitizedFields","admin","disableBlockName","sanitizedBlock","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/config/sanitize.spec.ts"],"sourcesContent":["import type { Config } from '../../config/types.js'\nimport type {\n ArrayField,\n Block,\n BlocksField,\n CheckboxField,\n Field,\n NumberField,\n TextField,\n} from './types.js'\n\nimport {\n DuplicateFieldName,\n InvalidFieldName,\n InvalidFieldRelationship,\n MissingFieldType,\n} from '../../errors/index.js'\nimport { sanitizeFields } from './sanitize.js'\nimport { CollectionConfig } from '../../index.js'\nimport { describe, it, expect } from 'vitest'\n\ndescribe('sanitizeFields', () => {\n const config = {} as Config\n const collectionConfig = {} as CollectionConfig\n\n it('should throw on missing type field', async () => {\n const fields: Field[] = [\n // @ts-expect-error\n {\n name: 'Some Collection',\n label: 'some-collection',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(MissingFieldType)\n })\n\n it('should throw on invalid field name', async () => {\n const fields: Field[] = [\n {\n name: 'some.collection',\n type: 'text',\n label: 'some.collection',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(InvalidFieldName)\n })\n\n it('should throw on duplicate field name', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n label: 'someField',\n },\n {\n name: 'someField',\n type: 'text',\n label: 'someField',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(DuplicateFieldName)\n })\n\n it('should throw on duplicate block slug', async () => {\n const fields: Field[] = [\n {\n name: 'blocks',\n type: 'blocks',\n blocks: [\n {\n slug: 'block',\n fields: [\n {\n name: 'blockField',\n type: 'text',\n },\n ],\n },\n {\n slug: 'block',\n fields: [\n {\n name: 'blockField',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n }).rejects.toThrow(DuplicateFieldName)\n })\n\n describe('auto-labeling', () => {\n it('should populate label if missing', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.name).toStrictEqual('someField')\n expect(sanitizedField.label).toStrictEqual('Some Field')\n expect(sanitizedField.type).toStrictEqual('text')\n })\n\n it('should allow auto-label override', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n label: 'Do not label',\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.name).toStrictEqual('someField')\n expect(sanitizedField.label).toStrictEqual('Do not label')\n expect(sanitizedField.type).toStrictEqual('text')\n })\n\n describe('opt-out', () => {\n it('should allow label opt-out', async () => {\n const fields: Field[] = [\n {\n name: 'someField',\n type: 'text',\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.name).toStrictEqual('someField')\n expect(sanitizedField.label).toStrictEqual(false)\n expect(sanitizedField.type).toStrictEqual('text')\n })\n\n it('should allow label opt-out for arrays', async () => {\n const arrayField: ArrayField = {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'itemName',\n type: 'text',\n },\n ],\n label: false,\n }\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields: [arrayField],\n validRelationships: [],\n })\n )[0] as ArrayField\n\n expect(sanitizedField.name).toStrictEqual('items')\n expect(sanitizedField.label).toStrictEqual(false)\n expect(sanitizedField.type).toStrictEqual('array')\n expect(sanitizedField.labels).toBeUndefined()\n })\n\n it('should allow label opt-out for blocks', async () => {\n const fields: Field[] = [\n {\n name: 'noLabelBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n fields: [\n {\n name: 'testNumber',\n type: 'number',\n },\n ],\n },\n ],\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n expect(sanitizedField.name).toStrictEqual('noLabelBlock')\n expect(sanitizedField.label).toStrictEqual(false)\n expect(sanitizedField.type).toStrictEqual('blocks')\n expect(sanitizedField.labels).toBeUndefined()\n })\n })\n\n it('should label arrays with plural and singular', async () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'itemName',\n type: 'text',\n },\n ],\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as ArrayField\n\n expect(sanitizedField.name).toStrictEqual('items')\n expect(sanitizedField.label).toStrictEqual('Items')\n expect(sanitizedField.type).toStrictEqual('array')\n expect(sanitizedField.labels).toMatchObject({ plural: 'Items', singular: 'Item' })\n })\n\n it('should label blocks with plural and singular', async () => {\n const fields: Field[] = [\n {\n name: 'specialBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n fields: [{ name: 'testNumber', type: 'number' }],\n },\n ],\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n expect(sanitizedField.name).toStrictEqual('specialBlock')\n expect(sanitizedField.label).toStrictEqual('Special Block')\n expect(sanitizedField.type).toStrictEqual('blocks')\n expect(sanitizedField.labels).toMatchObject({\n plural: 'Special Blocks',\n singular: 'Special Block',\n })\n\n expect((sanitizedField.blocks[0].fields[0] as NumberField).label).toStrictEqual('Test Number')\n })\n })\n\n describe('relationships', () => {\n it('should not throw on valid relationship', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'some-collection',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).not.toThrow()\n })\n\n it('should not throw on valid relationship - multiple', async () => {\n const validRelationships = ['some-collection', 'another-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: ['some-collection', 'another-collection'],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).not.toThrow()\n })\n\n it('should not throw on valid relationship inside blocks', async () => {\n const validRelationships = ['some-collection']\n const relationshipBlock: Block = {\n slug: 'relationshipBlock',\n fields: [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'some-collection',\n },\n ],\n }\n\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [relationshipBlock],\n label: 'Layout Blocks',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).not.toThrow()\n })\n\n it('should throw on invalid relationship', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'not-valid',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow(InvalidFieldRelationship)\n })\n\n it('should throw on invalid relationship - multiple', async () => {\n const validRelationships = ['some-collection', 'another-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: ['some-collection', 'not-valid'],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow(InvalidFieldRelationship)\n })\n\n it('should throw on invalid relationship inside blocks', async () => {\n const validRelationships = ['some-collection']\n const relationshipBlock: Block = {\n slug: 'relationshipBlock',\n fields: [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: 'not-valid',\n },\n ],\n }\n\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [relationshipBlock],\n label: 'Layout Blocks',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow(InvalidFieldRelationship)\n })\n\n it('should throw on empty relationTo array', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: [],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow('has an empty relationTo array')\n })\n\n it('should throw on empty relationTo array for upload field', async () => {\n const validRelationships = ['some-collection']\n const fields: Field[] = [\n {\n name: 'My Upload',\n type: 'upload',\n label: 'my-upload',\n relationTo: [],\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow('has an empty relationTo array')\n })\n\n it('should throw on empty relationTo array inside blocks', async () => {\n const validRelationships = ['some-collection']\n const relationshipBlock: Block = {\n slug: 'relationshipBlock',\n fields: [\n {\n name: 'My Relationship',\n type: 'relationship',\n label: 'my-relationship',\n relationTo: [],\n },\n ],\n }\n\n const fields: Field[] = [\n {\n name: 'layout',\n type: 'blocks',\n blocks: [relationshipBlock],\n label: 'Layout Blocks',\n },\n ]\n\n await expect(async () => {\n await sanitizeFields({ config, collectionConfig, fields, validRelationships })\n }).rejects.toThrow('has an empty relationTo array')\n })\n\n it('should defaultValue of checkbox to false if required and undefined', async () => {\n const fields: Field[] = [\n {\n name: 'My Checkbox',\n type: 'checkbox',\n required: true,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as CheckboxField\n\n expect(sanitizedField.defaultValue).toStrictEqual(false)\n })\n\n it('should return empty field array if no fields', async () => {\n const sanitizedFields = await sanitizeFields({\n config,\n collectionConfig,\n fields: [],\n validRelationships: [],\n })\n\n expect(sanitizedFields).toStrictEqual([])\n })\n })\n describe('blocks', () => {\n it('should maintain admin.blockName true after sanitization', async () => {\n const fields: Field[] = [\n {\n name: 'noLabelBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n admin: {\n disableBlockName: true,\n },\n fields: [\n {\n name: 'testNumber',\n type: 'number',\n },\n ],\n },\n ],\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n const sanitizedBlock = sanitizedField.blocks[0]\n\n expect(sanitizedBlock.admin?.disableBlockName).toStrictEqual(true)\n })\n it('should default admin.disableBlockName to true after sanitization', async () => {\n const fields: Field[] = [\n {\n name: 'noLabelBlock',\n type: 'blocks',\n blocks: [\n {\n slug: 'number',\n fields: [\n {\n name: 'testNumber',\n type: 'number',\n },\n ],\n },\n ],\n label: false,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as BlocksField\n\n const sanitizedBlock = sanitizedField.blocks[0]\n\n expect(sanitizedBlock.admin?.disableBlockName).toStrictEqual(undefined)\n })\n })\n\n describe('virtual fields', () => {\n it('should assign a noop validate for virtual: true fields', async () => {\n const fields: Field[] = [\n {\n name: 'virtualText',\n type: 'text',\n virtual: true,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.validate).toBeDefined()\n expect(sanitizedField.validate!('', {} as any)).toBe(true)\n expect(sanitizedField.validate!(undefined as any, {} as any)).toBe(true)\n })\n\n it('should assign a noop validate for virtual: \"string\" fields', async () => {\n const fields: Field[] = [\n {\n name: 'virtualRef',\n type: 'text',\n virtual: 'post.title',\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.validate).toBeDefined()\n expect(sanitizedField.validate!(undefined as any, {} as any)).toBe(true)\n })\n\n it('should not override an explicit validate on a virtual field', async () => {\n const customValidate = () => true as const\n const fields: Field[] = [\n {\n name: 'virtualText',\n type: 'text',\n virtual: true,\n validate: customValidate,\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.validate).toBe(customValidate)\n })\n\n it('should assign default type-based validate for non-virtual fields', async () => {\n const fields: Field[] = [\n {\n name: 'normalText',\n type: 'text',\n },\n ]\n\n const sanitizedField = (\n await sanitizeFields({\n config,\n collectionConfig,\n fields,\n validRelationships: [],\n })\n )[0] as TextField\n\n expect(sanitizedField.validate).toBeDefined()\n // Non-virtual text field should use the text validator which checks required/minLength/etc.\n // Passing undefined with required should fail\n const result = sanitizedField.validate!(undefined as any, { required: true, req: { payload: { config: {} }, t: ((v: string) => v) as any } } as any)\n expect(result).not.toBe(true)\n })\n })\n})\n"],"names":["DuplicateFieldName","InvalidFieldName","InvalidFieldRelationship","MissingFieldType","sanitizeFields","describe","it","expect","config","collectionConfig","fields","name","label","validRelationships","rejects","toThrow","type","blocks","slug","sanitizedField","toStrictEqual","arrayField","labels","toBeUndefined","toMatchObject","plural","singular","relationTo","not","relationshipBlock","required","defaultValue","sanitizedFields","admin","disableBlockName","sanitizedBlock","undefined","virtual","validate","toBeDefined","toBe","customValidate","result","req","payload","t","v"],"mappings":"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"}
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { SanitizedJoin, SanitizedJoins } from '../../collections/config/types.js';
|
|
2
2
|
import type { Config } from '../../config/types.js';
|
|
3
3
|
import type { FlattenedJoinField, JoinField } from './types.js';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Info about an orderable join field, collected during sanitization
|
|
6
|
+
* and processed after all collections are sanitized.
|
|
7
|
+
*/
|
|
8
|
+
export type OrderableJoinInfo = {
|
|
9
|
+
/** The `on` path of the join field */
|
|
10
|
+
joinFieldOn: string;
|
|
11
|
+
/** The name of the order field to add (e.g., `_posts_myJoin_order`) */
|
|
12
|
+
orderFieldName: string;
|
|
13
|
+
/** The collection that will receive the order field */
|
|
14
|
+
targetCollectionSlug: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const sanitizeJoinField: ({ config, field, joinPath, joins, orderableJoins, parentIsLocalized, polymorphicJoins, validateOnly, }: {
|
|
5
17
|
config: Config;
|
|
6
18
|
field: FlattenedJoinField | JoinField;
|
|
7
19
|
joinPath?: string;
|
|
8
20
|
joins?: SanitizedJoins;
|
|
21
|
+
/** Tracker for orderable join fields - populated during sanitization */
|
|
22
|
+
orderableJoins?: OrderableJoinInfo[];
|
|
9
23
|
parentIsLocalized: boolean;
|
|
10
24
|
polymorphicJoins?: SanitizedJoin[];
|
|
11
25
|
validateOnly?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeJoinField.d.ts","sourceRoot":"","sources":["../../../src/fields/config/sanitizeJoinField.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AACtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"sanitizeJoinField.d.ts","sourceRoot":"","sources":["../../../src/fields/config/sanitizeJoinField.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AACtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAI/D;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,uEAAuE;IACvE,cAAc,EAAE,MAAM,CAAA;IACtB,uDAAuD;IACvD,oBAAoB,EAAE,MAAM,CAAA;CAC7B,CAAA;AAKD,eAAO,MAAM,iBAAiB,2GAS3B;IACD,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,wEAAwE;IACxE,cAAc,CAAC,EAAE,iBAAiB,EAAE,CAAA;IACpC,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAA;IAClC,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,SA8GA,CAAA"}
|
|
@@ -2,7 +2,7 @@ import { APIError } from '../../errors/index.js';
|
|
|
2
2
|
import { InvalidFieldJoin } from '../../errors/InvalidFieldJoin.js';
|
|
3
3
|
import { flattenAllFields } from '../../utilities/flattenAllFields.js';
|
|
4
4
|
import { getFieldByPath } from '../../utilities/getFieldByPath.js';
|
|
5
|
-
export const sanitizeJoinField = ({ config, field, joinPath, joins, parentIsLocalized, polymorphicJoins, validateOnly })=>{
|
|
5
|
+
export const sanitizeJoinField = ({ config, field, joinPath, joins, orderableJoins, parentIsLocalized, polymorphicJoins, validateOnly })=>{
|
|
6
6
|
// the `joins` arg is not passed for globals or when recursing on fields that do not allow a join field
|
|
7
7
|
if (typeof joins === 'undefined') {
|
|
8
8
|
throw new APIError('Join fields cannot be added to arrays, blocks or globals.');
|
|
@@ -17,6 +17,10 @@ export const sanitizeJoinField = ({ config, field, joinPath, joins, parentIsLoca
|
|
|
17
17
|
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
|
18
18
|
targetField: undefined
|
|
19
19
|
};
|
|
20
|
+
// Orderable joins must target a single collection
|
|
21
|
+
if (field.orderable && Array.isArray(field.collection)) {
|
|
22
|
+
throw new APIError('Orderable joins must target a single collection');
|
|
23
|
+
}
|
|
20
24
|
if (Array.isArray(field.collection)) {
|
|
21
25
|
for (const collection of field.collection){
|
|
22
26
|
const sanitizedField = {
|
|
@@ -63,6 +67,18 @@ export const sanitizeJoinField = ({ config, field, joinPath, joins, parentIsLoca
|
|
|
63
67
|
if (validateOnly) {
|
|
64
68
|
return;
|
|
65
69
|
}
|
|
70
|
+
// Track orderable joins for post-sanitization processing
|
|
71
|
+
if (field.orderable && orderableJoins) {
|
|
72
|
+
const prefix = joinPath ? joinPath.replace(/\./g, '_') + '_' : '';
|
|
73
|
+
const orderFieldName = `_${field.collection}_${prefix}${field.name}_order`;
|
|
74
|
+
// Set defaultSort on the join field
|
|
75
|
+
field.defaultSort = field.defaultSort ?? orderFieldName;
|
|
76
|
+
orderableJoins.push({
|
|
77
|
+
joinFieldOn: field.on,
|
|
78
|
+
orderFieldName,
|
|
79
|
+
targetCollectionSlug: field.collection
|
|
80
|
+
});
|
|
81
|
+
}
|
|
66
82
|
join.targetField = relationshipField.field;
|
|
67
83
|
// override the join field localized property to use whatever the relationship field has
|
|
68
84
|
// or if it's nested to a localized array / blocks / tabs / group
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/config/sanitizeJoinField.ts"],"sourcesContent":["import type { SanitizedJoin, SanitizedJoins } from '../../collections/config/types.js'\nimport type { Config } from '../../config/types.js'\nimport type { FlattenedJoinField, JoinField } from './types.js'\n\nimport { APIError } from '../../errors/index.js'\nimport { InvalidFieldJoin } from '../../errors/InvalidFieldJoin.js'\nimport { flattenAllFields } from '../../utilities/flattenAllFields.js'\nimport { getFieldByPath } from '../../utilities/getFieldByPath.js'\n\nexport const sanitizeJoinField = ({\n config,\n field,\n joinPath,\n joins,\n parentIsLocalized,\n polymorphicJoins,\n validateOnly,\n}: {\n config: Config\n field: FlattenedJoinField | JoinField\n joinPath?: string\n joins?: SanitizedJoins\n parentIsLocalized: boolean\n polymorphicJoins?: SanitizedJoin[]\n validateOnly?: boolean\n}) => {\n // the `joins` arg is not passed for globals or when recursing on fields that do not allow a join field\n if (typeof joins === 'undefined') {\n throw new APIError('Join fields cannot be added to arrays, blocks or globals.')\n }\n if (typeof field.maxDepth === 'undefined') {\n field.maxDepth = 1\n }\n const join: SanitizedJoin = {\n field,\n joinPath: `${joinPath ? joinPath + '.' : ''}${field.name}`,\n parentIsLocalized,\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n targetField: undefined,\n }\n\n if (Array.isArray(field.collection)) {\n for (const collection of field.collection) {\n const sanitizedField = {\n ...field,\n collection,\n } as FlattenedJoinField\n\n sanitizeJoinField({\n config,\n field: sanitizedField,\n joinPath,\n joins,\n parentIsLocalized,\n polymorphicJoins,\n validateOnly: true,\n })\n }\n\n if (Array.isArray(polymorphicJoins)) {\n polymorphicJoins.push(join)\n }\n\n return\n }\n\n const joinCollection = config.collections?.find(\n (collection) => collection.slug === field.collection,\n )\n if (!joinCollection) {\n throw new InvalidFieldJoin(field)\n }\n\n const relationshipField = getFieldByPath({\n fields: flattenAllFields({ cache: true, fields: joinCollection.fields }),\n path: field.on,\n })\n\n if (\n !relationshipField ||\n (relationshipField.field.type !== 'relationship' && relationshipField.field.type !== 'upload')\n ) {\n throw new InvalidFieldJoin(join.field)\n }\n\n if (relationshipField.pathHasLocalized) {\n join.getForeignPath = ({ locale }) => {\n return relationshipField.localizedPath.replace('<locale>', locale!)\n }\n }\n\n if (!relationshipField.field.index && !relationshipField.field.unique) {\n relationshipField.field.index = true\n }\n\n if (validateOnly) {\n return\n }\n\n join.targetField = relationshipField.field\n\n // override the join field localized property to use whatever the relationship field has\n // or if it's nested to a localized array / blocks / tabs / group\n field.localized = relationshipField.field.localized\n // override the join field hasMany property to use whatever the relationship field has\n field.hasMany = relationshipField.field.hasMany\n\n // @ts-expect-error converting JoinField to FlattenedJoinField to track targetField\n field.targetField = join.targetField\n\n if (!joins[field.collection]) {\n joins[field.collection] = [join]\n } else {\n joins[field.collection]?.push(join)\n }\n}\n"],"names":["APIError","InvalidFieldJoin","flattenAllFields","getFieldByPath","sanitizeJoinField","config","field","joinPath","joins","parentIsLocalized","polymorphicJoins","validateOnly","maxDepth","join","name","targetField","undefined","Array","isArray","collection","sanitizedField","push","joinCollection","collections","find","slug","relationshipField","fields","cache","path","on","type","pathHasLocalized","getForeignPath","locale","localizedPath","replace","index","unique","localized","hasMany"],"mappings":"AAIA,SAASA,QAAQ,QAAQ,wBAAuB;
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/config/sanitizeJoinField.ts"],"sourcesContent":["import type { SanitizedJoin, SanitizedJoins } from '../../collections/config/types.js'\nimport type { Config } from '../../config/types.js'\nimport type { FlattenedJoinField, JoinField } from './types.js'\n\nimport { APIError } from '../../errors/index.js'\n\n/**\n * Info about an orderable join field, collected during sanitization\n * and processed after all collections are sanitized.\n */\nexport type OrderableJoinInfo = {\n /** The `on` path of the join field */\n joinFieldOn: string\n /** The name of the order field to add (e.g., `_posts_myJoin_order`) */\n orderFieldName: string\n /** The collection that will receive the order field */\n targetCollectionSlug: string\n}\nimport { InvalidFieldJoin } from '../../errors/InvalidFieldJoin.js'\nimport { flattenAllFields } from '../../utilities/flattenAllFields.js'\nimport { getFieldByPath } from '../../utilities/getFieldByPath.js'\n\nexport const sanitizeJoinField = ({\n config,\n field,\n joinPath,\n joins,\n orderableJoins,\n parentIsLocalized,\n polymorphicJoins,\n validateOnly,\n}: {\n config: Config\n field: FlattenedJoinField | JoinField\n joinPath?: string\n joins?: SanitizedJoins\n /** Tracker for orderable join fields - populated during sanitization */\n orderableJoins?: OrderableJoinInfo[]\n parentIsLocalized: boolean\n polymorphicJoins?: SanitizedJoin[]\n validateOnly?: boolean\n}) => {\n // the `joins` arg is not passed for globals or when recursing on fields that do not allow a join field\n if (typeof joins === 'undefined') {\n throw new APIError('Join fields cannot be added to arrays, blocks or globals.')\n }\n if (typeof field.maxDepth === 'undefined') {\n field.maxDepth = 1\n }\n const join: SanitizedJoin = {\n field,\n joinPath: `${joinPath ? joinPath + '.' : ''}${field.name}`,\n parentIsLocalized,\n // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n targetField: undefined,\n }\n\n // Orderable joins must target a single collection\n if (field.orderable && Array.isArray(field.collection)) {\n throw new APIError('Orderable joins must target a single collection')\n }\n\n if (Array.isArray(field.collection)) {\n for (const collection of field.collection) {\n const sanitizedField = {\n ...field,\n collection,\n } as FlattenedJoinField\n\n sanitizeJoinField({\n config,\n field: sanitizedField,\n joinPath,\n joins,\n parentIsLocalized,\n polymorphicJoins,\n validateOnly: true,\n })\n }\n\n if (Array.isArray(polymorphicJoins)) {\n polymorphicJoins.push(join)\n }\n\n return\n }\n\n const joinCollection = config.collections?.find(\n (collection) => collection.slug === field.collection,\n )\n if (!joinCollection) {\n throw new InvalidFieldJoin(field)\n }\n\n const relationshipField = getFieldByPath({\n fields: flattenAllFields({ cache: true, fields: joinCollection.fields }),\n path: field.on,\n })\n\n if (\n !relationshipField ||\n (relationshipField.field.type !== 'relationship' && relationshipField.field.type !== 'upload')\n ) {\n throw new InvalidFieldJoin(join.field)\n }\n\n if (relationshipField.pathHasLocalized) {\n join.getForeignPath = ({ locale }) => {\n return relationshipField.localizedPath.replace('<locale>', locale!)\n }\n }\n\n if (!relationshipField.field.index && !relationshipField.field.unique) {\n relationshipField.field.index = true\n }\n\n if (validateOnly) {\n return\n }\n\n // Track orderable joins for post-sanitization processing\n if (field.orderable && orderableJoins) {\n const prefix = joinPath ? joinPath.replace(/\\./g, '_') + '_' : ''\n const orderFieldName = `_${field.collection}_${prefix}${field.name}_order`\n\n // Set defaultSort on the join field\n field.defaultSort = field.defaultSort ?? orderFieldName\n\n orderableJoins.push({\n joinFieldOn: field.on,\n orderFieldName,\n targetCollectionSlug: field.collection,\n })\n }\n\n join.targetField = relationshipField.field\n\n // override the join field localized property to use whatever the relationship field has\n // or if it's nested to a localized array / blocks / tabs / group\n field.localized = relationshipField.field.localized\n // override the join field hasMany property to use whatever the relationship field has\n field.hasMany = relationshipField.field.hasMany\n\n // @ts-expect-error converting JoinField to FlattenedJoinField to track targetField\n field.targetField = join.targetField\n\n if (!joins[field.collection]) {\n joins[field.collection] = [join]\n } else {\n joins[field.collection]?.push(join)\n }\n}\n"],"names":["APIError","InvalidFieldJoin","flattenAllFields","getFieldByPath","sanitizeJoinField","config","field","joinPath","joins","orderableJoins","parentIsLocalized","polymorphicJoins","validateOnly","maxDepth","join","name","targetField","undefined","orderable","Array","isArray","collection","sanitizedField","push","joinCollection","collections","find","slug","relationshipField","fields","cache","path","on","type","pathHasLocalized","getForeignPath","locale","localizedPath","replace","index","unique","prefix","orderFieldName","defaultSort","joinFieldOn","targetCollectionSlug","localized","hasMany"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"findOne.d.ts","sourceRoot":"","sources":["../../../src/globals/operations/findOne.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAA;AAE7E,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EAEX,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAI/D,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,uCAAuC,CAAA;AAQrF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,qBAAqB,CAAA;IACnC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,GAAG,EAAE,cAAc,CAAA;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,GACnD,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAA;AAEjD,eAAO,MAAM,gBAAgB,GAAU,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAChE,iBAAiB,KACtB,OAAO,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"findOne.d.ts","sourceRoot":"","sources":["../../../src/globals/operations/findOne.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAA;AAE7E,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EAEX,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAI/D,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,uCAAuC,CAAA;AAQrF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,qBAAqB,CAAA;IACnC,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,GAAG,EAAE,cAAc,CAAA;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,GACnD,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAA;AAEjD,eAAO,MAAM,gBAAgB,GAAU,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QAChE,iBAAiB,KACtB,OAAO,CAAC,CAAC,CA6OX,CAAA"}
|
|
@@ -8,7 +8,7 @@ import { killTransaction } from '../../utilities/killTransaction.js';
|
|
|
8
8
|
import { sanitizeSelect } from '../../utilities/sanitizeSelect.js';
|
|
9
9
|
import { replaceWithDraftIfAvailable } from '../../versions/drafts/replaceWithDraftIfAvailable.js';
|
|
10
10
|
export const findOneOperation = async (args)=>{
|
|
11
|
-
const { slug, depth, draft: replaceWithVersion = false, flattenLocales, globalConfig, includeLockStatus: includeLockStatusFromArgs, overrideAccess = false, populate, req: { fallbackLocale, locale }, req, select: incomingSelect, showHiddenFields } = args;
|
|
11
|
+
const { slug, depth, disableErrors, draft: replaceWithVersion = false, flattenLocales, globalConfig, includeLockStatus: includeLockStatusFromArgs, overrideAccess = false, populate, req: { fallbackLocale, locale }, req, select: incomingSelect, showHiddenFields } = args;
|
|
12
12
|
const includeLockStatus = includeLockStatusFromArgs && req.payload.collections?.[lockedDocumentsCollectionSlug];
|
|
13
13
|
try {
|
|
14
14
|
// /////////////////////////////////////
|
|
@@ -32,11 +32,15 @@ export const findOneOperation = async (args)=>{
|
|
|
32
32
|
let accessResult;
|
|
33
33
|
if (!overrideAccess) {
|
|
34
34
|
accessResult = await executeAccess({
|
|
35
|
+
disableErrors,
|
|
35
36
|
req
|
|
36
37
|
}, globalConfig.access.read);
|
|
37
38
|
}
|
|
38
39
|
if (accessResult === false) {
|
|
39
|
-
|
|
40
|
+
if (!disableErrors) {
|
|
41
|
+
throw new NotFound(req.t);
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
40
44
|
}
|
|
41
45
|
const select = sanitizeSelect({
|
|
42
46
|
fields: globalConfig.flattenedFields,
|
|
@@ -64,7 +68,10 @@ export const findOneOperation = async (args)=>{
|
|
|
64
68
|
// Check if no document was returned (Postgres returns {} instead of null)
|
|
65
69
|
const hasDoc = docFromDB && Object.keys(docFromDB).length > 0;
|
|
66
70
|
if (!hasDoc && !args.data && !overrideAccess && accessResult !== true) {
|
|
67
|
-
|
|
71
|
+
if (!disableErrors) {
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
68
75
|
}
|
|
69
76
|
let doc = args.data ?? (hasDoc ? docFromDB : null) ?? {};
|
|
70
77
|
// /////////////////////////////////////
|