payload 3.0.0-beta.77 → 3.0.0-beta.79
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/bin.js +33 -10
- package/dist/admin/RichText.d.ts +20 -17
- package/dist/admin/RichText.d.ts.map +1 -1
- package/dist/admin/RichText.js.map +1 -1
- package/dist/admin/elements/Cell.d.ts +11 -26
- package/dist/admin/elements/Cell.d.ts.map +1 -1
- package/dist/admin/elements/Cell.js.map +1 -1
- package/dist/admin/elements/Tab.d.ts +16 -15
- package/dist/admin/elements/Tab.d.ts.map +1 -1
- package/dist/admin/elements/Tab.js.map +1 -1
- package/dist/admin/fields/Array.d.ts +6 -13
- package/dist/admin/fields/Array.d.ts.map +1 -1
- package/dist/admin/fields/Array.js.map +1 -1
- package/dist/admin/fields/Blocks.d.ts +8 -25
- package/dist/admin/fields/Blocks.d.ts.map +1 -1
- package/dist/admin/fields/Blocks.js.map +1 -1
- package/dist/admin/fields/Checkbox.d.ts +9 -9
- package/dist/admin/fields/Checkbox.d.ts.map +1 -1
- package/dist/admin/fields/Checkbox.js.map +1 -1
- package/dist/admin/fields/Code.d.ts +5 -7
- package/dist/admin/fields/Code.d.ts.map +1 -1
- package/dist/admin/fields/Code.js.map +1 -1
- package/dist/admin/fields/Collapsible.d.ts +3 -4
- package/dist/admin/fields/Collapsible.d.ts.map +1 -1
- package/dist/admin/fields/Collapsible.js.map +1 -1
- package/dist/admin/fields/Date.d.ts +4 -7
- package/dist/admin/fields/Date.d.ts.map +1 -1
- package/dist/admin/fields/Date.js.map +1 -1
- package/dist/admin/fields/Email.d.ts +5 -7
- package/dist/admin/fields/Email.d.ts.map +1 -1
- package/dist/admin/fields/Email.js.map +1 -1
- package/dist/admin/fields/Group.d.ts +3 -6
- package/dist/admin/fields/Group.d.ts.map +1 -1
- package/dist/admin/fields/Group.js.map +1 -1
- package/dist/admin/fields/Hidden.d.ts +7 -5
- package/dist/admin/fields/Hidden.d.ts.map +1 -1
- package/dist/admin/fields/Hidden.js.map +1 -1
- package/dist/admin/fields/JSON.d.ts +4 -7
- package/dist/admin/fields/JSON.d.ts.map +1 -1
- package/dist/admin/fields/JSON.js.map +1 -1
- package/dist/admin/fields/Number.d.ts +5 -12
- package/dist/admin/fields/Number.d.ts.map +1 -1
- package/dist/admin/fields/Number.js.map +1 -1
- package/dist/admin/fields/Point.d.ts +4 -6
- package/dist/admin/fields/Point.d.ts.map +1 -1
- package/dist/admin/fields/Point.js.map +1 -1
- package/dist/admin/fields/Radio.d.ts +6 -9
- package/dist/admin/fields/Radio.d.ts.map +1 -1
- package/dist/admin/fields/Radio.js.map +1 -1
- package/dist/admin/fields/Relationship.d.ts +4 -9
- package/dist/admin/fields/Relationship.d.ts.map +1 -1
- package/dist/admin/fields/Relationship.js.map +1 -1
- package/dist/admin/fields/RichText.d.ts +5 -6
- package/dist/admin/fields/RichText.d.ts.map +1 -1
- package/dist/admin/fields/RichText.js.map +1 -1
- package/dist/admin/fields/Row.d.ts +3 -4
- package/dist/admin/fields/Row.d.ts.map +1 -1
- package/dist/admin/fields/Row.js.map +1 -1
- package/dist/admin/fields/Select.d.ts +6 -11
- package/dist/admin/fields/Select.d.ts.map +1 -1
- package/dist/admin/fields/Select.js.map +1 -1
- package/dist/admin/fields/Tabs.d.ts +8 -12
- package/dist/admin/fields/Tabs.d.ts.map +1 -1
- package/dist/admin/fields/Tabs.js.map +1 -1
- package/dist/admin/fields/Text.d.ts +7 -13
- package/dist/admin/fields/Text.d.ts.map +1 -1
- package/dist/admin/fields/Text.js.map +1 -1
- package/dist/admin/fields/Textarea.d.ts +7 -9
- package/dist/admin/fields/Textarea.d.ts.map +1 -1
- package/dist/admin/fields/Textarea.js.map +1 -1
- package/dist/admin/fields/Upload.d.ts +6 -7
- package/dist/admin/fields/Upload.d.ts.map +1 -1
- package/dist/admin/fields/Upload.js.map +1 -1
- package/dist/admin/forms/Error.d.ts +10 -10
- package/dist/admin/forms/Error.d.ts.map +1 -1
- package/dist/admin/forms/Error.js.map +1 -1
- package/dist/admin/forms/Field.d.ts +17 -24
- package/dist/admin/forms/Field.d.ts.map +1 -1
- package/dist/admin/forms/Field.js +1 -0
- package/dist/admin/forms/Field.js.map +1 -1
- package/dist/admin/forms/FieldDescription.d.ts +10 -9
- package/dist/admin/forms/FieldDescription.d.ts.map +1 -1
- package/dist/admin/forms/FieldDescription.js.map +1 -1
- package/dist/admin/forms/Label.d.ts +14 -15
- package/dist/admin/forms/Label.d.ts.map +1 -1
- package/dist/admin/forms/Label.js.map +1 -1
- package/dist/admin/types.d.ts +30 -11
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/admin/types.js.map +1 -1
- package/dist/admin/views/types.d.ts +21 -13
- package/dist/admin/views/types.d.ts.map +1 -1
- package/dist/admin/views/types.js.map +1 -1
- package/dist/auth/baseFields/apiKey.js +2 -2
- package/dist/auth/baseFields/apiKey.js.map +1 -1
- package/dist/auth/baseFields/email.js +1 -1
- package/dist/auth/baseFields/email.js.map +1 -1
- package/dist/auth/baseFields/username.js +1 -1
- package/dist/auth/baseFields/username.js.map +1 -1
- package/dist/auth/baseFields/verification.js +1 -1
- package/dist/auth/baseFields/verification.js.map +1 -1
- package/dist/auth/strategies/jwt.d.ts.map +1 -1
- package/dist/auth/strategies/jwt.js +57 -24
- package/dist/auth/strategies/jwt.js.map +1 -1
- package/dist/auth/strategies/local/register.d.ts.map +1 -1
- package/dist/auth/strategies/local/register.js +27 -9
- package/dist/auth/strategies/local/register.js.map +1 -1
- package/dist/bin/generateImportMap/index.d.ts +47 -0
- package/dist/bin/generateImportMap/index.d.ts.map +1 -0
- package/dist/bin/generateImportMap/index.js +129 -0
- package/dist/bin/generateImportMap/index.js.map +1 -0
- package/dist/bin/generateImportMap/iterateCollections.d.ts +12 -0
- package/dist/bin/generateImportMap/iterateCollections.d.ts.map +1 -0
- package/dist/bin/generateImportMap/iterateCollections.js +41 -0
- package/dist/bin/generateImportMap/iterateCollections.js.map +1 -0
- package/dist/bin/generateImportMap/iterateConfig.d.ts +10 -0
- package/dist/bin/generateImportMap/iterateConfig.d.ts.map +1 -0
- package/dist/bin/generateImportMap/iterateConfig.js +75 -0
- package/dist/bin/generateImportMap/iterateConfig.js.map +1 -0
- package/dist/bin/generateImportMap/iterateFields.d.ts +12 -0
- package/dist/bin/generateImportMap/iterateFields.d.ts.map +1 -0
- package/dist/bin/generateImportMap/iterateFields.js +56 -0
- package/dist/bin/generateImportMap/iterateFields.js.map +1 -0
- package/dist/bin/generateImportMap/iterateGlobals.d.ts +12 -0
- package/dist/bin/generateImportMap/iterateGlobals.d.ts.map +1 -0
- package/dist/bin/generateImportMap/iterateGlobals.js +34 -0
- package/dist/bin/generateImportMap/iterateGlobals.js.map +1 -0
- package/dist/bin/generateImportMap/parsePayloadComponent.d.ts +6 -0
- package/dist/bin/generateImportMap/parsePayloadComponent.d.ts.map +1 -0
- package/dist/bin/generateImportMap/parsePayloadComponent.js +19 -0
- package/dist/bin/generateImportMap/parsePayloadComponent.js.map +1 -0
- package/dist/bin/index.d.ts.map +1 -1
- package/dist/bin/index.js +35 -4
- package/dist/bin/index.js.map +1 -1
- package/dist/collections/config/client.d.ts +32 -308
- package/dist/collections/config/client.d.ts.map +1 -1
- package/dist/collections/config/client.js +1 -73
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/config/types.d.ts +9 -9
- package/dist/collections/config/types.d.ts.map +1 -1
- package/dist/collections/config/types.js.map +1 -1
- package/dist/config/client.d.ts +12 -6
- package/dist/config/client.d.ts.map +1 -1
- package/dist/config/client.js +1 -49
- package/dist/config/client.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +4 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +28 -2
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +111 -52
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/getLocalizedPaths.d.ts.map +1 -1
- package/dist/database/getLocalizedPaths.js +1 -1
- package/dist/database/getLocalizedPaths.js.map +1 -1
- package/dist/exports/node.d.ts +0 -1
- package/dist/exports/node.d.ts.map +1 -1
- package/dist/exports/node.js +0 -1
- package/dist/exports/node.js.map +1 -1
- package/dist/exports/shared.d.ts +2 -1
- package/dist/exports/shared.d.ts.map +1 -1
- package/dist/exports/shared.js +2 -1
- package/dist/exports/shared.js.map +1 -1
- package/dist/fields/config/client.d.ts +3 -1642
- package/dist/fields/config/client.d.ts.map +1 -1
- package/dist/fields/config/client.js +1 -81
- package/dist/fields/config/client.js.map +1 -1
- package/dist/fields/config/sanitize.d.ts.map +1 -1
- package/dist/fields/config/sanitize.js +23 -22
- package/dist/fields/config/sanitize.js.map +1 -1
- package/dist/fields/config/types.d.ts +385 -56
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/config/types.js +3 -0
- package/dist/fields/config/types.js.map +1 -1
- package/dist/globals/config/client.d.ts +26 -14
- package/dist/globals/config/client.d.ts.map +1 -1
- package/dist/globals/config/client.js +1 -47
- package/dist/globals/config/client.js.map +1 -1
- package/dist/globals/config/types.d.ts +3 -3
- package/dist/globals/config/types.js.map +1 -1
- package/dist/index.d.ts +15 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/uploads/getBaseFields.d.ts.map +1 -1
- package/dist/uploads/getBaseFields.js +5 -2
- package/dist/uploads/getBaseFields.js.map +1 -1
- package/dist/uploads/imageResizer.d.ts.map +1 -1
- package/dist/uploads/imageResizer.js +10 -1
- package/dist/uploads/imageResizer.js.map +1 -1
- package/dist/uploads/types.d.ts +15 -0
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/dist/utilities/fieldSchemaToJSON.d.ts +4 -4
- package/dist/utilities/fieldSchemaToJSON.d.ts.map +1 -1
- package/dist/utilities/fieldSchemaToJSON.js +0 -10
- package/dist/utilities/fieldSchemaToJSON.js.map +1 -1
- package/dist/utilities/flattenTopLevelFields.d.ts +4 -3
- package/dist/utilities/flattenTopLevelFields.d.ts.map +1 -1
- package/dist/utilities/flattenTopLevelFields.js +12 -7
- package/dist/utilities/flattenTopLevelFields.js.map +1 -1
- package/dist/utilities/getEntityPolicies.d.ts.map +1 -1
- package/dist/utilities/getEntityPolicies.js +12 -6
- package/dist/utilities/getEntityPolicies.js.map +1 -1
- package/dist/utilities/telemetry/conf/index.js.map +1 -1
- package/dist/versions/baseFields.js +1 -1
- package/dist/versions/baseFields.js.map +1 -1
- package/package.json +3 -10
- package/dist/admin/fields/index.d.ts +0 -65
- package/dist/admin/fields/index.d.ts.map +0 -1
- package/dist/admin/fields/index.js +0 -3
- package/dist/admin/fields/index.js.map +0 -1
- package/dist/admin/forms/FieldMap.d.ts +0 -23
- package/dist/admin/forms/FieldMap.d.ts.map +0 -1
- package/dist/admin/forms/FieldMap.js +0 -3
- package/dist/admin/forms/FieldMap.js.map +0 -1
- package/dist/admin/forms/FieldTypes.d.ts +0 -27
- package/dist/admin/forms/FieldTypes.d.ts.map +0 -1
- package/dist/admin/forms/FieldTypes.js +0 -3
- package/dist/admin/forms/FieldTypes.js.map +0 -1
- package/dist/bin/loader/clientExtensions.d.ts +0 -2
- package/dist/bin/loader/clientExtensions.d.ts.map +0 -1
- package/dist/bin/loader/clientExtensions.js +0 -13
- package/dist/bin/loader/clientExtensions.js.map +0 -1
- package/dist/bin/loader/compile.d.ts +0 -5
- package/dist/bin/loader/compile.d.ts.map +0 -1
- package/dist/bin/loader/compile.js +0 -27
- package/dist/bin/loader/compile.js.map +0 -1
- package/dist/bin/loader/ignores.d.ts +0 -2
- package/dist/bin/loader/ignores.d.ts.map +0 -1
- package/dist/bin/loader/ignores.js +0 -5
- package/dist/bin/loader/ignores.js.map +0 -1
- package/dist/bin/loader/index.d.ts +0 -34
- package/dist/bin/loader/index.d.ts.map +0 -1
- package/dist/bin/loader/index.js +0 -116
- package/dist/bin/loader/index.js.map +0 -1
- package/dist/bin/loader/read-default-tsconfig.d.ts +0 -29
- package/dist/bin/loader/read-default-tsconfig.d.ts.map +0 -1
- package/dist/bin/loader/read-default-tsconfig.js +0 -116
- package/dist/bin/loader/read-default-tsconfig.js.map +0 -1
- package/dist/bin/loader/resolveOriginalPath.d.ts +0 -10
- package/dist/bin/loader/resolveOriginalPath.d.ts.map +0 -1
- package/dist/bin/loader/resolveOriginalPath.js +0 -36
- package/dist/bin/loader/resolveOriginalPath.js.map +0 -1
- package/dist/utilities/importWithoutClientFiles.d.ts +0 -7
- package/dist/utilities/importWithoutClientFiles.d.ts.map +0 -1
- package/dist/utilities/importWithoutClientFiles.js +0 -47
- package/dist/utilities/importWithoutClientFiles.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/getBaseFields.ts"],"sourcesContent":["import type { CollectionConfig } from '../collections/config/types.js'\nimport type { Config } from '../config/types.js'\nimport type { Field } from '../fields/config/types.js'\nimport type { UploadConfig } from './types.js'\n\nimport { mimeTypeValidator } from './mimeTypeValidator.js'\n\ntype GenerateURLArgs = {\n collectionSlug: string\n config: Config\n filename?: string\n}\nconst generateURL = ({ collectionSlug, config, filename }: GenerateURLArgs) => {\n if (filename) {\n return `${config.serverURL || ''}${config.routes.api || ''}/${collectionSlug}/file/${filename}`\n }\n return undefined\n}\n\ntype Options = {\n collection: CollectionConfig\n config: Config\n}\n\nexport const getBaseUploadFields = ({ collection, config }: Options): Field[] => {\n const uploadOptions: UploadConfig = typeof collection.upload === 'object' ? collection.upload : {}\n\n const mimeType: Field = {\n name: 'mimeType',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'MIME Type',\n }\n\n const thumbnailURL: Field = {\n name: 'thumbnailURL',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n hooks: {\n afterRead: [\n ({ originalDoc }) => {\n const adminThumbnail =\n typeof collection.upload !== 'boolean' ? collection.upload?.adminThumbnail : undefined\n\n if (typeof adminThumbnail === 'function') {\n return adminThumbnail({ doc: originalDoc })\n }\n\n if (\n typeof adminThumbnail === 'string' &&\n 'sizes' in originalDoc &&\n originalDoc.sizes?.[adminThumbnail]?.filename\n ) {\n return generateURL({\n collectionSlug: collection.slug,\n config,\n filename: originalDoc.sizes?.[adminThumbnail].filename as string,\n })\n }\n\n return null\n },\n ],\n },\n label: 'Thumbnail URL',\n }\n\n const width: Field = {\n name: 'width',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:width'),\n }\n\n const height: Field = {\n name: 'height',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:height'),\n }\n\n const filesize: Field = {\n name: 'filesize',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:fileSize'),\n }\n\n const filename: Field = {\n name: 'filename',\n type: 'text',\n admin: {\n disableBulkEdit: true,\n hidden: true,\n readOnly: true,\n },\n index: true,\n label: ({ t }) => t('upload:fileName'),\n
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/getBaseFields.ts"],"sourcesContent":["import type { CollectionConfig } from '../collections/config/types.js'\nimport type { Config } from '../config/types.js'\nimport type { Field } from '../fields/config/types.js'\nimport type { UploadConfig } from './types.js'\n\nimport { mimeTypeValidator } from './mimeTypeValidator.js'\n\ntype GenerateURLArgs = {\n collectionSlug: string\n config: Config\n filename?: string\n}\nconst generateURL = ({ collectionSlug, config, filename }: GenerateURLArgs) => {\n if (filename) {\n return `${config.serverURL || ''}${config.routes.api || ''}/${collectionSlug}/file/${filename}`\n }\n return undefined\n}\n\ntype Options = {\n collection: CollectionConfig\n config: Config\n}\n\nexport const getBaseUploadFields = ({ collection, config }: Options): Field[] => {\n const uploadOptions: UploadConfig = typeof collection.upload === 'object' ? collection.upload : {}\n\n const mimeType: Field = {\n name: 'mimeType',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'MIME Type',\n }\n\n const thumbnailURL: Field = {\n name: 'thumbnailURL',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n hooks: {\n afterRead: [\n ({ originalDoc }) => {\n const adminThumbnail =\n typeof collection.upload !== 'boolean' ? collection.upload?.adminThumbnail : undefined\n\n if (typeof adminThumbnail === 'function') {\n return adminThumbnail({ doc: originalDoc })\n }\n\n if (\n typeof adminThumbnail === 'string' &&\n 'sizes' in originalDoc &&\n originalDoc.sizes?.[adminThumbnail]?.filename\n ) {\n return generateURL({\n collectionSlug: collection.slug,\n config,\n filename: originalDoc.sizes?.[adminThumbnail].filename as string,\n })\n }\n\n return null\n },\n ],\n },\n label: 'Thumbnail URL',\n }\n\n const width: Field = {\n name: 'width',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:width'),\n }\n\n const height: Field = {\n name: 'height',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:height'),\n }\n\n const filesize: Field = {\n name: 'filesize',\n type: 'number',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: ({ t }) => t('upload:fileSize'),\n }\n\n const filename: Field = {\n name: 'filename',\n type: 'text',\n admin: {\n disableBulkEdit: true,\n hidden: true,\n readOnly: true,\n },\n index: true,\n label: ({ t }) => t('upload:fileName'),\n }\n\n // Only set unique: true if the collection does not have a compound index\n if (\n collection.upload === true ||\n (typeof collection.upload === 'object' && !collection.upload.filenameCompoundIndex)\n ) {\n filename.unique = true\n }\n\n const url: Field = {\n name: 'url',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'URL',\n }\n\n let uploadFields: Field[] = [\n {\n ...url,\n hooks: {\n afterRead: [\n ({ data, value }) => {\n if (value && !data.filename) return value\n\n return generateURL({\n collectionSlug: collection.slug,\n config,\n filename: data?.filename,\n })\n },\n ],\n },\n },\n thumbnailURL,\n filename,\n mimeType,\n filesize,\n width,\n height,\n ]\n\n // Add focal point fields if not disabled\n if (\n uploadOptions.focalPoint !== false ||\n uploadOptions.imageSizes ||\n uploadOptions.resizeOptions\n ) {\n uploadFields = uploadFields.concat(\n ['focalX', 'focalY'].map((name) => {\n return {\n name,\n type: 'number',\n admin: {\n hidden: true,\n },\n }\n }),\n )\n }\n\n if (uploadOptions.mimeTypes) {\n mimeType.validate = mimeTypeValidator(uploadOptions.mimeTypes)\n }\n\n if (uploadOptions.imageSizes) {\n uploadFields = uploadFields.concat([\n {\n name: 'sizes',\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: uploadOptions.imageSizes.map((size) => ({\n name: size.name,\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: [\n {\n ...url,\n hooks: {\n afterRead: [\n ({ data, value }) => {\n if (value && size.height && size.width && !data.filename) return value\n\n const sizeFilename = data?.sizes?.[size.name]?.filename\n\n if (sizeFilename) {\n return `${config.serverURL}${config.routes.api}/${collection.slug}/file/${sizeFilename}`\n }\n\n return null\n },\n ],\n },\n },\n width,\n height,\n mimeType,\n filesize,\n {\n ...filename,\n unique: false,\n },\n ],\n label: size.name,\n })),\n label: ({ t }) => t('upload:sizes'),\n },\n ])\n }\n return uploadFields\n}\n"],"names":["mimeTypeValidator","generateURL","collectionSlug","config","filename","serverURL","routes","api","undefined","getBaseUploadFields","collection","uploadOptions","upload","mimeType","name","type","admin","hidden","readOnly","label","thumbnailURL","hooks","afterRead","originalDoc","adminThumbnail","doc","sizes","slug","width","t","height","filesize","disableBulkEdit","index","filenameCompoundIndex","unique","url","uploadFields","data","value","focalPoint","imageSizes","resizeOptions","concat","map","mimeTypes","validate","fields","size","sizeFilename"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imageResizer.d.ts","sourceRoot":"","sources":["../../src/uploads/imageResizer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,KAAK,EAEV,SAAS,EACT,UAAU,EAEV,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAA;AAMnB,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,yBAAyB,CAAA;IACjC,UAAU,EAAE,eAAe,CAAA;IAC3B,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,cAAc,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED,sEAAsE;AACtE,KAAK,gBAAgB,GAAG;IACtB,UAAU,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;IACtC,QAAQ,EAAE,SAAS,CAAA;IACnB,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B,CAAA;AAyLD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,EACjD,MAAM,EACN,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,aAAa,EACb,KAAK,EACL,UAAU,EACV,WAAW,EACX,YAAY,GACb,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"imageResizer.d.ts","sourceRoot":"","sources":["../../src/uploads/imageResizer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,KAAK,EAEV,SAAS,EACT,UAAU,EAEV,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAA;AAMnB,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,yBAAyB,CAAA;IACjC,UAAU,EAAE,eAAe,CAAA;IAC3B,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,cAAc,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED,sEAAsE;AACtE,KAAK,gBAAgB,GAAG;IACtB,UAAU,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;IACtC,QAAQ,EAAE,SAAS,CAAA;IACnB,WAAW,EAAE,UAAU,EAAE,CAAA;CAC1B,CAAA;AAyLD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,EACjD,MAAM,EACN,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,aAAa,EACb,KAAK,EACL,UAAU,EACV,WAAW,EACX,YAAY,GACb,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoNxC"}
|
|
@@ -255,7 +255,16 @@ const createImageName = ({ extension, height, outputImageName, width })=>{
|
|
|
255
255
|
req.payloadUploadSizes[imageResizeConfig.name] = bufferData;
|
|
256
256
|
}
|
|
257
257
|
const mimeInfo = await fileTypeFromBuffer(bufferData);
|
|
258
|
-
const imageNameWithDimensions =
|
|
258
|
+
const imageNameWithDimensions = imageResizeConfig.generateImageName ? imageResizeConfig.generateImageName({
|
|
259
|
+
extension: mimeInfo?.ext || sanitizedImage.ext,
|
|
260
|
+
height: extractHeightFromImage({
|
|
261
|
+
...originalImageMeta,
|
|
262
|
+
height: bufferInfo.height
|
|
263
|
+
}),
|
|
264
|
+
originalName: sanitizedImage.name,
|
|
265
|
+
sizeName: imageResizeConfig.name,
|
|
266
|
+
width: bufferInfo.width
|
|
267
|
+
}) : createImageName({
|
|
259
268
|
extension: mimeInfo?.ext || sanitizedImage.ext,
|
|
260
269
|
height: extractHeightFromImage({
|
|
261
270
|
...originalImageMeta,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/imageResizer.ts"],"sourcesContent":["import type { Sharp, Metadata as SharpMetadata, SharpOptions } from 'sharp'\n\nimport { fileTypeFromBuffer } from 'file-type'\nimport fs from 'fs'\nimport sanitize from 'sanitize-filename'\n\nimport type { SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { SharpDependency } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { WithMetadata } from './optionallyAppendMetadata.js'\nimport type {\n FileSize,\n FileSizes,\n FileToSave,\n ImageSize,\n ProbedImageSize,\n UploadEdits,\n} from './types.js'\n\nimport { isNumber } from '../utilities/isNumber.js'\nimport fileExists from './fileExists.js'\nimport { optionallyAppendMetadata } from './optionallyAppendMetadata.js'\n\ntype ResizeArgs = {\n config: SanitizedCollectionConfig\n dimensions: ProbedImageSize\n file: PayloadRequest['file']\n mimeType: string\n req: PayloadRequest\n savedFilename: string\n sharp?: SharpDependency\n staticPath: string\n uploadEdits?: UploadEdits\n withMetadata?: WithMetadata\n}\n\n/** Result from resizing and transforming the requested image sizes */\ntype ImageSizesResult = {\n focalPoint?: UploadEdits['focalPoint']\n sizeData: FileSizes\n sizesToSave: FileToSave[]\n}\n\ntype SanitizedImageData = {\n ext: string\n name: string\n}\n\n/**\n * Sanitize the image name and extract the extension from the source image\n *\n * @param sourceImage - the source image\n * @returns the sanitized name and extension\n */\nconst getSanitizedImageData = (sourceImage: string): SanitizedImageData => {\n const extension = sourceImage.split('.').pop()\n const name = sanitize(sourceImage.substring(0, sourceImage.lastIndexOf('.')) || sourceImage)\n return { name, ext: extension }\n}\n\n/**\n * Create a new image name based on the output image name, the dimensions and\n * the extension.\n *\n * Ignore the fact that duplicate names could happen if the there is one\n * size with `width AND height` and one with only `height OR width`. Because\n * space is expensive, we will reuse the same image for both sizes.\n *\n * @param outputImageName - the sanitized image name\n * @param bufferInfo - the buffer info\n * @param extension - the extension to use\n * @returns the new image name that is not taken\n */\ntype CreateImageNameArgs = {\n extension: string\n height: number\n outputImageName: string\n width: number\n}\nconst createImageName = ({\n extension,\n height,\n outputImageName,\n width,\n}: CreateImageNameArgs): string => {\n return `${outputImageName}-${width}x${height}.${extension}`\n}\n\ntype CreateResultArgs = {\n filename?: FileSize['filename']\n filesize?: FileSize['filesize']\n height?: FileSize['height']\n mimeType?: FileSize['mimeType']\n name: string\n sizesToSave?: FileToSave[]\n width?: FileSize['width']\n}\n\n/**\n * Create the result object for the image resize operation based on the\n * provided parameters. If the name is not provided, an empty result object\n * is returned.\n *\n * @param name - the name of the image\n * @param filename - the filename of the image\n * @param width - the width of the image\n * @param height - the height of the image\n * @param filesize - the filesize of the image\n * @param mimeType - the mime type of the image\n * @param sizesToSave - the sizes to save\n * @returns the result object\n */\nconst createResult = ({\n name,\n filename = null,\n filesize = null,\n height = null,\n mimeType = null,\n sizesToSave = [],\n width = null,\n}: CreateResultArgs): ImageSizesResult => {\n return {\n sizeData: {\n [name]: {\n filename,\n filesize,\n height,\n mimeType,\n width,\n },\n },\n sizesToSave,\n }\n}\n\n/**\n * Determine whether or not to resize the image.\n * - resize using image config\n * - resize using image config with focal adjustments\n * - do not resize at all\n *\n * `imageResizeConfig.withoutEnlargement`:\n * - undefined [default]: uploading images with smaller width AND height than the image size will return null\n * - false: always enlarge images to the image size\n * - true: if the image is smaller than the image size, return the original image\n *\n * `imageResizeConfig.withoutReduction`:\n * - false [default]: always enlarge images to the image size\n * - true: if the image is smaller than the image size, return the original image\n *\n * @return 'omit' | 'resize' | 'resizeWithFocalPoint'\n */\nconst getImageResizeAction = ({\n dimensions: originalImage,\n hasFocalPoint,\n imageResizeConfig,\n}: {\n dimensions: ProbedImageSize\n hasFocalPoint?: boolean\n imageResizeConfig: ImageSize\n}): 'omit' | 'resize' | 'resizeWithFocalPoint' => {\n const {\n fit,\n height: targetHeight,\n width: targetWidth,\n withoutEnlargement,\n withoutReduction,\n } = imageResizeConfig\n\n // prevent upscaling by default when x and y are both smaller than target image size\n if (targetHeight && targetWidth) {\n const originalImageIsSmallerXAndY =\n originalImage.width < targetWidth && originalImage.height < targetHeight\n if (withoutEnlargement === undefined && originalImageIsSmallerXAndY) {\n return 'omit' // prevent image size from being enlarged\n }\n }\n\n const originalImageIsSmallerXOrY =\n originalImage.width < targetWidth || originalImage.height < targetHeight\n if (fit === 'contain' || fit === 'inside') return 'resize'\n if (!isNumber(targetHeight) && !isNumber(targetWidth)) return 'resize'\n\n const targetAspectRatio = targetWidth / targetHeight\n const originalAspectRatio = originalImage.width / originalImage.height\n if (originalAspectRatio === targetAspectRatio) return 'resize'\n\n if (withoutEnlargement && originalImageIsSmallerXOrY) return 'resize'\n if (withoutReduction && !originalImageIsSmallerXOrY) return 'resize'\n\n return hasFocalPoint ? 'resizeWithFocalPoint' : 'resize'\n}\n\n/**\n * Sanitize the resize config. If the resize config has the `withoutReduction`\n * property set to true, the `fit` and `position` properties will be set to `contain`\n * and `top left` respectively.\n *\n * @param resizeConfig - the resize config\n * @returns a sanitized resize config\n */\nconst sanitizeResizeConfig = (resizeConfig: ImageSize): ImageSize => {\n if (resizeConfig.withoutReduction) {\n return {\n ...resizeConfig,\n // Why fit `contain` should also be set to https://github.com/lovell/sharp/issues/3595\n fit: resizeConfig?.fit || 'contain',\n position: resizeConfig?.position || 'left top',\n }\n }\n return resizeConfig\n}\n\n/**\n * Used to extract height from images, animated or not.\n *\n * @param sharpMetadata - the sharp metadata\n * @returns the height of the image\n */\nfunction extractHeightFromImage(sharpMetadata: SharpMetadata): number {\n if (sharpMetadata?.pages) {\n return sharpMetadata.height / sharpMetadata.pages\n }\n return sharpMetadata.height\n}\n\n/**\n * For the provided image sizes, handle the resizing and the transforms\n * (format, trim, etc.) of each requested image size and return the result object.\n * This only handles the image sizes. The transforms of the original image\n * are handled in {@link ./generateFileData.ts}.\n *\n * The image will be resized according to the provided\n * resize config. If no image sizes are requested, the resolved data will be empty.\n * For every image that does not need to be resized, a result object with `null`\n * parameters will be returned.\n *\n * @param resizeConfig - the resize config\n * @returns the result of the resize operation(s)\n */\nexport async function resizeAndTransformImageSizes({\n config,\n dimensions,\n file,\n mimeType,\n req,\n savedFilename,\n sharp,\n staticPath,\n uploadEdits,\n withMetadata,\n}: ResizeArgs): Promise<ImageSizesResult> {\n const { focalPoint: focalPointEnabled = true, imageSizes } = config.upload\n\n // Focal point adjustments\n const incomingFocalPoint = uploadEdits.focalPoint\n ? {\n x: isNumber(uploadEdits.focalPoint.x) ? Math.round(uploadEdits.focalPoint.x) : 50,\n y: isNumber(uploadEdits.focalPoint.y) ? Math.round(uploadEdits.focalPoint.y) : 50,\n }\n : undefined\n\n const defaultResult: ImageSizesResult = {\n ...(focalPointEnabled && incomingFocalPoint && { focalPoint: incomingFocalPoint }),\n sizeData: {},\n sizesToSave: [],\n }\n\n if (!imageSizes || !sharp) {\n return defaultResult\n }\n\n // Determine if the file is animated\n const fileIsAnimatedType = ['image/avif', 'image/gif', 'image/webp'].includes(file.mimetype)\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimatedType) sharpOptions.animated = true\n\n const sharpBase: Sharp | undefined = sharp(file.tempFilePath || file.data, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n const originalImageMeta = await sharpBase.metadata()\n\n const resizeImageMeta = {\n height: extractHeightFromImage(originalImageMeta),\n width: originalImageMeta.width,\n }\n\n const results: ImageSizesResult[] = await Promise.all(\n imageSizes.map(async (imageResizeConfig): Promise<ImageSizesResult> => {\n imageResizeConfig = sanitizeResizeConfig(imageResizeConfig)\n\n const resizeAction = getImageResizeAction({\n dimensions,\n hasFocalPoint: Boolean(incomingFocalPoint),\n imageResizeConfig,\n })\n if (resizeAction === 'omit') return createResult({ name: imageResizeConfig.name })\n\n const imageToResize = sharpBase.clone()\n let resized = imageToResize\n\n if (resizeAction === 'resizeWithFocalPoint') {\n let { height: resizeHeight, width: resizeWidth } = imageResizeConfig\n\n const originalAspectRatio = dimensions.width / dimensions.height\n\n // Calculate resizeWidth based on original aspect ratio if it's undefined\n if (resizeHeight && !resizeWidth) {\n resizeWidth = Math.round(resizeHeight * originalAspectRatio)\n }\n\n // Calculate resizeHeight based on original aspect ratio if it's undefined\n if (resizeWidth && !resizeHeight) {\n resizeHeight = Math.round(resizeWidth / originalAspectRatio)\n }\n\n if (!resizeHeight) resizeHeight = resizeImageMeta.height\n if (!resizeWidth) resizeWidth = resizeImageMeta.width\n\n const resizeAspectRatio = resizeWidth / resizeHeight\n const prioritizeHeight = resizeAspectRatio < originalAspectRatio\n // Scales the image before extracting from it\n resized = imageToResize.resize({\n height: prioritizeHeight ? resizeHeight : undefined,\n width: prioritizeHeight ? undefined : resizeWidth,\n })\n\n const metadataAppendedFile = await optionallyAppendMetadata({\n req,\n sharpFile: resized,\n withMetadata,\n })\n\n // Must read from buffer, resized.metadata will return the original image metadata\n const { info } = await metadataAppendedFile.toBuffer({ resolveWithObject: true })\n\n resizeImageMeta.height = extractHeightFromImage({\n ...originalImageMeta,\n height: info.height,\n })\n resizeImageMeta.width = info.width\n\n const halfResizeX = resizeWidth / 2\n const xFocalCenter = resizeImageMeta.width * (incomingFocalPoint.x / 100)\n const calculatedRightPixelBound = xFocalCenter + halfResizeX\n let leftBound = xFocalCenter - halfResizeX\n\n // if the right bound is greater than the image width, adjust the left bound\n // keeping focus on the right\n if (calculatedRightPixelBound > resizeImageMeta.width) {\n leftBound = resizeImageMeta.width - resizeWidth\n }\n\n // if the left bound is less than 0, adjust the left bound to 0\n // keeping the focus on the left\n if (leftBound < 0) leftBound = 0\n\n const halfResizeY = resizeHeight / 2\n const yFocalCenter = resizeImageMeta.height * (incomingFocalPoint.y / 100)\n const calculatedBottomPixelBound = yFocalCenter + halfResizeY\n let topBound = yFocalCenter - halfResizeY\n\n // if the bottom bound is greater than the image height, adjust the top bound\n // keeping the image as far right as possible\n if (calculatedBottomPixelBound > resizeImageMeta.height) {\n topBound = resizeImageMeta.height - resizeHeight\n }\n\n // if the top bound is less than 0, adjust the top bound to 0\n // keeping the image focus near the top\n if (topBound < 0) topBound = 0\n\n resized = resized.extract({\n height: resizeHeight,\n left: Math.floor(leftBound),\n top: Math.floor(topBound),\n width: resizeWidth,\n })\n } else {\n resized = imageToResize.resize(imageResizeConfig)\n }\n\n if (imageResizeConfig.formatOptions) {\n resized = resized.toFormat(\n imageResizeConfig.formatOptions.format,\n imageResizeConfig.formatOptions.options,\n )\n }\n\n if (imageResizeConfig.trimOptions) {\n resized = resized.trim(imageResizeConfig.trimOptions)\n }\n\n const metadataAppendedFile = await optionallyAppendMetadata({\n req,\n sharpFile: resized,\n withMetadata,\n })\n\n const { data: bufferData, info: bufferInfo } = await metadataAppendedFile.toBuffer({\n resolveWithObject: true,\n })\n\n const sanitizedImage = getSanitizedImageData(savedFilename)\n\n if (req.payloadUploadSizes) {\n req.payloadUploadSizes[imageResizeConfig.name] = bufferData\n }\n\n const mimeInfo = await fileTypeFromBuffer(bufferData)\n\n const imageNameWithDimensions = createImageName({\n extension: mimeInfo?.ext || sanitizedImage.ext,\n height: extractHeightFromImage({\n ...originalImageMeta,\n height: bufferInfo.height,\n }),\n outputImageName: sanitizedImage.name,\n width: bufferInfo.width,\n })\n\n const imagePath = `${staticPath}/${imageNameWithDimensions}`\n\n if (await fileExists(imagePath)) {\n try {\n fs.unlinkSync(imagePath)\n } catch {\n // Ignore unlink errors\n }\n }\n\n const { height, size, width } = bufferInfo\n return createResult({\n name: imageResizeConfig.name,\n filename: imageNameWithDimensions,\n filesize: size,\n height:\n fileIsAnimatedType && originalImageMeta.pages ? height / originalImageMeta.pages : height,\n mimeType: mimeInfo?.mime || mimeType,\n sizesToSave: [{ buffer: bufferData, path: imagePath }],\n width,\n })\n }),\n )\n\n return results.reduce(\n (acc, result) => {\n Object.assign(acc.sizeData, result.sizeData)\n acc.sizesToSave.push(...result.sizesToSave)\n return acc\n },\n { ...defaultResult },\n )\n}\n"],"names":["fileTypeFromBuffer","fs","sanitize","isNumber","fileExists","optionallyAppendMetadata","getSanitizedImageData","sourceImage","extension","split","pop","name","substring","lastIndexOf","ext","createImageName","height","outputImageName","width","createResult","filename","filesize","mimeType","sizesToSave","sizeData","getImageResizeAction","dimensions","originalImage","hasFocalPoint","imageResizeConfig","fit","targetHeight","targetWidth","withoutEnlargement","withoutReduction","originalImageIsSmallerXAndY","undefined","originalImageIsSmallerXOrY","targetAspectRatio","originalAspectRatio","sanitizeResizeConfig","resizeConfig","position","extractHeightFromImage","sharpMetadata","pages","resizeAndTransformImageSizes","config","file","req","savedFilename","sharp","staticPath","uploadEdits","withMetadata","focalPoint","focalPointEnabled","imageSizes","upload","incomingFocalPoint","x","Math","round","y","defaultResult","fileIsAnimatedType","includes","mimetype","sharpOptions","animated","sharpBase","tempFilePath","data","rotate","originalImageMeta","metadata","resizeImageMeta","results","Promise","all","map","resizeAction","Boolean","imageToResize","clone","resized","resizeHeight","resizeWidth","resizeAspectRatio","prioritizeHeight","resize","metadataAppendedFile","sharpFile","info","toBuffer","resolveWithObject","halfResizeX","xFocalCenter","calculatedRightPixelBound","leftBound","halfResizeY","yFocalCenter","calculatedBottomPixelBound","topBound","extract","left","floor","top","formatOptions","toFormat","format","options","trimOptions","trim","bufferData","bufferInfo","sanitizedImage","payloadUploadSizes","mimeInfo","imageNameWithDimensions","imagePath","unlinkSync","size","mime","buffer","path","reduce","acc","result","Object","assign","push"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/imageResizer.ts"],"sourcesContent":["import type { Sharp, Metadata as SharpMetadata, SharpOptions } from 'sharp'\n\nimport { fileTypeFromBuffer } from 'file-type'\nimport fs from 'fs'\nimport sanitize from 'sanitize-filename'\n\nimport type { SanitizedCollectionConfig } from '../collections/config/types.js'\nimport type { SharpDependency } from '../config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { WithMetadata } from './optionallyAppendMetadata.js'\nimport type {\n FileSize,\n FileSizes,\n FileToSave,\n ImageSize,\n ProbedImageSize,\n UploadEdits,\n} from './types.js'\n\nimport { isNumber } from '../utilities/isNumber.js'\nimport fileExists from './fileExists.js'\nimport { optionallyAppendMetadata } from './optionallyAppendMetadata.js'\n\ntype ResizeArgs = {\n config: SanitizedCollectionConfig\n dimensions: ProbedImageSize\n file: PayloadRequest['file']\n mimeType: string\n req: PayloadRequest\n savedFilename: string\n sharp?: SharpDependency\n staticPath: string\n uploadEdits?: UploadEdits\n withMetadata?: WithMetadata\n}\n\n/** Result from resizing and transforming the requested image sizes */\ntype ImageSizesResult = {\n focalPoint?: UploadEdits['focalPoint']\n sizeData: FileSizes\n sizesToSave: FileToSave[]\n}\n\ntype SanitizedImageData = {\n ext: string\n name: string\n}\n\n/**\n * Sanitize the image name and extract the extension from the source image\n *\n * @param sourceImage - the source image\n * @returns the sanitized name and extension\n */\nconst getSanitizedImageData = (sourceImage: string): SanitizedImageData => {\n const extension = sourceImage.split('.').pop()\n const name = sanitize(sourceImage.substring(0, sourceImage.lastIndexOf('.')) || sourceImage)\n return { name, ext: extension }\n}\n\n/**\n * Create a new image name based on the output image name, the dimensions and\n * the extension.\n *\n * Ignore the fact that duplicate names could happen if the there is one\n * size with `width AND height` and one with only `height OR width`. Because\n * space is expensive, we will reuse the same image for both sizes.\n *\n * @param outputImageName - the sanitized image name\n * @param bufferInfo - the buffer info\n * @param extension - the extension to use\n * @returns the new image name that is not taken\n */\ntype CreateImageNameArgs = {\n extension: string\n height: number\n outputImageName: string\n width: number\n}\nconst createImageName = ({\n extension,\n height,\n outputImageName,\n width,\n}: CreateImageNameArgs): string => {\n return `${outputImageName}-${width}x${height}.${extension}`\n}\n\ntype CreateResultArgs = {\n filename?: FileSize['filename']\n filesize?: FileSize['filesize']\n height?: FileSize['height']\n mimeType?: FileSize['mimeType']\n name: string\n sizesToSave?: FileToSave[]\n width?: FileSize['width']\n}\n\n/**\n * Create the result object for the image resize operation based on the\n * provided parameters. If the name is not provided, an empty result object\n * is returned.\n *\n * @param name - the name of the image\n * @param filename - the filename of the image\n * @param width - the width of the image\n * @param height - the height of the image\n * @param filesize - the filesize of the image\n * @param mimeType - the mime type of the image\n * @param sizesToSave - the sizes to save\n * @returns the result object\n */\nconst createResult = ({\n name,\n filename = null,\n filesize = null,\n height = null,\n mimeType = null,\n sizesToSave = [],\n width = null,\n}: CreateResultArgs): ImageSizesResult => {\n return {\n sizeData: {\n [name]: {\n filename,\n filesize,\n height,\n mimeType,\n width,\n },\n },\n sizesToSave,\n }\n}\n\n/**\n * Determine whether or not to resize the image.\n * - resize using image config\n * - resize using image config with focal adjustments\n * - do not resize at all\n *\n * `imageResizeConfig.withoutEnlargement`:\n * - undefined [default]: uploading images with smaller width AND height than the image size will return null\n * - false: always enlarge images to the image size\n * - true: if the image is smaller than the image size, return the original image\n *\n * `imageResizeConfig.withoutReduction`:\n * - false [default]: always enlarge images to the image size\n * - true: if the image is smaller than the image size, return the original image\n *\n * @return 'omit' | 'resize' | 'resizeWithFocalPoint'\n */\nconst getImageResizeAction = ({\n dimensions: originalImage,\n hasFocalPoint,\n imageResizeConfig,\n}: {\n dimensions: ProbedImageSize\n hasFocalPoint?: boolean\n imageResizeConfig: ImageSize\n}): 'omit' | 'resize' | 'resizeWithFocalPoint' => {\n const {\n fit,\n height: targetHeight,\n width: targetWidth,\n withoutEnlargement,\n withoutReduction,\n } = imageResizeConfig\n\n // prevent upscaling by default when x and y are both smaller than target image size\n if (targetHeight && targetWidth) {\n const originalImageIsSmallerXAndY =\n originalImage.width < targetWidth && originalImage.height < targetHeight\n if (withoutEnlargement === undefined && originalImageIsSmallerXAndY) {\n return 'omit' // prevent image size from being enlarged\n }\n }\n\n const originalImageIsSmallerXOrY =\n originalImage.width < targetWidth || originalImage.height < targetHeight\n if (fit === 'contain' || fit === 'inside') return 'resize'\n if (!isNumber(targetHeight) && !isNumber(targetWidth)) return 'resize'\n\n const targetAspectRatio = targetWidth / targetHeight\n const originalAspectRatio = originalImage.width / originalImage.height\n if (originalAspectRatio === targetAspectRatio) return 'resize'\n\n if (withoutEnlargement && originalImageIsSmallerXOrY) return 'resize'\n if (withoutReduction && !originalImageIsSmallerXOrY) return 'resize'\n\n return hasFocalPoint ? 'resizeWithFocalPoint' : 'resize'\n}\n\n/**\n * Sanitize the resize config. If the resize config has the `withoutReduction`\n * property set to true, the `fit` and `position` properties will be set to `contain`\n * and `top left` respectively.\n *\n * @param resizeConfig - the resize config\n * @returns a sanitized resize config\n */\nconst sanitizeResizeConfig = (resizeConfig: ImageSize): ImageSize => {\n if (resizeConfig.withoutReduction) {\n return {\n ...resizeConfig,\n // Why fit `contain` should also be set to https://github.com/lovell/sharp/issues/3595\n fit: resizeConfig?.fit || 'contain',\n position: resizeConfig?.position || 'left top',\n }\n }\n return resizeConfig\n}\n\n/**\n * Used to extract height from images, animated or not.\n *\n * @param sharpMetadata - the sharp metadata\n * @returns the height of the image\n */\nfunction extractHeightFromImage(sharpMetadata: SharpMetadata): number {\n if (sharpMetadata?.pages) {\n return sharpMetadata.height / sharpMetadata.pages\n }\n return sharpMetadata.height\n}\n\n/**\n * For the provided image sizes, handle the resizing and the transforms\n * (format, trim, etc.) of each requested image size and return the result object.\n * This only handles the image sizes. The transforms of the original image\n * are handled in {@link ./generateFileData.ts}.\n *\n * The image will be resized according to the provided\n * resize config. If no image sizes are requested, the resolved data will be empty.\n * For every image that does not need to be resized, a result object with `null`\n * parameters will be returned.\n *\n * @param resizeConfig - the resize config\n * @returns the result of the resize operation(s)\n */\nexport async function resizeAndTransformImageSizes({\n config,\n dimensions,\n file,\n mimeType,\n req,\n savedFilename,\n sharp,\n staticPath,\n uploadEdits,\n withMetadata,\n}: ResizeArgs): Promise<ImageSizesResult> {\n const { focalPoint: focalPointEnabled = true, imageSizes } = config.upload\n\n // Focal point adjustments\n const incomingFocalPoint = uploadEdits.focalPoint\n ? {\n x: isNumber(uploadEdits.focalPoint.x) ? Math.round(uploadEdits.focalPoint.x) : 50,\n y: isNumber(uploadEdits.focalPoint.y) ? Math.round(uploadEdits.focalPoint.y) : 50,\n }\n : undefined\n\n const defaultResult: ImageSizesResult = {\n ...(focalPointEnabled && incomingFocalPoint && { focalPoint: incomingFocalPoint }),\n sizeData: {},\n sizesToSave: [],\n }\n\n if (!imageSizes || !sharp) {\n return defaultResult\n }\n\n // Determine if the file is animated\n const fileIsAnimatedType = ['image/avif', 'image/gif', 'image/webp'].includes(file.mimetype)\n const sharpOptions: SharpOptions = {}\n\n if (fileIsAnimatedType) sharpOptions.animated = true\n\n const sharpBase: Sharp | undefined = sharp(file.tempFilePath || file.data, sharpOptions).rotate() // pass rotate() to auto-rotate based on EXIF data. https://github.com/payloadcms/payload/pull/3081\n const originalImageMeta = await sharpBase.metadata()\n\n const resizeImageMeta = {\n height: extractHeightFromImage(originalImageMeta),\n width: originalImageMeta.width,\n }\n\n const results: ImageSizesResult[] = await Promise.all(\n imageSizes.map(async (imageResizeConfig): Promise<ImageSizesResult> => {\n imageResizeConfig = sanitizeResizeConfig(imageResizeConfig)\n\n const resizeAction = getImageResizeAction({\n dimensions,\n hasFocalPoint: Boolean(incomingFocalPoint),\n imageResizeConfig,\n })\n if (resizeAction === 'omit') return createResult({ name: imageResizeConfig.name })\n\n const imageToResize = sharpBase.clone()\n let resized = imageToResize\n\n if (resizeAction === 'resizeWithFocalPoint') {\n let { height: resizeHeight, width: resizeWidth } = imageResizeConfig\n\n const originalAspectRatio = dimensions.width / dimensions.height\n\n // Calculate resizeWidth based on original aspect ratio if it's undefined\n if (resizeHeight && !resizeWidth) {\n resizeWidth = Math.round(resizeHeight * originalAspectRatio)\n }\n\n // Calculate resizeHeight based on original aspect ratio if it's undefined\n if (resizeWidth && !resizeHeight) {\n resizeHeight = Math.round(resizeWidth / originalAspectRatio)\n }\n\n if (!resizeHeight) resizeHeight = resizeImageMeta.height\n if (!resizeWidth) resizeWidth = resizeImageMeta.width\n\n const resizeAspectRatio = resizeWidth / resizeHeight\n const prioritizeHeight = resizeAspectRatio < originalAspectRatio\n // Scales the image before extracting from it\n resized = imageToResize.resize({\n height: prioritizeHeight ? resizeHeight : undefined,\n width: prioritizeHeight ? undefined : resizeWidth,\n })\n\n const metadataAppendedFile = await optionallyAppendMetadata({\n req,\n sharpFile: resized,\n withMetadata,\n })\n\n // Must read from buffer, resized.metadata will return the original image metadata\n const { info } = await metadataAppendedFile.toBuffer({ resolveWithObject: true })\n\n resizeImageMeta.height = extractHeightFromImage({\n ...originalImageMeta,\n height: info.height,\n })\n resizeImageMeta.width = info.width\n\n const halfResizeX = resizeWidth / 2\n const xFocalCenter = resizeImageMeta.width * (incomingFocalPoint.x / 100)\n const calculatedRightPixelBound = xFocalCenter + halfResizeX\n let leftBound = xFocalCenter - halfResizeX\n\n // if the right bound is greater than the image width, adjust the left bound\n // keeping focus on the right\n if (calculatedRightPixelBound > resizeImageMeta.width) {\n leftBound = resizeImageMeta.width - resizeWidth\n }\n\n // if the left bound is less than 0, adjust the left bound to 0\n // keeping the focus on the left\n if (leftBound < 0) leftBound = 0\n\n const halfResizeY = resizeHeight / 2\n const yFocalCenter = resizeImageMeta.height * (incomingFocalPoint.y / 100)\n const calculatedBottomPixelBound = yFocalCenter + halfResizeY\n let topBound = yFocalCenter - halfResizeY\n\n // if the bottom bound is greater than the image height, adjust the top bound\n // keeping the image as far right as possible\n if (calculatedBottomPixelBound > resizeImageMeta.height) {\n topBound = resizeImageMeta.height - resizeHeight\n }\n\n // if the top bound is less than 0, adjust the top bound to 0\n // keeping the image focus near the top\n if (topBound < 0) topBound = 0\n\n resized = resized.extract({\n height: resizeHeight,\n left: Math.floor(leftBound),\n top: Math.floor(topBound),\n width: resizeWidth,\n })\n } else {\n resized = imageToResize.resize(imageResizeConfig)\n }\n\n if (imageResizeConfig.formatOptions) {\n resized = resized.toFormat(\n imageResizeConfig.formatOptions.format,\n imageResizeConfig.formatOptions.options,\n )\n }\n\n if (imageResizeConfig.trimOptions) {\n resized = resized.trim(imageResizeConfig.trimOptions)\n }\n\n const metadataAppendedFile = await optionallyAppendMetadata({\n req,\n sharpFile: resized,\n withMetadata,\n })\n\n const { data: bufferData, info: bufferInfo } = await metadataAppendedFile.toBuffer({\n resolveWithObject: true,\n })\n\n const sanitizedImage = getSanitizedImageData(savedFilename)\n\n if (req.payloadUploadSizes) {\n req.payloadUploadSizes[imageResizeConfig.name] = bufferData\n }\n\n const mimeInfo = await fileTypeFromBuffer(bufferData)\n\n const imageNameWithDimensions = imageResizeConfig.generateImageName\n ? imageResizeConfig.generateImageName({\n extension: mimeInfo?.ext || sanitizedImage.ext,\n height: extractHeightFromImage({\n ...originalImageMeta,\n height: bufferInfo.height,\n }),\n originalName: sanitizedImage.name,\n sizeName: imageResizeConfig.name,\n width: bufferInfo.width,\n })\n : createImageName({\n extension: mimeInfo?.ext || sanitizedImage.ext,\n height: extractHeightFromImage({\n ...originalImageMeta,\n height: bufferInfo.height,\n }),\n outputImageName: sanitizedImage.name,\n width: bufferInfo.width,\n })\n\n const imagePath = `${staticPath}/${imageNameWithDimensions}`\n\n if (await fileExists(imagePath)) {\n try {\n fs.unlinkSync(imagePath)\n } catch {\n // Ignore unlink errors\n }\n }\n\n const { height, size, width } = bufferInfo\n return createResult({\n name: imageResizeConfig.name,\n filename: imageNameWithDimensions,\n filesize: size,\n height:\n fileIsAnimatedType && originalImageMeta.pages ? height / originalImageMeta.pages : height,\n mimeType: mimeInfo?.mime || mimeType,\n sizesToSave: [{ buffer: bufferData, path: imagePath }],\n width,\n })\n }),\n )\n\n return results.reduce(\n (acc, result) => {\n Object.assign(acc.sizeData, result.sizeData)\n acc.sizesToSave.push(...result.sizesToSave)\n return acc\n },\n { ...defaultResult },\n )\n}\n"],"names":["fileTypeFromBuffer","fs","sanitize","isNumber","fileExists","optionallyAppendMetadata","getSanitizedImageData","sourceImage","extension","split","pop","name","substring","lastIndexOf","ext","createImageName","height","outputImageName","width","createResult","filename","filesize","mimeType","sizesToSave","sizeData","getImageResizeAction","dimensions","originalImage","hasFocalPoint","imageResizeConfig","fit","targetHeight","targetWidth","withoutEnlargement","withoutReduction","originalImageIsSmallerXAndY","undefined","originalImageIsSmallerXOrY","targetAspectRatio","originalAspectRatio","sanitizeResizeConfig","resizeConfig","position","extractHeightFromImage","sharpMetadata","pages","resizeAndTransformImageSizes","config","file","req","savedFilename","sharp","staticPath","uploadEdits","withMetadata","focalPoint","focalPointEnabled","imageSizes","upload","incomingFocalPoint","x","Math","round","y","defaultResult","fileIsAnimatedType","includes","mimetype","sharpOptions","animated","sharpBase","tempFilePath","data","rotate","originalImageMeta","metadata","resizeImageMeta","results","Promise","all","map","resizeAction","Boolean","imageToResize","clone","resized","resizeHeight","resizeWidth","resizeAspectRatio","prioritizeHeight","resize","metadataAppendedFile","sharpFile","info","toBuffer","resolveWithObject","halfResizeX","xFocalCenter","calculatedRightPixelBound","leftBound","halfResizeY","yFocalCenter","calculatedBottomPixelBound","topBound","extract","left","floor","top","formatOptions","toFormat","format","options","trimOptions","trim","bufferData","bufferInfo","sanitizedImage","payloadUploadSizes","mimeInfo","imageNameWithDimensions","generateImageName","originalName","sizeName","imagePath","unlinkSync","size","mime","buffer","path","reduce","acc","result","Object","assign","push"],"mappings":"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"}
|
package/dist/uploads/types.d.ts
CHANGED
|
@@ -41,12 +41,23 @@ export type ImageUploadFormatOptions = {
|
|
|
41
41
|
* @link https://sharp.pixelplumbing.com/api-resize#trim
|
|
42
42
|
*/
|
|
43
43
|
export type ImageUploadTrimOptions = Parameters<Sharp['trim']>[0];
|
|
44
|
+
export type GenerateImageName = (args: {
|
|
45
|
+
extension: string;
|
|
46
|
+
height: number;
|
|
47
|
+
originalName: string;
|
|
48
|
+
sizeName: string;
|
|
49
|
+
width: number;
|
|
50
|
+
}) => string;
|
|
44
51
|
export type ImageSize = {
|
|
45
52
|
/**
|
|
46
53
|
* @deprecated prefer position
|
|
47
54
|
*/
|
|
48
55
|
crop?: string;
|
|
49
56
|
formatOptions?: ImageUploadFormatOptions;
|
|
57
|
+
/**
|
|
58
|
+
* Generate a custom name for the file of this image size.
|
|
59
|
+
*/
|
|
60
|
+
generateImageName?: GenerateImageName;
|
|
50
61
|
name: string;
|
|
51
62
|
trimOptions?: ImageUploadTrimOptions;
|
|
52
63
|
/**
|
|
@@ -98,6 +109,10 @@ export type UploadConfig = {
|
|
|
98
109
|
* @default undefined
|
|
99
110
|
*/
|
|
100
111
|
externalFileHeaderFilter?: (headers: Record<string, string>) => Record<string, string>;
|
|
112
|
+
/**
|
|
113
|
+
* Field slugs to use for a compount index instead of the default filename index.
|
|
114
|
+
*/
|
|
115
|
+
filenameCompoundIndex?: string[];
|
|
101
116
|
/**
|
|
102
117
|
* Require files to be uploaded when creating a document.
|
|
103
118
|
* @default true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/uploads/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAA6B,MAAM,OAAO,CAAA;AAE5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAEjE,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAA;IACvB,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAA;IACvB,MAAM,EAAE,IAAI,GAAG,MAAM,CAAA;IACrB,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAA;IACvB,KAAK,EAAE,IAAI,GAAG,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,OAAO,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;CAC3C,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAEjE,MAAM,MAAM,SAAS,GAAG;IACtB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,wBAAwB,CAAA;IACxC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,sBAAsB,CAAA;IACpC;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;CACzD,GAAG,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAA;AAE7C,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,KAAK,KAAK,GAAG,IAAI,GAAG,MAAM,CAAA;AAEjG,MAAM,MAAM,YAAY,GAAG;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;QAII;IACJ,cAAc,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAA;IAC3C;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtF;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;OAEG;IACH,aAAa,CAAC,EAAE,wBAAwB,CAAA;IACxC;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,CAAC,CACV,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE;QACJ,GAAG,EAAE,UAAU,CAAA;QACf,MAAM,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KACjD,KACE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAA;IAC3D,UAAU,CAAC,EAAE,SAAS,EAAE,CAAA;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAA;IACtE;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,sBAAsB,CAAA;IACpC;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,YAAY,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,YAAY,CAAC,WAAW,CAAC,CAAA;CACrC,GAAG,YAAY,CAAA;AAEhB,MAAM,MAAM,IAAI,GAAG;IACjB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,GAAG,GAAG,IAAI,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/uploads/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/types.ts"],"sourcesContent":["import type { ResizeOptions, Sharp, Metadata as SharpMetadata } from 'sharp'\n\nimport type { TypeWithID } from '../collections/config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { WithMetadata } from './optionallyAppendMetadata.js'\n\nexport type FileSize = {\n filename: null | string\n filesize: null | number\n height: null | number\n mimeType: null | string\n width: null | number\n}\n\nexport type FileSizes = {\n [size: string]: FileSize\n}\n\nexport type FileData = {\n filename: string\n filesize: number\n focalX?: number\n focalY?: number\n height: number\n mimeType: string\n sizes: FileSizes\n tempFilePath?: string\n url?: string\n width: number\n}\n\nexport type ProbedImageSize = {\n height: number\n width: number\n}\n\n/**\n * Params sent to the sharp `toFormat()` function\n * @link https://sharp.pixelplumbing.com/api-output#toformat\n */\nexport type ImageUploadFormatOptions = {\n format: Parameters<Sharp['toFormat']>[0]\n options?: Parameters<Sharp['toFormat']>[1]\n}\n\n/**\n * Params sent to the sharp trim() function\n * @link https://sharp.pixelplumbing.com/api-resize#trim\n */\nexport type ImageUploadTrimOptions = Parameters<Sharp['trim']>[0]\n\nexport type ImageSize = {\n /**\n * @deprecated prefer position\n */\n crop?: string // comes from sharp package\n formatOptions?: ImageUploadFormatOptions\n name: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * When an uploaded image is smaller than the defined image size, we have 3 options:\n *\n * `undefined | false | true`\n *\n * 1. `undefined` [default]: uploading images with smaller width AND height than the image size will return null\n * 2. `false`: always enlarge images to the image size\n * 3. `true`: if the image is smaller than the image size, return the original image\n */\n withoutEnlargement?: ResizeOptions['withoutEnlargement']\n} & Omit<ResizeOptions, 'withoutEnlargement'>\n\nexport type GetAdminThumbnail = (args: { doc: Record<string, unknown> }) => false | null | string\n\nexport type UploadConfig = {\n /**\n * The adapter name to use for uploads. Used for storage adapter telemetry.\n * @default undefined\n */\n adapter?: string\n /**\n * Represents an admin thumbnail, which can be either a React component or a string.\n * - If a string, it should be one of the image size names.\n * - A function that generates a fully qualified URL for the thumbnail, receives the doc as the only argument.\n **/\n adminThumbnail?: GetAdminThumbnail | string\n /**\n * Enables cropping of images.\n * @default true\n */\n crop?: boolean\n /**\n * Disable the ability to save files to disk.\n * @default false\n */\n disableLocalStorage?: boolean\n /**\n * Enable displaying preview of the uploaded file in Upload fields related to this Collection.\n * Can be locally overridden by `displayPreview` option in Upload field.\n * @default false\n */\n displayPreview?: boolean\n /**\n * Ability to filter/modify Request Headers when fetching a file.\n *\n * Useful for adding custom headers to fetch from external providers.\n * @default undefined\n */\n externalFileHeaderFilter?: (headers: Record<string, string>) => Record<string, string>\n /**\n * Require files to be uploaded when creating a document.\n * @default true\n */\n filesRequiredOnCreate?: boolean\n /**\n * Enables focal point positioning for image manipulation.\n * @default false\n */\n focalPoint?: boolean\n /**\n * Format options for the uploaded file. Formatting image sizes needs to be done within each formatOptions individually.\n */\n formatOptions?: ImageUploadFormatOptions\n /**\n * Custom handlers to run when a file is fetched.\n *\n * - If a handler returns a Response, the response will be sent to the client and no further handlers will be run.\n * - If a handler returns null, the next handler will be run.\n * - If no handlers return a response the file will be returned by default.\n *\n * @default undefined\n */\n handlers?: ((\n req: PayloadRequest,\n args: {\n doc: TypeWithID\n params: { collection: string; filename: string }\n },\n ) => Promise<Response> | Promise<void> | Response | void)[]\n imageSizes?: ImageSize[]\n /**\n * Restrict mimeTypes in the file picker. Array of valid mime types or mimetype wildcards\n * @example ['image/*', 'application/pdf']\n * @default undefined\n */\n mimeTypes?: string[]\n /**\n * Ability to modify the response headers fetching a file.\n * @default undefined\n */\n modifyResponseHeaders?: ({ headers }: { headers: Headers }) => Headers\n /**\n * Sharp resize options for the original image.\n * @link https://sharp.pixelplumbing.com/api-resize#resize\n * @default undefined\n */\n resizeOptions?: ResizeOptions\n /**\n * The directory to serve static files from. Defaults to collection slug.\n * @default undefined\n */\n staticDir?: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * Optionally append metadata to the image during processing.\n *\n * Can be a boolean or a function.\n *\n * If true, metadata will be appended to the image.\n * If false, no metadata will be appended.\n * If a function, it will receive an object containing the metadata and should return a boolean indicating whether to append the metadata.\n * @default false\n */\n withMetadata?: WithMetadata\n}\n\nexport type SanitizedUploadConfig = {\n staticDir: UploadConfig['staticDir']\n} & UploadConfig\n\nexport type File = {\n /**\n * The buffer of the file.\n */\n data: Buffer\n /**\n * The mimetype of the file.\n */\n mimetype: string\n /**\n * The name of the file.\n */\n name: string\n /**\n * The size of the file in bytes.\n */\n size: number\n}\n\nexport type FileToSave = {\n /**\n * The buffer of the file.\n */\n buffer: Buffer\n /**\n * The path to save the file.\n */\n path: string\n}\n\ntype Crop = {\n height: number\n unit: '%' | 'px'\n width: number\n x: number\n y: number\n}\n\ntype FocalPoint = {\n x: number\n y: number\n}\n\nexport type UploadEdits = {\n crop?: Crop\n focalPoint?: FocalPoint\n heightInPixels?: number\n widthInPixels?: number\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/types.ts"],"sourcesContent":["import type { ResizeOptions, Sharp, Metadata as SharpMetadata } from 'sharp'\n\nimport type { TypeWithID } from '../collections/config/types.js'\nimport type { PayloadRequest } from '../types/index.js'\nimport type { WithMetadata } from './optionallyAppendMetadata.js'\n\nexport type FileSize = {\n filename: null | string\n filesize: null | number\n height: null | number\n mimeType: null | string\n width: null | number\n}\n\nexport type FileSizes = {\n [size: string]: FileSize\n}\n\nexport type FileData = {\n filename: string\n filesize: number\n focalX?: number\n focalY?: number\n height: number\n mimeType: string\n sizes: FileSizes\n tempFilePath?: string\n url?: string\n width: number\n}\n\nexport type ProbedImageSize = {\n height: number\n width: number\n}\n\n/**\n * Params sent to the sharp `toFormat()` function\n * @link https://sharp.pixelplumbing.com/api-output#toformat\n */\nexport type ImageUploadFormatOptions = {\n format: Parameters<Sharp['toFormat']>[0]\n options?: Parameters<Sharp['toFormat']>[1]\n}\n\n/**\n * Params sent to the sharp trim() function\n * @link https://sharp.pixelplumbing.com/api-resize#trim\n */\nexport type ImageUploadTrimOptions = Parameters<Sharp['trim']>[0]\n\nexport type GenerateImageName = (args: {\n extension: string\n height: number\n originalName: string\n sizeName: string\n width: number\n}) => string\n\nexport type ImageSize = {\n /**\n * @deprecated prefer position\n */\n crop?: string // comes from sharp package\n formatOptions?: ImageUploadFormatOptions\n /**\n * Generate a custom name for the file of this image size.\n */\n generateImageName?: GenerateImageName\n name: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * When an uploaded image is smaller than the defined image size, we have 3 options:\n *\n * `undefined | false | true`\n *\n * 1. `undefined` [default]: uploading images with smaller width AND height than the image size will return null\n * 2. `false`: always enlarge images to the image size\n * 3. `true`: if the image is smaller than the image size, return the original image\n */\n withoutEnlargement?: ResizeOptions['withoutEnlargement']\n} & Omit<ResizeOptions, 'withoutEnlargement'>\n\nexport type GetAdminThumbnail = (args: { doc: Record<string, unknown> }) => false | null | string\n\nexport type UploadConfig = {\n /**\n * The adapter name to use for uploads. Used for storage adapter telemetry.\n * @default undefined\n */\n adapter?: string\n /**\n * Represents an admin thumbnail, which can be either a React component or a string.\n * - If a string, it should be one of the image size names.\n * - A function that generates a fully qualified URL for the thumbnail, receives the doc as the only argument.\n **/\n adminThumbnail?: GetAdminThumbnail | string\n /**\n * Enables cropping of images.\n * @default true\n */\n crop?: boolean\n /**\n * Disable the ability to save files to disk.\n * @default false\n */\n disableLocalStorage?: boolean\n /**\n * Enable displaying preview of the uploaded file in Upload fields related to this Collection.\n * Can be locally overridden by `displayPreview` option in Upload field.\n * @default false\n */\n displayPreview?: boolean\n /**\n * Ability to filter/modify Request Headers when fetching a file.\n *\n * Useful for adding custom headers to fetch from external providers.\n * @default undefined\n */\n externalFileHeaderFilter?: (headers: Record<string, string>) => Record<string, string>\n /**\n * Field slugs to use for a compount index instead of the default filename index.\n */\n filenameCompoundIndex?: string[]\n /**\n * Require files to be uploaded when creating a document.\n * @default true\n */\n filesRequiredOnCreate?: boolean\n /**\n * Enables focal point positioning for image manipulation.\n * @default false\n */\n focalPoint?: boolean\n /**\n * Format options for the uploaded file. Formatting image sizes needs to be done within each formatOptions individually.\n */\n formatOptions?: ImageUploadFormatOptions\n /**\n * Custom handlers to run when a file is fetched.\n *\n * - If a handler returns a Response, the response will be sent to the client and no further handlers will be run.\n * - If a handler returns null, the next handler will be run.\n * - If no handlers return a response the file will be returned by default.\n *\n * @default undefined\n */\n handlers?: ((\n req: PayloadRequest,\n args: {\n doc: TypeWithID\n params: { collection: string; filename: string }\n },\n ) => Promise<Response> | Promise<void> | Response | void)[]\n imageSizes?: ImageSize[]\n /**\n * Restrict mimeTypes in the file picker. Array of valid mime types or mimetype wildcards\n * @example ['image/*', 'application/pdf']\n * @default undefined\n */\n mimeTypes?: string[]\n /**\n * Ability to modify the response headers fetching a file.\n * @default undefined\n */\n modifyResponseHeaders?: ({ headers }: { headers: Headers }) => Headers\n /**\n * Sharp resize options for the original image.\n * @link https://sharp.pixelplumbing.com/api-resize#resize\n * @default undefined\n */\n resizeOptions?: ResizeOptions\n /**\n * The directory to serve static files from. Defaults to collection slug.\n * @default undefined\n */\n staticDir?: string\n trimOptions?: ImageUploadTrimOptions\n /**\n * Optionally append metadata to the image during processing.\n *\n * Can be a boolean or a function.\n *\n * If true, metadata will be appended to the image.\n * If false, no metadata will be appended.\n * If a function, it will receive an object containing the metadata and should return a boolean indicating whether to append the metadata.\n * @default false\n */\n withMetadata?: WithMetadata\n}\n\nexport type SanitizedUploadConfig = {\n staticDir: UploadConfig['staticDir']\n} & UploadConfig\n\nexport type File = {\n /**\n * The buffer of the file.\n */\n data: Buffer\n /**\n * The mimetype of the file.\n */\n mimetype: string\n /**\n * The name of the file.\n */\n name: string\n /**\n * The size of the file in bytes.\n */\n size: number\n}\n\nexport type FileToSave = {\n /**\n * The buffer of the file.\n */\n buffer: Buffer\n /**\n * The path to save the file.\n */\n path: string\n}\n\ntype Crop = {\n height: number\n unit: '%' | 'px'\n width: number\n x: number\n y: number\n}\n\ntype FocalPoint = {\n x: number\n y: number\n}\n\nexport type UploadEdits = {\n crop?: Crop\n focalPoint?: FocalPoint\n heightInPixels?: number\n widthInPixels?: number\n}\n"],"names":[],"mappings":"AA8OA,WAKC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { ClientField } from '../fields/config/client.js';
|
|
2
|
+
import type { FieldTypes } from '../fields/config/types.js';
|
|
3
3
|
export type FieldSchemaJSON = {
|
|
4
4
|
blocks?: FieldSchemaJSON;
|
|
5
5
|
fields?: FieldSchemaJSON;
|
|
@@ -7,7 +7,7 @@ export type FieldSchemaJSON = {
|
|
|
7
7
|
name: string;
|
|
8
8
|
relationTo?: string;
|
|
9
9
|
slug?: string;
|
|
10
|
-
type:
|
|
10
|
+
type: FieldTypes;
|
|
11
11
|
}[];
|
|
12
|
-
export declare const fieldSchemaToJSON: (fields:
|
|
12
|
+
export declare const fieldSchemaToJSON: (fields: ClientField[]) => FieldSchemaJSON;
|
|
13
13
|
//# sourceMappingURL=fieldSchemaToJSON.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldSchemaToJSON.d.ts","sourceRoot":"","sources":["../../src/utilities/fieldSchemaToJSON.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"fieldSchemaToJSON.d.ts","sourceRoot":"","sources":["../../src/utilities/fieldSchemaToJSON.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAE3D,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,UAAU,CAAA;CACjB,EAAE,CAAA;AAEH,eAAO,MAAM,iBAAiB,WAAY,WAAW,EAAE,KAAG,eAkGzD,CAAA"}
|
|
@@ -4,20 +4,16 @@ export const fieldSchemaToJSON = (fields)=>{
|
|
|
4
4
|
switch(field.type){
|
|
5
5
|
case 'group':
|
|
6
6
|
acc.push({
|
|
7
|
-
// @ts-expect-error
|
|
8
7
|
name: field.name,
|
|
9
8
|
type: field.type,
|
|
10
|
-
// @ts-expect-error
|
|
11
9
|
fields: fieldSchemaToJSON(field.fields)
|
|
12
10
|
});
|
|
13
11
|
break;
|
|
14
12
|
case 'array':
|
|
15
13
|
acc.push({
|
|
16
|
-
// @ts-expect-error
|
|
17
14
|
name: field.name,
|
|
18
15
|
type: field.type,
|
|
19
16
|
fields: fieldSchemaToJSON([
|
|
20
|
-
// @ts-expect-error
|
|
21
17
|
...field.fields,
|
|
22
18
|
{
|
|
23
19
|
name: 'id',
|
|
@@ -28,10 +24,8 @@ export const fieldSchemaToJSON = (fields)=>{
|
|
|
28
24
|
break;
|
|
29
25
|
case 'blocks':
|
|
30
26
|
acc.push({
|
|
31
|
-
// @ts-expect-error
|
|
32
27
|
name: field.name,
|
|
33
28
|
type: field.type,
|
|
34
|
-
// @ts-expect-error
|
|
35
29
|
blocks: field.blocks.reduce((acc, block)=>{
|
|
36
30
|
acc[block.slug] = {
|
|
37
31
|
fields: fieldSchemaToJSON([
|
|
@@ -48,13 +42,11 @@ export const fieldSchemaToJSON = (fields)=>{
|
|
|
48
42
|
break;
|
|
49
43
|
case 'row':
|
|
50
44
|
case 'collapsible':
|
|
51
|
-
// @ts-expect-error
|
|
52
45
|
result = result.concat(fieldSchemaToJSON(field.fields));
|
|
53
46
|
break;
|
|
54
47
|
case 'tabs':
|
|
55
48
|
{
|
|
56
49
|
let tabFields = [];
|
|
57
|
-
// @ts-expect-error
|
|
58
50
|
field.tabs.forEach((tab)=>{
|
|
59
51
|
if ('name' in tab) {
|
|
60
52
|
tabFields.push({
|
|
@@ -72,11 +64,9 @@ export const fieldSchemaToJSON = (fields)=>{
|
|
|
72
64
|
case 'relationship':
|
|
73
65
|
case 'upload':
|
|
74
66
|
acc.push({
|
|
75
|
-
// @ts-expect-error
|
|
76
67
|
name: field.name,
|
|
77
68
|
type: field.type,
|
|
78
69
|
hasMany: 'hasMany' in field ? Boolean(field.hasMany) : false,
|
|
79
|
-
// @ts-expect-error
|
|
80
70
|
relationTo: field.relationTo
|
|
81
71
|
});
|
|
82
72
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/fieldSchemaToJSON.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/fieldSchemaToJSON.ts"],"sourcesContent":["import type { ClientField } from '../fields/config/client.js'\nimport type { FieldTypes } from '../fields/config/types.js'\n\nexport type FieldSchemaJSON = {\n blocks?: FieldSchemaJSON // TODO: conditionally add based on `type`\n fields?: FieldSchemaJSON // TODO: conditionally add based on `type`\n hasMany?: boolean // TODO: conditionally add based on `type`\n name: string\n relationTo?: string // TODO: conditionally add based on `type`\n slug?: string // TODO: conditionally add based on `type`\n type: FieldTypes\n}[]\n\nexport const fieldSchemaToJSON = (fields: ClientField[]): FieldSchemaJSON => {\n return fields.reduce((acc, field) => {\n let result = acc\n\n switch (field.type) {\n case 'group':\n acc.push({\n name: field.name,\n type: field.type,\n fields: fieldSchemaToJSON(field.fields),\n })\n\n break\n\n case 'array':\n acc.push({\n name: field.name,\n type: field.type,\n fields: fieldSchemaToJSON([\n ...field.fields,\n {\n name: 'id',\n type: 'text',\n },\n ]),\n })\n\n break\n\n case 'blocks':\n acc.push({\n name: field.name,\n type: field.type,\n blocks: field.blocks.reduce((acc, block) => {\n acc[block.slug] = {\n fields: fieldSchemaToJSON([\n ...block.fields,\n {\n name: 'id',\n type: 'text',\n },\n ]),\n }\n\n return acc\n }, {}),\n })\n\n break\n\n case 'row':\n case 'collapsible':\n result = result.concat(fieldSchemaToJSON(field.fields))\n break\n\n case 'tabs': {\n let tabFields = []\n\n field.tabs.forEach((tab) => {\n if ('name' in tab) {\n tabFields.push({\n name: tab.name,\n type: field.type,\n fields: fieldSchemaToJSON(tab.fields),\n })\n return\n }\n\n tabFields = tabFields.concat(fieldSchemaToJSON(tab.fields))\n })\n\n result = result.concat(tabFields)\n\n break\n }\n\n case 'relationship':\n case 'upload':\n acc.push({\n name: field.name,\n type: field.type,\n hasMany: 'hasMany' in field ? Boolean(field.hasMany) : false, // TODO: type this\n relationTo: field.relationTo,\n })\n\n break\n\n default:\n if ('name' in field) {\n acc.push({\n name: field.name,\n type: field.type,\n })\n }\n }\n\n return result\n }, [])\n}\n"],"names":["fieldSchemaToJSON","fields","reduce","acc","field","result","type","push","name","blocks","block","slug","concat","tabFields","tabs","forEach","tab","hasMany","Boolean","relationTo"],"mappings":"AAaA,OAAO,MAAMA,oBAAoB,CAACC;IAChC,OAAOA,OAAOC,MAAM,CAAC,CAACC,KAAKC;QACzB,IAAIC,SAASF;QAEb,OAAQC,MAAME,IAAI;YAChB,KAAK;gBACHH,IAAII,IAAI,CAAC;oBACPC,MAAMJ,MAAMI,IAAI;oBAChBF,MAAMF,MAAME,IAAI;oBAChBL,QAAQD,kBAAkBI,MAAMH,MAAM;gBACxC;gBAEA;YAEF,KAAK;gBACHE,IAAII,IAAI,CAAC;oBACPC,MAAMJ,MAAMI,IAAI;oBAChBF,MAAMF,MAAME,IAAI;oBAChBL,QAAQD,kBAAkB;2BACrBI,MAAMH,MAAM;wBACf;4BACEO,MAAM;4BACNF,MAAM;wBACR;qBACD;gBACH;gBAEA;YAEF,KAAK;gBACHH,IAAII,IAAI,CAAC;oBACPC,MAAMJ,MAAMI,IAAI;oBAChBF,MAAMF,MAAME,IAAI;oBAChBG,QAAQL,MAAMK,MAAM,CAACP,MAAM,CAAC,CAACC,KAAKO;wBAChCP,GAAG,CAACO,MAAMC,IAAI,CAAC,GAAG;4BAChBV,QAAQD,kBAAkB;mCACrBU,MAAMT,MAAM;gCACf;oCACEO,MAAM;oCACNF,MAAM;gCACR;6BACD;wBACH;wBAEA,OAAOH;oBACT,GAAG,CAAC;gBACN;gBAEA;YAEF,KAAK;YACL,KAAK;gBACHE,SAASA,OAAOO,MAAM,CAACZ,kBAAkBI,MAAMH,MAAM;gBACrD;YAEF,KAAK;gBAAQ;oBACX,IAAIY,YAAY,EAAE;oBAElBT,MAAMU,IAAI,CAACC,OAAO,CAAC,CAACC;wBAClB,IAAI,UAAUA,KAAK;4BACjBH,UAAUN,IAAI,CAAC;gCACbC,MAAMQ,IAAIR,IAAI;gCACdF,MAAMF,MAAME,IAAI;gCAChBL,QAAQD,kBAAkBgB,IAAIf,MAAM;4BACtC;4BACA;wBACF;wBAEAY,YAAYA,UAAUD,MAAM,CAACZ,kBAAkBgB,IAAIf,MAAM;oBAC3D;oBAEAI,SAASA,OAAOO,MAAM,CAACC;oBAEvB;gBACF;YAEA,KAAK;YACL,KAAK;gBACHV,IAAII,IAAI,CAAC;oBACPC,MAAMJ,MAAMI,IAAI;oBAChBF,MAAMF,MAAME,IAAI;oBAChBW,SAAS,aAAab,QAAQc,QAAQd,MAAMa,OAAO,IAAI;oBACvDE,YAAYf,MAAMe,UAAU;gBAC9B;gBAEA;YAEF;gBACE,IAAI,UAAUf,OAAO;oBACnBD,IAAII,IAAI,CAAC;wBACPC,MAAMJ,MAAMI,IAAI;wBAChBF,MAAMF,MAAME,IAAI;oBAClB;gBACF;QACJ;QAEA,OAAOD;IACT,GAAG,EAAE;AACP,EAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Field, FieldAffectingData, FieldPresentationalOnly } from '../fields/config/types.js';
|
|
1
|
+
import type { ClientField } from '../fields/config/client.js';
|
|
2
|
+
import type { Field, FieldAffectingData, FieldAffectingDataClient, FieldPresentationalOnly, FieldPresentationalOnlyClient } from '../fields/config/types.js';
|
|
3
|
+
type FlattenedField<T> = T extends ClientField ? FieldAffectingDataClient | FieldPresentationalOnlyClient : FieldAffectingData | FieldPresentationalOnly;
|
|
3
4
|
/**
|
|
4
5
|
* Flattens a collection's fields into a single array of fields, as long
|
|
5
6
|
* as the fields do not affect data.
|
|
@@ -7,6 +8,6 @@ import type { Field, FieldAffectingData, FieldPresentationalOnly } from '../fiel
|
|
|
7
8
|
* @param fields
|
|
8
9
|
* @param keepPresentationalFields if true, will skip flattening fields that are presentational only
|
|
9
10
|
*/
|
|
10
|
-
declare
|
|
11
|
+
declare function flattenFields<T extends ClientField | Field>(fields: T[], keepPresentationalFields?: boolean): FlattenedField<T>[];
|
|
11
12
|
export default flattenFields;
|
|
12
13
|
//# sourceMappingURL=flattenTopLevelFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flattenTopLevelFields.d.ts","sourceRoot":"","sources":["../../src/utilities/flattenTopLevelFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"flattenTopLevelFields.d.ts","sourceRoot":"","sources":["../../src/utilities/flattenTopLevelFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,KAAK,EACV,KAAK,EACL,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,EAE9B,MAAM,2BAA2B,CAAA;AAUlC,KAAK,cAAc,CAAC,CAAC,IAAI,CAAC,SAAS,WAAW,GAC1C,wBAAwB,GAAG,6BAA6B,GACxD,kBAAkB,GAAG,uBAAuB,CAAA;AAIhD;;;;;;GAMG;AACH,iBAAS,aAAa,CAAC,CAAC,SAAS,WAAW,GAAG,KAAK,EAClD,MAAM,EAAE,CAAC,EAAE,EACX,wBAAwB,CAAC,EAAE,OAAO,GACjC,cAAc,CAAC,CAAC,CAAC,EAAE,CAyBrB;AAED,eAAe,aAAa,CAAA"}
|
|
@@ -5,7 +5,7 @@ import { fieldAffectsData, fieldHasSubFields, fieldIsPresentationalOnly, tabHasN
|
|
|
5
5
|
*
|
|
6
6
|
* @param fields
|
|
7
7
|
* @param keepPresentationalFields if true, will skip flattening fields that are presentational only
|
|
8
|
-
*/
|
|
8
|
+
*/ function flattenFields(fields, keepPresentationalFields) {
|
|
9
9
|
return fields.reduce((fieldsToUse, field)=>{
|
|
10
10
|
if (fieldAffectsData(field) || keepPresentationalFields && fieldIsPresentationalOnly(field)) {
|
|
11
11
|
return [
|
|
@@ -23,21 +23,26 @@ import { fieldAffectsData, fieldHasSubFields, fieldIsPresentationalOnly, tabHasN
|
|
|
23
23
|
return [
|
|
24
24
|
...fieldsToUse,
|
|
25
25
|
...field.tabs.reduce((tabFields, tab)=>{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
if (tabHasName(tab)) {
|
|
27
|
+
return [
|
|
28
|
+
...tabFields,
|
|
29
29
|
{
|
|
30
30
|
...tab,
|
|
31
31
|
type: 'tab'
|
|
32
32
|
}
|
|
33
|
-
]
|
|
34
|
-
|
|
33
|
+
];
|
|
34
|
+
} else {
|
|
35
|
+
return [
|
|
36
|
+
...tabFields,
|
|
37
|
+
...flattenFields(tab.fields, keepPresentationalFields)
|
|
38
|
+
];
|
|
39
|
+
}
|
|
35
40
|
}, [])
|
|
36
41
|
];
|
|
37
42
|
}
|
|
38
43
|
return fieldsToUse;
|
|
39
44
|
}, []);
|
|
40
|
-
}
|
|
45
|
+
}
|
|
41
46
|
export default flattenFields;
|
|
42
47
|
|
|
43
48
|
//# sourceMappingURL=flattenTopLevelFields.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/flattenTopLevelFields.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/flattenTopLevelFields.ts"],"sourcesContent":["import type { ClientField } from '../fields/config/client.js'\nimport type {\n Field,\n FieldAffectingData,\n FieldAffectingDataClient,\n FieldPresentationalOnly,\n FieldPresentationalOnlyClient,\n Tab,\n} from '../fields/config/types.js'\n\nimport {\n fieldAffectsData,\n fieldHasSubFields,\n fieldIsPresentationalOnly,\n tabHasName,\n} from '../fields/config/types.js'\nimport { ClientTab } from '../admin/fields/Tabs.js'\n\ntype FlattenedField<T> = T extends ClientField\n ? FieldAffectingDataClient | FieldPresentationalOnlyClient\n : FieldAffectingData | FieldPresentationalOnly\n\ntype TabType<T> = T extends ClientField ? ClientTab : Tab\n\n/**\n * Flattens a collection's fields into a single array of fields, as long\n * as the fields do not affect data.\n *\n * @param fields\n * @param keepPresentationalFields if true, will skip flattening fields that are presentational only\n */\nfunction flattenFields<T extends ClientField | Field>(\n fields: T[],\n keepPresentationalFields?: boolean,\n): FlattenedField<T>[] {\n return fields.reduce<FlattenedField<T>[]>((fieldsToUse, field) => {\n if (fieldAffectsData(field) || (keepPresentationalFields && fieldIsPresentationalOnly(field))) {\n return [...fieldsToUse, field as FlattenedField<T>]\n }\n\n if (fieldHasSubFields(field)) {\n return [...fieldsToUse, ...flattenFields(field.fields as T[], keepPresentationalFields)]\n }\n\n if (field.type === 'tabs' && 'tabs' in field) {\n return [\n ...fieldsToUse,\n ...field.tabs.reduce<FlattenedField<T>[]>((tabFields, tab: TabType<T>) => {\n if (tabHasName(tab)) {\n return [...tabFields, { ...tab, type: 'tab' } as unknown as FlattenedField<T>]\n } else {\n return [...tabFields, ...flattenFields(tab.fields as T[], keepPresentationalFields)]\n }\n }, []),\n ]\n }\n\n return fieldsToUse\n }, [])\n}\n\nexport default flattenFields\n"],"names":["fieldAffectsData","fieldHasSubFields","fieldIsPresentationalOnly","tabHasName","flattenFields","fields","keepPresentationalFields","reduce","fieldsToUse","field","type","tabs","tabFields","tab"],"mappings":"AAUA,SACEA,gBAAgB,EAChBC,iBAAiB,EACjBC,yBAAyB,EACzBC,UAAU,QACL,4BAA2B;AASlC;;;;;;CAMC,GACD,SAASC,cACPC,MAAW,EACXC,wBAAkC;IAElC,OAAOD,OAAOE,MAAM,CAAsB,CAACC,aAAaC;QACtD,IAAIT,iBAAiBS,UAAWH,4BAA4BJ,0BAA0BO,QAAS;YAC7F,OAAO;mBAAID;gBAAaC;aAA2B;QACrD;QAEA,IAAIR,kBAAkBQ,QAAQ;YAC5B,OAAO;mBAAID;mBAAgBJ,cAAcK,MAAMJ,MAAM,EAASC;aAA0B;QAC1F;QAEA,IAAIG,MAAMC,IAAI,KAAK,UAAU,UAAUD,OAAO;YAC5C,OAAO;mBACFD;mBACAC,MAAME,IAAI,CAACJ,MAAM,CAAsB,CAACK,WAAWC;oBACpD,IAAIV,WAAWU,MAAM;wBACnB,OAAO;+BAAID;4BAAW;gCAAE,GAAGC,GAAG;gCAAEH,MAAM;4BAAM;yBAAkC;oBAChF,OAAO;wBACL,OAAO;+BAAIE;+BAAcR,cAAcS,IAAIR,MAAM,EAASC;yBAA0B;oBACtF;gBACF,GAAG,EAAE;aACN;QACH;QAEA,OAAOE;IACT,GAAG,EAAE;AACP;AAEA,eAAeJ,cAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getEntityPolicies.d.ts","sourceRoot":"","sources":["../../src/utilities/getEntityPolicies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAC9E,OAAO,KAAK,EAAE,yBAAyB,EAAc,MAAM,gCAAgC,CAAA;AAG3F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,KAAK,EAAE,aAAa,EAAY,cAAc,EAAS,MAAM,mBAAmB,CAAA;AAIvF,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,yBAAyB,GAAG,qBAAqB,CAAA;IACzD,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,GAAG,EAAE,cAAc,CAAA;IACnB,IAAI,EAAE,YAAY,GAAG,QAAQ,CAAA;CAC9B,CAAA;AAED,KAAK,UAAU,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,GACxD,gBAAgB,GAChB,oBAAoB,CAAA;AAYxB,wBAAsB,iBAAiB,CAAC,CAAC,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"getEntityPolicies.d.ts","sourceRoot":"","sources":["../../src/utilities/getEntityPolicies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAC9E,OAAO,KAAK,EAAE,yBAAyB,EAAc,MAAM,gCAAgC,CAAA;AAG3F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,KAAK,EAAE,aAAa,EAAY,cAAc,EAAS,MAAM,mBAAmB,CAAA;AAIvF,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,yBAAyB,GAAG,qBAAqB,CAAA;IACzD,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,GAAG,EAAE,cAAc,CAAA;IACnB,IAAI,EAAE,YAAY,GAAG,QAAQ,CAAA;CAC9B,CAAA;AAED,KAAK,UAAU,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,QAAQ,GACxD,gBAAgB,GAChB,oBAAoB,CAAA;AAYxB,wBAAsB,iBAAiB,CAAC,CAAC,SAAS,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CA4OvF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tabHasName } from '../fields/config/types.js';
|
|
2
2
|
export async function getEntityPolicies(args) {
|
|
3
3
|
const { id, type, entity, operations, req } = args;
|
|
4
|
-
const { data, payload, user } = req;
|
|
4
|
+
const { data, locale, payload, user } = req;
|
|
5
5
|
const isLoggedIn = !!user;
|
|
6
6
|
const policies = {
|
|
7
7
|
fields: {}
|
|
@@ -12,6 +12,8 @@ export async function getEntityPolicies(args) {
|
|
|
12
12
|
if (type === 'global') {
|
|
13
13
|
return payload.findGlobal({
|
|
14
14
|
slug: entity.slug,
|
|
15
|
+
fallbackLocale: null,
|
|
16
|
+
locale,
|
|
15
17
|
overrideAccess: true,
|
|
16
18
|
req
|
|
17
19
|
});
|
|
@@ -21,7 +23,9 @@ export async function getEntityPolicies(args) {
|
|
|
21
23
|
const paginatedRes = await payload.find({
|
|
22
24
|
collection: entity.slug,
|
|
23
25
|
depth: 0,
|
|
26
|
+
fallbackLocale: null,
|
|
24
27
|
limit: 1,
|
|
28
|
+
locale,
|
|
25
29
|
overrideAccess: true,
|
|
26
30
|
pagination: false,
|
|
27
31
|
req,
|
|
@@ -43,6 +47,8 @@ export async function getEntityPolicies(args) {
|
|
|
43
47
|
id,
|
|
44
48
|
collection: entity.slug,
|
|
45
49
|
depth: 0,
|
|
50
|
+
fallbackLocale: null,
|
|
51
|
+
locale,
|
|
46
52
|
overrideAccess: true,
|
|
47
53
|
req
|
|
48
54
|
});
|
|
@@ -83,9 +89,9 @@ export async function getEntityPolicies(args) {
|
|
|
83
89
|
const executeFieldPolicies = async ({ entityPermission, fields, operation, policiesObj })=>{
|
|
84
90
|
const mutablePolicies = policiesObj.fields;
|
|
85
91
|
await Promise.all(fields.map(async (field)=>{
|
|
86
|
-
if (field.name) {
|
|
92
|
+
if ('name' in field && field.name) {
|
|
87
93
|
if (!mutablePolicies[field.name]) mutablePolicies[field.name] = {};
|
|
88
|
-
if (field.access && typeof field.access[operation] === 'function') {
|
|
94
|
+
if ('access' in field && field.access && typeof field.access[operation] === 'function') {
|
|
89
95
|
await createAccessPromise({
|
|
90
96
|
access: field.access[operation],
|
|
91
97
|
accessLevel: 'field',
|
|
@@ -98,7 +104,7 @@ export async function getEntityPolicies(args) {
|
|
|
98
104
|
permission: policiesObj[operation]?.permission
|
|
99
105
|
};
|
|
100
106
|
}
|
|
101
|
-
if (field.fields) {
|
|
107
|
+
if ('fields' in field && field.fields) {
|
|
102
108
|
if (!mutablePolicies[field.name].fields) mutablePolicies[field.name].fields = {};
|
|
103
109
|
await executeFieldPolicies({
|
|
104
110
|
entityPermission,
|
|
@@ -107,7 +113,7 @@ export async function getEntityPolicies(args) {
|
|
|
107
113
|
policiesObj: mutablePolicies[field.name]
|
|
108
114
|
});
|
|
109
115
|
}
|
|
110
|
-
if (field?.blocks) {
|
|
116
|
+
if ('blocks' in field && field?.blocks) {
|
|
111
117
|
if (!mutablePolicies[field.name]?.blocks) mutablePolicies[field.name].blocks = {};
|
|
112
118
|
await Promise.all(field.blocks.map(async (block)=>{
|
|
113
119
|
if (!mutablePolicies[field.name].blocks?.[block.slug]) {
|
|
@@ -130,7 +136,7 @@ export async function getEntityPolicies(args) {
|
|
|
130
136
|
});
|
|
131
137
|
}));
|
|
132
138
|
}
|
|
133
|
-
} else if (field.fields) {
|
|
139
|
+
} else if ('fields' in field && field.fields) {
|
|
134
140
|
await executeFieldPolicies({
|
|
135
141
|
entityPermission,
|
|
136
142
|
fields: field.fields,
|