@payloadcms/plugin-cloud-storage 4.0.0-internal.934870d → 4.0.0-internal.952ed66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/exports/utilities.d.ts +1 -0
- package/dist/exports/utilities.d.ts.map +1 -1
- package/dist/exports/utilities.js +1 -0
- package/dist/exports/utilities.js.map +1 -1
- package/dist/fields/getFields.js.map +1 -1
- package/dist/hooks/afterChange.d.ts.map +1 -1
- package/dist/hooks/afterChange.js +74 -11
- package/dist/hooks/afterChange.js.map +1 -1
- package/dist/hooks/afterDelete.d.ts +7 -1
- package/dist/hooks/afterDelete.d.ts.map +1 -1
- package/dist/hooks/afterDelete.js +99 -26
- package/dist/hooks/afterDelete.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +7 -1
- package/dist/plugin.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/resolveSignedURLKey.d.ts +3 -1
- package/dist/utilities/resolveSignedURLKey.d.ts.map +1 -1
- package/dist/utilities/resolveSignedURLKey.js +18 -4
- package/dist/utilities/resolveSignedURLKey.js.map +1 -1
- package/package.json +22 -24
|
@@ -2,4 +2,5 @@ export { buildStoragePathData, buildUploadStoragePathData, isStoragePathWithinCo
|
|
|
2
2
|
export { getFilePrefix } from '../utilities/getFilePrefix.js';
|
|
3
3
|
export { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js';
|
|
4
4
|
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
5
|
+
export { resignClientUploadReceipt } from 'payload/internal';
|
|
5
6
|
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/exports/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,mCAAmC,GACpC,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA"}
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/exports/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,mCAAmC,GACpC,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -2,5 +2,6 @@ export { buildStoragePathData, buildUploadStoragePathData, isStoragePathWithinCo
|
|
|
2
2
|
export { getFilePrefix } from '../utilities/getFilePrefix.js';
|
|
3
3
|
export { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js';
|
|
4
4
|
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
5
|
+
export { resignClientUploadReceipt } from 'payload/internal';
|
|
5
6
|
|
|
6
7
|
//# sourceMappingURL=utilities.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/utilities.ts"],"sourcesContent":["export {\n buildStoragePathData,\n buildUploadStoragePathData,\n isStoragePathWithinCollectionPrefix,\n} from '../utilities/buildStoragePathData.js'\nexport { getFilePrefix } from '../utilities/getFilePrefix.js'\nexport { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js'\nexport { sanitizePrefix } from '../utilities/sanitizePrefix.js'\n"],"names":["buildStoragePathData","buildUploadStoragePathData","isStoragePathWithinCollectionPrefix","getFilePrefix","resolveSignedURLKey","sanitizePrefix"],"mappings":"AAAA,SACEA,oBAAoB,EACpBC,0BAA0B,EAC1BC,mCAAmC,QAC9B,uCAAsC;AAC7C,SAASC,aAAa,QAAQ,gCAA+B;AAC7D,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,cAAc,QAAQ,iCAAgC"}
|
|
1
|
+
{"version":3,"sources":["../../src/exports/utilities.ts"],"sourcesContent":["export {\n buildStoragePathData,\n buildUploadStoragePathData,\n isStoragePathWithinCollectionPrefix,\n} from '../utilities/buildStoragePathData.js'\nexport { getFilePrefix } from '../utilities/getFilePrefix.js'\nexport { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js'\nexport { sanitizePrefix } from '../utilities/sanitizePrefix.js'\nexport { resignClientUploadReceipt } from 'payload/internal'\n"],"names":["buildStoragePathData","buildUploadStoragePathData","isStoragePathWithinCollectionPrefix","getFilePrefix","resolveSignedURLKey","sanitizePrefix","resignClientUploadReceipt"],"mappings":"AAAA,SACEA,oBAAoB,EACpBC,0BAA0B,EAC1BC,mCAAmC,QAC9B,uCAAsC;AAC7C,SAASC,aAAa,QAAQ,gCAA+B;AAC7D,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,cAAc,QAAQ,iCAAgC;AAC/D,SAASC,yBAAyB,QAAQ,mBAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/getFields.ts"],"sourcesContent":["import type { CollectionConfig, Field, GroupField, SanitizedUploadConfig, TextField } from 'payload'\n\nimport path from 'path'\n\nimport type { GeneratedAdapter, GenerateFileURL } from '../types.js'\n\nimport { getAfterReadHook } from '../hooks/afterRead.js'\nimport { getBeforeChangeHook } from '../hooks/beforeChange.js'\nimport { getNormalizeUploadPrefixFieldHook } from '../hooks/normalizeUploadPrefix.js'\n\ninterface Args {\n adapter?: GeneratedAdapter\n collection: CollectionConfig\n disablePayloadAccessControl?: true\n generateFileURL?: GenerateFileURL\n prefix?: string\n /**\n * When true, do not default the `prefix` field to the collection prefix; the\n * document field holds only the document-level segment.\n */\n useCompositePrefixes?: boolean\n}\n\nexport const getFields = ({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n prefix,\n useCompositePrefixes = false,\n}: Args): Field[] => {\n const baseURLField: TextField = {\n name: 'url',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'URL',\n }\n\n const basePrefixField: TextField = {\n name: 'prefix',\n type: 'text',\n admin: {\n disabled: {\n bulkEdit: true,\n column: true,\n filter: true,\n groupBy: true,\n },\n hidden: true,\n readOnly: true,\n },\n }\n\n // Server-owned key segment. Field-level `hidden` would remove it before the URL hooks can read it.\n const baseObjectKeyField: TextField = {\n name: '_objectKey',\n type: 'text',\n admin: {\n disabled: {\n bulkEdit: true,\n column: true,\n filter: true,\n groupBy: true,\n },\n hidden: true,\n readOnly: true,\n },\n }\n\n const storedPrefixField: TextField = {\n ...basePrefixField,\n admin: {\n ...basePrefixField.admin,\n disabled: true,\n },\n }\n\n const fields = [...collection.fields, ...(adapter?.fields || [])]\n\n // Inject a hook into all URL fields to generate URLs\n\n let existingURLFieldIndex = -1\n\n const existingURLField = fields.find((existingField, i) => {\n if ('name' in existingField && existingField.name === 'url') {\n existingURLFieldIndex = i\n return true\n }\n return false\n }) as TextField\n\n if (existingURLFieldIndex > -1) {\n fields.splice(existingURLFieldIndex, 1)\n }\n\n // Only add afterRead hook if adapter is provided\n if (adapter) {\n fields.push({\n ...baseURLField,\n ...(existingURLField || {}),\n hooks: {\n afterRead: [\n getAfterReadHook({ adapter, collection, disablePayloadAccessControl, generateFileURL }),\n ...(existingURLField?.hooks?.afterRead || []),\n ],\n beforeChange: [\n getBeforeChangeHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n }),\n ...(existingURLField?.hooks?.beforeChange || []),\n ],\n },\n } as TextField)\n } else {\n fields.push({\n ...baseURLField,\n ...(existingURLField || {}),\n } as TextField)\n }\n\n let originalField = fields.find(\n (field): field is GroupField =>\n field.type === 'group' && 'name' in field && field.name === 'original',\n )\n\n if (adapter && !originalField) {\n originalField = {\n name: 'original',\n type: 'group',\n fields: [baseURLField],\n }\n fields.push(originalField)\n }\n\n const originalURLFieldIndex = originalField?.fields.findIndex(\n (field) => 'name' in field && field.name === 'url',\n )\n\n if (\n adapter &&\n originalField &&\n originalURLFieldIndex !== undefined &&\n originalURLFieldIndex >= 0\n ) {\n const originalURLField = originalField.fields[originalURLFieldIndex] as TextField\n\n originalField.fields[originalURLFieldIndex] = {\n ...baseURLField,\n ...originalURLField,\n hooks: {\n afterRead: [\n getAfterReadHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n isOriginal: true,\n }),\n ...(originalURLField.hooks?.afterRead || []),\n ],\n beforeChange: [\n getBeforeChangeHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n isOriginal: true,\n }),\n ...(originalURLField.hooks?.beforeChange || []),\n ],\n },\n } as TextField\n }\n\n // Storage adapters add these fields during their `init`, after transformers (e.g. Sharp) have\n // written each collection's image sizes onto its upload config.\n const variants =\n typeof collection.upload === 'object'\n ? (collection.upload as SanitizedUploadConfig).variants\n : undefined\n\n if (variants) {\n let existingSizesFieldIndex = -1\n\n const existingSizesField = fields.find((existingField, i) => {\n if ('name' in existingField && existingField.name === 'variants') {\n existingSizesFieldIndex = i\n return true\n }\n\n return false\n }) as GroupField\n\n if (existingSizesFieldIndex > -1) {\n fields.splice(existingSizesFieldIndex, 1)\n }\n\n const sizesField: Field = {\n ...(existingSizesField || {}),\n name: 'variants',\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: variants.map((size) => {\n const existingSizeField = existingSizesField?.fields.find(\n (existingField) => 'name' in existingField && existingField.name === size.name,\n ) as GroupField\n\n const existingSizeURLField = existingSizeField?.fields.find(\n (existingField) => 'name' in existingField && existingField.name === 'url',\n ) as TextField\n\n // Only add afterRead hook if adapter is provided\n const sizeURLField: TextField = adapter\n ? ({\n ...(existingSizeURLField || {}),\n ...baseURLField,\n hooks: {\n afterRead: [\n getAfterReadHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n size,\n }),\n ...((typeof existingSizeURLField === 'object' &&\n 'hooks' in existingSizeURLField &&\n existingSizeURLField?.hooks?.afterRead) ||\n []),\n ],\n beforeChange: [\n getBeforeChangeHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n size,\n }),\n ...((typeof existingSizeURLField === 'object' &&\n 'hooks' in existingSizeURLField &&\n existingSizeURLField?.hooks?.beforeChange) ||\n []),\n ],\n },\n } as TextField)\n : ({\n ...(existingSizeURLField || {}),\n ...baseURLField,\n } as TextField)\n\n return {\n ...existingSizeField,\n name: size.name,\n type: 'group',\n fields: [\n ...(adapter?.fields || []).filter(\n (field) => !('name' in field && ['_objectKey', 'prefix'].includes(field.name)),\n ),\n sizeURLField,\n storedPrefixField,\n baseObjectKeyField,\n ],\n } as Field\n }),\n }\n\n fields.push(sizesField)\n }\n\n // Always insert the prefix field so the schema stays consistent regardless of\n // whether the plugin is enabled or a prefix is configured.\n let existingPrefixFieldIndex = -1\n\n const existingPrefixField = fields.find((existingField, i) => {\n if ('name' in existingField && existingField.name === 'prefix') {\n existingPrefixFieldIndex = i\n return true\n }\n return false\n }) as TextField\n\n if (existingPrefixFieldIndex > -1) {\n fields.splice(existingPrefixFieldIndex, 1)\n }\n\n fields.push({\n ...basePrefixField,\n ...(existingPrefixField || {}),\n defaultValue:\n existingPrefixField?.defaultValue ??\n (useCompositePrefixes ? '' : prefix ? path.posix.join(prefix) : ''),\n hooks: {\n ...existingPrefixField?.hooks,\n beforeChange: [\n ...(existingPrefixField?.hooks?.beforeChange || []),\n getNormalizeUploadPrefixFieldHook({ collectionPrefix: prefix, useCompositePrefixes }),\n ],\n },\n } as TextField)\n\n const existingObjectKeyFieldIndex = fields.findIndex(\n (existingField) => 'name' in existingField && existingField.name === '_objectKey',\n )\n if (existingObjectKeyFieldIndex > -1) {\n fields.splice(existingObjectKeyFieldIndex, 1)\n }\n\n fields.push({ ...baseObjectKeyField } as TextField)\n\n return fields\n}\n"],"names":["path","getAfterReadHook","getBeforeChangeHook","getNormalizeUploadPrefixFieldHook","getFields","adapter","collection","disablePayloadAccessControl","generateFileURL","prefix","useCompositePrefixes","baseURLField","name","type","admin","hidden","readOnly","label","basePrefixField","disabled","bulkEdit","column","filter","groupBy","baseObjectKeyField","storedPrefixField","fields","existingURLFieldIndex","existingURLField","find","existingField","i","splice","push","hooks","afterRead","beforeChange","originalField","field","originalURLFieldIndex","findIndex","undefined","originalURLField","isOriginal","variants","upload","existingSizesFieldIndex","existingSizesField","sizesField","map","size","existingSizeField","existingSizeURLField","sizeURLField","includes","existingPrefixFieldIndex","existingPrefixField","defaultValue","posix","join","collectionPrefix","existingObjectKeyFieldIndex"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/fields/getFields.ts"],"sourcesContent":["import type { CollectionConfig, Field, GroupField, SanitizedUploadConfig, TextField } from 'payload'\n\nimport path from 'path'\n\nimport type { GeneratedAdapter, GenerateFileURL } from '../types.js'\n\nimport { getAfterReadHook } from '../hooks/afterRead.js'\nimport { getBeforeChangeHook } from '../hooks/beforeChange.js'\nimport { getNormalizeUploadPrefixFieldHook } from '../hooks/normalizeUploadPrefix.js'\n\ninterface Args {\n adapter?: GeneratedAdapter\n collection: CollectionConfig\n disablePayloadAccessControl?: true\n generateFileURL?: GenerateFileURL\n prefix?: string\n /**\n * When true, do not default the `prefix` field to the collection prefix; the\n * document field holds only the document-level segment.\n */\n useCompositePrefixes?: boolean\n}\n\nexport const getFields = ({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n prefix,\n useCompositePrefixes = false,\n}: Args): Field[] => {\n const baseURLField: TextField = {\n name: 'url',\n type: 'text',\n admin: {\n hidden: true,\n readOnly: true,\n },\n label: 'URL',\n }\n\n const basePrefixField: TextField = {\n name: 'prefix',\n type: 'text',\n admin: {\n disabled: {\n bulkEdit: true,\n column: true,\n filter: true,\n groupBy: true,\n },\n hidden: true,\n readOnly: true,\n },\n }\n\n // Server-owned key segment. Field-level `hidden` would remove it before the URL hooks can read it.\n const baseObjectKeyField: TextField = {\n name: '_objectKey',\n type: 'text',\n admin: {\n disabled: {\n bulkEdit: true,\n column: true,\n filter: true,\n groupBy: true,\n },\n hidden: true,\n readOnly: true,\n },\n }\n\n const storedPrefixField: TextField = {\n ...basePrefixField,\n admin: {\n ...basePrefixField.admin,\n disabled: true,\n },\n }\n\n const fields = [...collection.fields, ...(adapter?.fields || [])]\n\n // Inject a hook into all URL fields to generate URLs\n\n let existingURLFieldIndex = -1\n\n const existingURLField = fields.find((existingField, i) => {\n if ('name' in existingField && existingField.name === 'url') {\n existingURLFieldIndex = i\n return true\n }\n return false\n }) as TextField\n\n if (existingURLFieldIndex > -1) {\n fields.splice(existingURLFieldIndex, 1)\n }\n\n // Only add afterRead hook if adapter is provided\n if (adapter) {\n fields.push({\n ...baseURLField,\n ...(existingURLField || {}),\n hooks: {\n afterRead: [\n getAfterReadHook({ adapter, collection, disablePayloadAccessControl, generateFileURL }),\n ...(existingURLField?.hooks?.afterRead || []),\n ],\n beforeChange: [\n getBeforeChangeHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n }),\n ...(existingURLField?.hooks?.beforeChange || []),\n ],\n },\n } as TextField)\n } else {\n fields.push({\n ...baseURLField,\n ...(existingURLField || {}),\n } as TextField)\n }\n\n let originalField = fields.find(\n (field): field is GroupField =>\n field.type === 'group' && 'name' in field && field.name === 'original',\n )\n\n if (adapter && !originalField) {\n originalField = {\n name: 'original',\n type: 'group',\n fields: [baseURLField],\n }\n fields.push(originalField)\n }\n\n const originalURLFieldIndex = originalField?.fields.findIndex(\n (field) => 'name' in field && field.name === 'url',\n )\n\n if (\n adapter &&\n originalField &&\n originalURLFieldIndex !== undefined &&\n originalURLFieldIndex >= 0\n ) {\n const originalURLField = originalField.fields[originalURLFieldIndex] as TextField\n\n originalField.fields[originalURLFieldIndex] = {\n ...baseURLField,\n ...originalURLField,\n hooks: {\n afterRead: [\n getAfterReadHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n isOriginal: true,\n }),\n ...(originalURLField.hooks?.afterRead || []),\n ],\n beforeChange: [\n getBeforeChangeHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n isOriginal: true,\n }),\n ...(originalURLField.hooks?.beforeChange || []),\n ],\n },\n } as TextField\n }\n\n // Storage adapters add these fields during their `init`, after transformers (e.g. Sharp) have\n // written each collection's image sizes onto its upload config.\n const variants =\n typeof collection.upload === 'object'\n ? (collection.upload as SanitizedUploadConfig).variants\n : undefined\n\n if (variants) {\n let existingSizesFieldIndex = -1\n\n const existingSizesField = fields.find((existingField, i) => {\n if ('name' in existingField && existingField.name === 'variants') {\n existingSizesFieldIndex = i\n return true\n }\n\n return false\n }) as GroupField\n\n if (existingSizesFieldIndex > -1) {\n fields.splice(existingSizesFieldIndex, 1)\n }\n\n const sizesField: Field = {\n ...(existingSizesField || {}),\n name: 'variants',\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: variants.map((size) => {\n const existingSizeField = existingSizesField?.fields.find(\n (existingField) => 'name' in existingField && existingField.name === size.name,\n ) as GroupField\n\n const existingSizeURLField = existingSizeField?.fields.find(\n (existingField) => 'name' in existingField && existingField.name === 'url',\n ) as TextField\n\n // Only add afterRead hook if adapter is provided\n const sizeURLField: TextField = adapter\n ? ({\n ...(existingSizeURLField || {}),\n ...baseURLField,\n hooks: {\n afterRead: [\n getAfterReadHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n size,\n }),\n ...((typeof existingSizeURLField === 'object' &&\n 'hooks' in existingSizeURLField &&\n existingSizeURLField?.hooks?.afterRead) ||\n []),\n ],\n beforeChange: [\n getBeforeChangeHook({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n size,\n }),\n ...((typeof existingSizeURLField === 'object' &&\n 'hooks' in existingSizeURLField &&\n existingSizeURLField?.hooks?.beforeChange) ||\n []),\n ],\n },\n } as TextField)\n : ({\n ...(existingSizeURLField || {}),\n ...baseURLField,\n } as TextField)\n\n return {\n ...existingSizeField,\n name: size.name,\n type: 'group',\n fields: [\n ...(adapter?.fields || []).filter(\n (field) => !('name' in field && ['_objectKey', 'prefix'].includes(field.name)),\n ),\n sizeURLField,\n storedPrefixField,\n baseObjectKeyField,\n ],\n }\n }),\n }\n\n fields.push(sizesField)\n }\n\n // Always insert the prefix field so the schema stays consistent regardless of\n // whether the plugin is enabled or a prefix is configured.\n let existingPrefixFieldIndex = -1\n\n const existingPrefixField = fields.find((existingField, i) => {\n if ('name' in existingField && existingField.name === 'prefix') {\n existingPrefixFieldIndex = i\n return true\n }\n return false\n }) as TextField\n\n if (existingPrefixFieldIndex > -1) {\n fields.splice(existingPrefixFieldIndex, 1)\n }\n\n fields.push({\n ...basePrefixField,\n ...(existingPrefixField || {}),\n defaultValue:\n existingPrefixField?.defaultValue ??\n (useCompositePrefixes ? '' : prefix ? path.posix.join(prefix) : ''),\n hooks: {\n ...existingPrefixField?.hooks,\n beforeChange: [\n ...(existingPrefixField?.hooks?.beforeChange || []),\n getNormalizeUploadPrefixFieldHook({ collectionPrefix: prefix, useCompositePrefixes }),\n ],\n },\n } as TextField)\n\n const existingObjectKeyFieldIndex = fields.findIndex(\n (existingField) => 'name' in existingField && existingField.name === '_objectKey',\n )\n if (existingObjectKeyFieldIndex > -1) {\n fields.splice(existingObjectKeyFieldIndex, 1)\n }\n\n fields.push({ ...baseObjectKeyField })\n\n return fields\n}\n"],"names":["path","getAfterReadHook","getBeforeChangeHook","getNormalizeUploadPrefixFieldHook","getFields","adapter","collection","disablePayloadAccessControl","generateFileURL","prefix","useCompositePrefixes","baseURLField","name","type","admin","hidden","readOnly","label","basePrefixField","disabled","bulkEdit","column","filter","groupBy","baseObjectKeyField","storedPrefixField","fields","existingURLFieldIndex","existingURLField","find","existingField","i","splice","push","hooks","afterRead","beforeChange","originalField","field","originalURLFieldIndex","findIndex","undefined","originalURLField","isOriginal","variants","upload","existingSizesFieldIndex","existingSizesField","sizesField","map","size","existingSizeField","existingSizeURLField","sizeURLField","includes","existingPrefixFieldIndex","existingPrefixField","defaultValue","posix","join","collectionPrefix","existingObjectKeyFieldIndex"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"afterChange.d.ts","sourceRoot":"","sources":["../../src/hooks/afterChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAIhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAUnD,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAQD,eAAO,MAAM,kBAAkB,oHAQ1B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"afterChange.d.ts","sourceRoot":"","sources":["../../src/hooks/afterChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAIhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAUnD,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAQD,eAAO,MAAM,kBAAkB,oHAQ1B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,CAyQxD,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deepMergeWithSourceArrays } from 'payload';
|
|
1
|
+
import { deepMergeWithSourceArrays, MAIN_BRANCH, scheduleAfterTransactionCommit } from 'payload';
|
|
2
2
|
import { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js';
|
|
3
3
|
import { buildStoragePathData, buildUploadStoragePathData } from '../utilities/buildStoragePathData.js';
|
|
4
4
|
import { getIncomingFiles } from '../utilities/getIncomingFiles.js';
|
|
@@ -180,25 +180,63 @@ export const getAfterChangeHook = ({ adapter, collection, collectionPrefix, disa
|
|
|
180
180
|
data: newFileData,
|
|
181
181
|
filename
|
|
182
182
|
})));
|
|
183
|
-
const
|
|
183
|
+
const branchDocumentID = getBranchDocumentID(previousDoc);
|
|
184
|
+
if (branchDocumentID !== undefined) {
|
|
185
|
+
const retainedMainDocument = await req.payload.db.findOne({
|
|
186
|
+
branch: false,
|
|
187
|
+
collection: collection.slug,
|
|
188
|
+
req,
|
|
189
|
+
where: {
|
|
190
|
+
and: [
|
|
191
|
+
{
|
|
192
|
+
_branch: {
|
|
193
|
+
equals: MAIN_BRANCH
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: {
|
|
198
|
+
equals: branchDocumentID
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
if (retainedMainDocument) {
|
|
205
|
+
for (const filename of getDocumentFilenames(retainedMainDocument)){
|
|
206
|
+
newKeys.add(resolveKey({
|
|
207
|
+
data: retainedMainDocument,
|
|
208
|
+
filename
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const deletionTargets = filesToDelete.flatMap((filename)=>{
|
|
184
214
|
if (!filename) {
|
|
185
|
-
return;
|
|
215
|
+
return [];
|
|
186
216
|
}
|
|
187
217
|
const storageFilePath = resolveKey({
|
|
188
218
|
data: previousDoc,
|
|
189
219
|
filename
|
|
190
220
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
collection,
|
|
194
|
-
doc: previousDoc,
|
|
221
|
+
return newKeys.has(storageFilePath) ? [] : [
|
|
222
|
+
{
|
|
195
223
|
filename,
|
|
196
|
-
req,
|
|
197
224
|
storageFilePath
|
|
198
|
-
}
|
|
199
|
-
|
|
225
|
+
}
|
|
226
|
+
];
|
|
227
|
+
});
|
|
228
|
+
await scheduleAfterTransactionCommit({
|
|
229
|
+
callback: async ()=>{
|
|
230
|
+
await Promise.all(deletionTargets.map(async ({ filename, storageFilePath })=>adapter.handleDelete({
|
|
231
|
+
collection,
|
|
232
|
+
doc: previousDoc,
|
|
233
|
+
filename,
|
|
234
|
+
req,
|
|
235
|
+
storageFilePath
|
|
236
|
+
})));
|
|
237
|
+
},
|
|
238
|
+
req
|
|
200
239
|
});
|
|
201
|
-
await Promise.all(deletionPromises);
|
|
202
240
|
}
|
|
203
241
|
if (docWithMetadata !== doc) {
|
|
204
242
|
return docWithMetadata;
|
|
@@ -213,5 +251,30 @@ export const getAfterChangeHook = ({ adapter, collection, collectionPrefix, disa
|
|
|
213
251
|
}
|
|
214
252
|
return doc;
|
|
215
253
|
};
|
|
254
|
+
const getBranchDocumentID = (doc)=>{
|
|
255
|
+
if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
const branchDocument = doc;
|
|
259
|
+
if (branchDocument._branch === MAIN_BRANCH) {
|
|
260
|
+
return undefined;
|
|
261
|
+
}
|
|
262
|
+
const relation = branchDocument._branchDocID;
|
|
263
|
+
const value = relation && typeof relation === 'object' && !Array.isArray(relation) && 'value' in relation ? relation.value : relation;
|
|
264
|
+
return typeof value === 'number' || typeof value === 'string' ? value : undefined;
|
|
265
|
+
};
|
|
266
|
+
const getDocumentFilenames = (doc)=>{
|
|
267
|
+
const filenames = typeof doc.filename === 'string' ? [
|
|
268
|
+
doc.filename
|
|
269
|
+
] : [];
|
|
270
|
+
if (doc.variants && typeof doc.variants === 'object' && !Array.isArray(doc.variants)) {
|
|
271
|
+
for (const variant of Object.values(doc.variants)){
|
|
272
|
+
if (variant && typeof variant === 'object' && !Array.isArray(variant) && 'filename' in variant && typeof variant.filename === 'string') {
|
|
273
|
+
filenames.push(variant.filename);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return filenames;
|
|
278
|
+
};
|
|
216
279
|
|
|
217
280
|
//# sourceMappingURL=afterChange.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/afterChange.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport { deepMergeWithSourceArrays } from 'payload'\n\nimport type { GeneratedAdapter } from '../types.js'\n\nimport { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js'\nimport {\n buildStoragePathData,\n buildUploadStoragePathData,\n} from '../utilities/buildStoragePathData.js'\nimport { getIncomingFiles } from '../utilities/getIncomingFiles.js'\nimport { appendProxyPrefix } from './afterRead.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n collectionPrefix?: string\n disablePayloadAccessControl?: boolean\n hasCustomFileURL?: boolean\n useCompositePrefixes?: boolean\n}\n\n// The object's folder: semantic prefix + `_objectKey` segment.\nconst getObjectFolder = (data: unknown): string => {\n const record = (data ?? {}) as { _objectKey?: string; prefix?: string }\n return buildPrefixWithObjectKey({ objectKey: record._objectKey, prefix: record.prefix })\n}\n\nexport const getAfterChangeHook =\n ({\n adapter,\n collection,\n collectionPrefix,\n disablePayloadAccessControl,\n hasCustomFileURL,\n useCompositePrefixes,\n }: Args): CollectionAfterChangeHook<FileData & TypeWithID> =>\n async ({ data, doc, operation, previousDoc, req, select }) => {\n // Skip if this is an internal update to prevent infinite loop\n if (req.context?.skipCloudStorage) {\n return doc\n }\n\n // Restore upload metadata removed by select, including partially selected image sizes.\n const uploadData = select ? deepMergeWithSourceArrays<FileData & TypeWithID>(data, doc) : doc\n const withProxyPrefix = (upload: FileData & TypeWithID): FileData & TypeWithID => {\n const { prefix } = upload as { prefix?: string } & FileData & TypeWithID\n\n if (disablePayloadAccessControl || hasCustomFileURL || !useCompositePrefixes || !prefix) {\n return upload\n }\n\n return {\n ...upload,\n ...(upload.url && {\n url: appendProxyPrefix({ prefix, url: upload.url }),\n }),\n ...(upload.original?.url && {\n original: {\n ...upload.original,\n url: appendProxyPrefix({ prefix, url: upload.original.url }),\n },\n }),\n }\n }\n const isDraftSave = (uploadData as { _status?: string })._status === 'draft'\n const isDraftOverPublished =\n isDraftSave && (previousDoc as { _status?: string } | undefined)?._status === 'published'\n\n if (req.context?._payloadManagedCloudStorage) {\n const metadata = req.context._payloadManagedCloudMetadata as\n | Partial<FileData & TypeWithID>\n | undefined\n\n if (!metadata || Object.keys(metadata).length === 0) {\n return withProxyPrefix(doc)\n }\n\n req.context.skipCloudStorage = true\n req.file = undefined\n req.payloadUploadSizes = undefined\n const originalQuery = req.query\n req.query = { ...req.query }\n delete req.query.uploadEdits\n\n try {\n const updatedDoc = await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: metadata,\n depth: 0,\n draft: isDraftSave,\n overrideAccess: true,\n req,\n select,\n })\n\n return withProxyPrefix({ ...doc, ...updatedDoc })\n } finally {\n req.query = originalQuery\n delete req.context.skipCloudStorage\n }\n }\n\n try {\n const files = getIncomingFiles({ data: uploadData, req })\n\n if (files.length > 0) {\n // Fold `_objectKey` so generated sizes land in the same folder as the original.\n const dataForUpload = { ...uploadData, prefix: getObjectFolder(uploadData) }\n\n const uploadResults = await Promise.all(\n files\n .filter((file) => !file.uploadReference)\n .map((file) =>\n adapter.handleUpload({\n collection,\n data: dataForUpload,\n file,\n req,\n storageFilePath: buildUploadStoragePathData({\n collectionPrefix,\n docPrefix: dataForUpload.prefix,\n filename: file.filename,\n useCompositePrefixes,\n }).storageFilePath,\n }),\n ),\n )\n\n const uploadMetadata = uploadResults\n .filter(\n (result): result is Partial<FileData & TypeWithID> =>\n result != null && typeof result === 'object',\n )\n .reduce(\n (acc, metadata) => ({ ...acc, ...metadata }),\n {} as Partial<FileData & TypeWithID>,\n )\n\n // Adapters may echo `data` back as metadata; keep the document's own `prefix`/`_objectKey`.\n delete (uploadMetadata as Record<string, unknown>).prefix\n delete (uploadMetadata as Record<string, unknown>)._objectKey\n\n let docWithMetadata = doc\n\n if (Object.keys(uploadMetadata).length > 0) {\n if (!req.context) {\n req.context = {}\n }\n req.context.skipCloudStorage = true\n\n // Clear to prevent re-processing\n req.file = undefined\n req.payloadUploadSizes = undefined\n\n try {\n const updatedDoc = await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: uploadMetadata,\n depth: 0,\n draft: isDraftSave,\n overrideAccess: true,\n req,\n select,\n })\n\n // Persist all adapter metadata, but do not add unselected fields to the response.\n docWithMetadata = select ? { ...doc, ...updatedDoc } : { ...doc, ...uploadMetadata }\n } finally {\n delete req.context.skipCloudStorage\n }\n }\n\n // Delete previous files only after the new upload and metadata\n // persistence have succeeded. Deleting earlier would orphan the\n // record if a later step throws (e.g. a user-defined afterChange\n // hook on the same collection).\n if (\n previousDoc &&\n operation === 'update' &&\n !isDraftOverPublished &&\n !collection.versions &&\n !previousDoc.original\n ) {\n let filesToDelete: string[] = []\n\n if (typeof previousDoc?.filename === 'string') {\n filesToDelete.push(previousDoc.filename)\n }\n\n if (typeof previousDoc.variants === 'object') {\n filesToDelete = filesToDelete.concat(\n Object.values(previousDoc?.variants || []).map(\n (resizedFileData) => resizedFileData?.filename as string,\n ),\n )\n }\n\n // Compare full locations: a replacement can reuse a filename while moving\n // a legacy object beneath the collection prefix.\n const newFileData = { ...uploadData, ...uploadMetadata }\n const newFilenames = new Set<string>()\n if (typeof newFileData.filename === 'string') {\n newFilenames.add(newFileData.filename)\n }\n if (typeof newFileData.variants === 'object') {\n for (const size of Object.values(newFileData.variants || {})) {\n if (size?.filename && typeof size.filename === 'string') {\n newFilenames.add(size.filename)\n }\n }\n }\n\n const resolveKey = ({\n data,\n filename,\n }: {\n data: { _objectKey?: string; prefix?: string }\n filename: string\n }) =>\n buildStoragePathData({\n collectionPrefix,\n docPrefix: getObjectFolder(data),\n filename,\n useCompositePrefixes,\n }).storageFilePath\n const newKeys = new Set(\n [...newFilenames].map((filename) =>\n resolveKey({\n data: newFileData as { _objectKey?: string; prefix?: string },\n filename,\n }),\n ),\n )\n\n const deletionPromises = filesToDelete.map(async (filename) => {\n if (!filename) {\n return\n }\n const storageFilePath = resolveKey({\n data: previousDoc as { _objectKey?: string; prefix?: string },\n filename,\n })\n if (!newKeys.has(storageFilePath)) {\n await adapter.handleDelete({\n collection,\n doc: previousDoc,\n filename,\n req,\n storageFilePath,\n })\n }\n })\n\n await Promise.all(deletionPromises)\n }\n\n if (docWithMetadata !== doc) {\n return docWithMetadata\n }\n }\n } catch (err: unknown) {\n req.payload.logger.error(\n `There was an error while uploading files corresponding to the collection ${collection.slug} with filename ${doc.filename}:`,\n )\n req.payload.logger.error({ err })\n throw err\n }\n return doc\n }\n"],"names":["deepMergeWithSourceArrays","buildPrefixWithObjectKey","buildStoragePathData","buildUploadStoragePathData","getIncomingFiles","appendProxyPrefix","getObjectFolder","data","record","objectKey","_objectKey","prefix","getAfterChangeHook","adapter","collection","collectionPrefix","disablePayloadAccessControl","hasCustomFileURL","useCompositePrefixes","doc","operation","previousDoc","req","select","context","skipCloudStorage","uploadData","withProxyPrefix","upload","url","original","isDraftSave","_status","isDraftOverPublished","_payloadManagedCloudStorage","metadata","_payloadManagedCloudMetadata","Object","keys","length","file","undefined","payloadUploadSizes","originalQuery","query","uploadEdits","updatedDoc","payload","update","id","slug","depth","draft","overrideAccess","files","dataForUpload","uploadResults","Promise","all","filter","uploadReference","map","handleUpload","storageFilePath","docPrefix","filename","uploadMetadata","result","reduce","acc","docWithMetadata","versions","filesToDelete","push","variants","concat","values","resizedFileData","newFileData","newFilenames","Set","add","size","resolveKey","newKeys","deletionPromises","has","handleDelete","err","logger","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/afterChange.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport { deepMergeWithSourceArrays, MAIN_BRANCH, scheduleAfterTransactionCommit } from 'payload'\n\nimport type { GeneratedAdapter } from '../types.js'\n\nimport { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js'\nimport {\n buildStoragePathData,\n buildUploadStoragePathData,\n} from '../utilities/buildStoragePathData.js'\nimport { getIncomingFiles } from '../utilities/getIncomingFiles.js'\nimport { appendProxyPrefix } from './afterRead.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n collectionPrefix?: string\n disablePayloadAccessControl?: boolean\n hasCustomFileURL?: boolean\n useCompositePrefixes?: boolean\n}\n\n// The object's folder: semantic prefix + `_objectKey` segment.\nconst getObjectFolder = (data: unknown): string => {\n const record = (data ?? {}) as { _objectKey?: string; prefix?: string }\n return buildPrefixWithObjectKey({ objectKey: record._objectKey, prefix: record.prefix })\n}\n\nexport const getAfterChangeHook =\n ({\n adapter,\n collection,\n collectionPrefix,\n disablePayloadAccessControl,\n hasCustomFileURL,\n useCompositePrefixes,\n }: Args): CollectionAfterChangeHook<FileData & TypeWithID> =>\n async ({ data, doc, operation, previousDoc, req, select }) => {\n // Skip if this is an internal update to prevent infinite loop\n if (req.context?.skipCloudStorage) {\n return doc\n }\n\n // Restore upload metadata removed by select, including partially selected image sizes.\n const uploadData = select ? deepMergeWithSourceArrays<FileData & TypeWithID>(data, doc) : doc\n const withProxyPrefix = (upload: FileData & TypeWithID): FileData & TypeWithID => {\n const { prefix } = upload\n\n if (disablePayloadAccessControl || hasCustomFileURL || !useCompositePrefixes || !prefix) {\n return upload\n }\n\n return {\n ...upload,\n ...(upload.url && {\n url: appendProxyPrefix({ prefix, url: upload.url }),\n }),\n ...(upload.original?.url && {\n original: {\n ...upload.original,\n url: appendProxyPrefix({ prefix, url: upload.original.url }),\n },\n }),\n }\n }\n const isDraftSave = (uploadData as { _status?: string })._status === 'draft'\n const isDraftOverPublished =\n isDraftSave && (previousDoc as { _status?: string } | undefined)?._status === 'published'\n\n if (req.context?._payloadManagedCloudStorage) {\n const metadata = req.context._payloadManagedCloudMetadata as\n | Partial<FileData & TypeWithID>\n | undefined\n\n if (!metadata || Object.keys(metadata).length === 0) {\n return withProxyPrefix(doc)\n }\n\n req.context.skipCloudStorage = true\n req.file = undefined\n req.payloadUploadSizes = undefined\n const originalQuery = req.query\n req.query = { ...req.query }\n delete req.query.uploadEdits\n\n try {\n const updatedDoc = await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: metadata,\n depth: 0,\n draft: isDraftSave,\n overrideAccess: true,\n req,\n select,\n })\n\n return withProxyPrefix({ ...doc, ...updatedDoc })\n } finally {\n req.query = originalQuery\n delete req.context.skipCloudStorage\n }\n }\n\n try {\n const files = getIncomingFiles({ data: uploadData, req })\n\n if (files.length > 0) {\n // Fold `_objectKey` so generated sizes land in the same folder as the original.\n const dataForUpload = { ...uploadData, prefix: getObjectFolder(uploadData) }\n\n const uploadResults = await Promise.all(\n files\n .filter((file) => !file.uploadReference)\n .map((file) =>\n adapter.handleUpload({\n collection,\n data: dataForUpload,\n file,\n req,\n storageFilePath: buildUploadStoragePathData({\n collectionPrefix,\n docPrefix: dataForUpload.prefix,\n filename: file.filename,\n useCompositePrefixes,\n }).storageFilePath,\n }),\n ),\n )\n\n const uploadMetadata = uploadResults\n .filter(\n (result): result is Partial<FileData & TypeWithID> =>\n result != null && typeof result === 'object',\n )\n .reduce(\n (acc, metadata) => ({ ...acc, ...metadata }),\n {} as Partial<FileData & TypeWithID>,\n )\n\n // Adapters may echo `data` back as metadata; keep the document's own `prefix`/`_objectKey`.\n delete (uploadMetadata as Record<string, unknown>).prefix\n delete (uploadMetadata as Record<string, unknown>)._objectKey\n\n let docWithMetadata = doc\n\n if (Object.keys(uploadMetadata).length > 0) {\n if (!req.context) {\n req.context = {}\n }\n req.context.skipCloudStorage = true\n\n // Clear to prevent re-processing\n req.file = undefined\n req.payloadUploadSizes = undefined\n\n try {\n const updatedDoc = await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: uploadMetadata,\n depth: 0,\n draft: isDraftSave,\n overrideAccess: true,\n req,\n select,\n })\n\n // Persist all adapter metadata, but do not add unselected fields to the response.\n docWithMetadata = select ? { ...doc, ...updatedDoc } : { ...doc, ...uploadMetadata }\n } finally {\n delete req.context.skipCloudStorage\n }\n }\n\n // Delete previous files only after the new upload and metadata\n // persistence have succeeded. Deleting earlier would orphan the\n // record if a later step throws (e.g. a user-defined afterChange\n // hook on the same collection).\n if (\n previousDoc &&\n operation === 'update' &&\n !isDraftOverPublished &&\n !collection.versions &&\n !previousDoc.original\n ) {\n let filesToDelete: string[] = []\n\n if (typeof previousDoc?.filename === 'string') {\n filesToDelete.push(previousDoc.filename)\n }\n\n if (typeof previousDoc.variants === 'object') {\n filesToDelete = filesToDelete.concat(\n Object.values(previousDoc?.variants || []).map(\n (resizedFileData) => resizedFileData?.filename as string,\n ),\n )\n }\n\n // Compare full locations: a replacement can reuse a filename while moving\n // a legacy object beneath the collection prefix.\n const newFileData = { ...uploadData, ...uploadMetadata }\n const newFilenames = new Set<string>()\n if (typeof newFileData.filename === 'string') {\n newFilenames.add(newFileData.filename)\n }\n if (typeof newFileData.variants === 'object') {\n for (const size of Object.values(newFileData.variants || {})) {\n if (size?.filename && typeof size.filename === 'string') {\n newFilenames.add(size.filename)\n }\n }\n }\n\n const resolveKey = ({\n data,\n filename,\n }: {\n data: { _objectKey?: string; prefix?: string }\n filename: string\n }) =>\n buildStoragePathData({\n collectionPrefix,\n docPrefix: getObjectFolder(data),\n filename,\n useCompositePrefixes,\n }).storageFilePath\n const newKeys = new Set(\n [...newFilenames].map((filename) =>\n resolveKey({\n data: newFileData,\n filename,\n }),\n ),\n )\n const branchDocumentID = getBranchDocumentID(previousDoc)\n\n if (branchDocumentID !== undefined) {\n const retainedMainDocument = (await req.payload.db.findOne({\n branch: false,\n collection: collection.slug,\n req,\n where: {\n and: [{ _branch: { equals: MAIN_BRANCH } }, { id: { equals: branchDocumentID } }],\n },\n })) as null | Record<string, unknown>\n\n if (retainedMainDocument) {\n for (const filename of getDocumentFilenames(retainedMainDocument)) {\n newKeys.add(\n resolveKey({\n data: retainedMainDocument as { _objectKey?: string; prefix?: string },\n filename,\n }),\n )\n }\n }\n }\n\n const deletionTargets = filesToDelete.flatMap((filename) => {\n if (!filename) {\n return []\n }\n const storageFilePath = resolveKey({\n data: previousDoc,\n filename,\n })\n return newKeys.has(storageFilePath) ? [] : [{ filename, storageFilePath }]\n })\n\n await scheduleAfterTransactionCommit({\n callback: async () => {\n await Promise.all(\n deletionTargets.map(async ({ filename, storageFilePath }) =>\n adapter.handleDelete({\n collection,\n doc: previousDoc,\n filename,\n req,\n storageFilePath,\n }),\n ),\n )\n },\n req,\n })\n }\n\n if (docWithMetadata !== doc) {\n return docWithMetadata\n }\n }\n } catch (err: unknown) {\n req.payload.logger.error(\n `There was an error while uploading files corresponding to the collection ${collection.slug} with filename ${doc.filename}:`,\n )\n req.payload.logger.error({ err })\n throw err\n }\n return doc\n }\n\nconst getBranchDocumentID = (doc: unknown): number | string | undefined => {\n if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {\n return undefined\n }\n\n const branchDocument = doc as Record<string, unknown>\n\n if (branchDocument._branch === MAIN_BRANCH) {\n return undefined\n }\n\n const relation = branchDocument._branchDocID\n const value =\n relation && typeof relation === 'object' && !Array.isArray(relation) && 'value' in relation\n ? relation.value\n : relation\n\n return typeof value === 'number' || typeof value === 'string' ? value : undefined\n}\n\nconst getDocumentFilenames = (doc: Record<string, unknown>): string[] => {\n const filenames = typeof doc.filename === 'string' ? [doc.filename] : []\n\n if (doc.variants && typeof doc.variants === 'object' && !Array.isArray(doc.variants)) {\n for (const variant of Object.values(doc.variants)) {\n if (\n variant &&\n typeof variant === 'object' &&\n !Array.isArray(variant) &&\n 'filename' in variant &&\n typeof variant.filename === 'string'\n ) {\n filenames.push(variant.filename)\n }\n }\n }\n\n return filenames\n}\n"],"names":["deepMergeWithSourceArrays","MAIN_BRANCH","scheduleAfterTransactionCommit","buildPrefixWithObjectKey","buildStoragePathData","buildUploadStoragePathData","getIncomingFiles","appendProxyPrefix","getObjectFolder","data","record","objectKey","_objectKey","prefix","getAfterChangeHook","adapter","collection","collectionPrefix","disablePayloadAccessControl","hasCustomFileURL","useCompositePrefixes","doc","operation","previousDoc","req","select","context","skipCloudStorage","uploadData","withProxyPrefix","upload","url","original","isDraftSave","_status","isDraftOverPublished","_payloadManagedCloudStorage","metadata","_payloadManagedCloudMetadata","Object","keys","length","file","undefined","payloadUploadSizes","originalQuery","query","uploadEdits","updatedDoc","payload","update","id","slug","depth","draft","overrideAccess","files","dataForUpload","uploadResults","Promise","all","filter","uploadReference","map","handleUpload","storageFilePath","docPrefix","filename","uploadMetadata","result","reduce","acc","docWithMetadata","versions","filesToDelete","push","variants","concat","values","resizedFileData","newFileData","newFilenames","Set","add","size","resolveKey","newKeys","branchDocumentID","getBranchDocumentID","retainedMainDocument","db","findOne","branch","where","and","_branch","equals","getDocumentFilenames","deletionTargets","flatMap","has","callback","handleDelete","err","logger","error","Array","isArray","branchDocument","relation","_branchDocID","value","filenames","variant"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CollectionAfterDeleteHook, CollectionConfig, FileData, TypeWithID } from 'payload';
|
|
1
|
+
import type { CollectionAfterDeleteHook, CollectionConfig, FileData, PayloadRequest, TypeWithID } from 'payload';
|
|
2
2
|
import type { GeneratedAdapter, TypeWithPrefix } from '../types.js';
|
|
3
3
|
interface Args {
|
|
4
4
|
adapter: GeneratedAdapter;
|
|
@@ -7,5 +7,11 @@ interface Args {
|
|
|
7
7
|
useCompositePrefixes?: boolean;
|
|
8
8
|
}
|
|
9
9
|
export declare const getAfterDeleteHook: ({ adapter, collection, collectionPrefix, useCompositePrefixes, }: Args) => CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix>;
|
|
10
|
+
export declare const getDeleteFiles: ({ adapter, collection, collectionPrefix, useCompositePrefixes }: Args) => ({ onError, req, retainedDoc, sourceDoc, }: {
|
|
11
|
+
onError?: (error: unknown) => void;
|
|
12
|
+
req: PayloadRequest;
|
|
13
|
+
retainedDoc?: null | object;
|
|
14
|
+
sourceDoc: object;
|
|
15
|
+
}) => Promise<void>;
|
|
10
16
|
export {};
|
|
11
17
|
//# sourceMappingURL=afterDelete.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,UAAU,EACX,MAAM,SAAS,CAAA;AAShB,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAKnE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAID,eAAO,MAAM,kBAAkB,qEAK5B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,GAAG,cAAc,CAiDzE,CAAA;AAED,eAAO,MAAM,cAAc,oEACyC,IAAI,iDAMnE;IACD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAClC,GAAG,EAAE,cAAc,CAAA;IACnB,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;CAClB,kBAoEA,CAAA"}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
+
import { beginDeferredCleanupScopeIfNeeded, clearDeferredCleanupScope, flushDeferredCleanupScope, scheduleAfterTransactionCommit } from 'payload';
|
|
1
2
|
import { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js';
|
|
2
3
|
import { buildStoragePathData } from '../utilities/buildStoragePathData.js';
|
|
3
4
|
export const getAfterDeleteHook = ({ adapter, collection, collectionPrefix, useCompositePrefixes })=>{
|
|
5
|
+
const logDeleteError = ({ doc, err, req })=>{
|
|
6
|
+
req.payload.logger.error({
|
|
7
|
+
err,
|
|
8
|
+
msg: `There was an error while deleting files for collection ${collection.slug} document ${doc.id}.`
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const deleteFiles = getDeleteFiles({
|
|
12
|
+
adapter,
|
|
13
|
+
collection,
|
|
14
|
+
collectionPrefix,
|
|
15
|
+
useCompositePrefixes
|
|
16
|
+
});
|
|
4
17
|
return async ({ id, doc, req })=>{
|
|
5
18
|
// Managed objects are deleted after the operation commits and all references are checked.
|
|
6
19
|
const managedDeletedUploads = req.context?._payloadManagedDeletedUploads;
|
|
@@ -11,41 +24,101 @@ export const getAfterDeleteHook = ({ adapter, collection, collectionPrefix, useC
|
|
|
11
24
|
return doc;
|
|
12
25
|
}
|
|
13
26
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
prefix: doc.prefix
|
|
18
|
-
});
|
|
19
|
-
const filesToDelete = [
|
|
20
|
-
doc.filename,
|
|
21
|
-
...Object.values(doc?.variants || []).map((resizedFileData)=>resizedFileData?.filename)
|
|
22
|
-
];
|
|
23
|
-
const promises = filesToDelete.map(async (filename)=>{
|
|
24
|
-
if (filename) {
|
|
25
|
-
const { storageFilePath } = buildStoragePathData({
|
|
26
|
-
collectionPrefix,
|
|
27
|
-
docPrefix,
|
|
28
|
-
filename,
|
|
29
|
-
useCompositePrefixes
|
|
30
|
-
});
|
|
31
|
-
await adapter.handleDelete({
|
|
32
|
-
collection,
|
|
27
|
+
await deleteFiles({
|
|
28
|
+
onError: (err)=>{
|
|
29
|
+
logDeleteError({
|
|
33
30
|
doc,
|
|
34
|
-
|
|
35
|
-
req
|
|
36
|
-
storageFilePath
|
|
31
|
+
err,
|
|
32
|
+
req
|
|
37
33
|
});
|
|
38
|
-
}
|
|
34
|
+
},
|
|
35
|
+
req,
|
|
36
|
+
sourceDoc: doc
|
|
39
37
|
});
|
|
40
|
-
await Promise.all(promises);
|
|
41
38
|
} catch (err) {
|
|
42
|
-
|
|
39
|
+
logDeleteError({
|
|
40
|
+
doc,
|
|
43
41
|
err,
|
|
44
|
-
|
|
42
|
+
req
|
|
45
43
|
});
|
|
46
44
|
}
|
|
47
45
|
return doc;
|
|
48
46
|
};
|
|
49
47
|
};
|
|
48
|
+
export const getDeleteFiles = ({ adapter, collection, collectionPrefix, useCompositePrefixes })=>async ({ onError, req, retainedDoc, sourceDoc })=>{
|
|
49
|
+
const cleanupScope = await beginDeferredCleanupScopeIfNeeded({
|
|
50
|
+
req
|
|
51
|
+
});
|
|
52
|
+
const sourceUploadDocument = sourceDoc;
|
|
53
|
+
const retainedUploadDocument = retainedDoc;
|
|
54
|
+
const resolveKey = ({ doc, filename })=>{
|
|
55
|
+
const docPrefix = buildPrefixWithObjectKey({
|
|
56
|
+
objectKey: doc._objectKey,
|
|
57
|
+
prefix: doc.prefix
|
|
58
|
+
});
|
|
59
|
+
return buildStoragePathData({
|
|
60
|
+
collectionPrefix,
|
|
61
|
+
docPrefix,
|
|
62
|
+
filename,
|
|
63
|
+
useCompositePrefixes
|
|
64
|
+
}).storageFilePath;
|
|
65
|
+
};
|
|
66
|
+
const retainedStoragePaths = new Set(retainedUploadDocument ? getFilenames(retainedUploadDocument).map((filename)=>resolveKey({
|
|
67
|
+
doc: retainedUploadDocument,
|
|
68
|
+
filename
|
|
69
|
+
})) : []);
|
|
70
|
+
const filesToDelete = getFilenames(sourceUploadDocument).flatMap((filename)=>{
|
|
71
|
+
const storageFilePath = resolveKey({
|
|
72
|
+
doc: sourceUploadDocument,
|
|
73
|
+
filename
|
|
74
|
+
});
|
|
75
|
+
return retainedStoragePaths.has(storageFilePath) ? [] : [
|
|
76
|
+
{
|
|
77
|
+
filename,
|
|
78
|
+
storageFilePath
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
});
|
|
82
|
+
try {
|
|
83
|
+
await scheduleAfterTransactionCommit({
|
|
84
|
+
callback: async ()=>{
|
|
85
|
+
try {
|
|
86
|
+
await Promise.all(filesToDelete.map(async ({ filename, storageFilePath })=>adapter.handleDelete({
|
|
87
|
+
collection,
|
|
88
|
+
doc: sourceUploadDocument,
|
|
89
|
+
filename,
|
|
90
|
+
req,
|
|
91
|
+
storageFilePath
|
|
92
|
+
})));
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (onError) {
|
|
95
|
+
onError(error);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
req
|
|
102
|
+
});
|
|
103
|
+
if (cleanupScope) {
|
|
104
|
+
await flushDeferredCleanupScope({
|
|
105
|
+
req,
|
|
106
|
+
scope: cleanupScope
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (cleanupScope) {
|
|
111
|
+
clearDeferredCleanupScope({
|
|
112
|
+
req,
|
|
113
|
+
scope: cleanupScope
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const getFilenames = (doc)=>[
|
|
120
|
+
doc.filename,
|
|
121
|
+
...Object.values(doc.variants || {}).map((variantFileData)=>variantFileData?.filename)
|
|
122
|
+
].filter((filename)=>typeof filename === 'string' && filename.length > 0);
|
|
50
123
|
|
|
51
124
|
//# sourceMappingURL=afterDelete.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/afterDelete.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/afterDelete.ts"],"sourcesContent":["import type {\n CollectionAfterDeleteHook,\n CollectionConfig,\n FileData,\n PayloadRequest,\n TypeWithID,\n} from 'payload'\n\nimport {\n beginDeferredCleanupScopeIfNeeded,\n clearDeferredCleanupScope,\n flushDeferredCleanupScope,\n scheduleAfterTransactionCommit,\n} from 'payload'\n\nimport type { GeneratedAdapter, TypeWithPrefix } from '../types.js'\n\nimport { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js'\nimport { buildStoragePathData } from '../utilities/buildStoragePathData.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n collectionPrefix?: string\n useCompositePrefixes?: boolean\n}\n\ntype UploadDocument = { _objectKey?: string } & FileData & TypeWithID & TypeWithPrefix\n\nexport const getAfterDeleteHook = ({\n adapter,\n collection,\n collectionPrefix,\n useCompositePrefixes,\n}: Args): CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix> => {\n const logDeleteError = ({\n doc,\n err,\n req,\n }: {\n doc: TypeWithID\n err: unknown\n req: PayloadRequest\n }) => {\n req.payload.logger.error({\n err,\n msg: `There was an error while deleting files for collection ${collection.slug} document ${doc.id}.`,\n })\n }\n const deleteFiles = getDeleteFiles({\n adapter,\n collection,\n collectionPrefix,\n useCompositePrefixes,\n })\n\n return async ({ id, doc, req }) => {\n // Managed objects are deleted after the operation commits and all references are checked.\n const managedDeletedUploads = req.context?._payloadManagedDeletedUploads as\n | Set<string>\n | undefined\n if (\n collection.versions ||\n (Boolean(doc.original) && typeof doc.original?.filename === 'string') ||\n managedDeletedUploads?.has(JSON.stringify([collection.slug, String(id)]))\n ) {\n return doc\n }\n\n try {\n await deleteFiles({\n onError: (err) => {\n logDeleteError({ doc, err, req })\n },\n req,\n sourceDoc: doc,\n })\n } catch (err: unknown) {\n logDeleteError({ doc, err, req })\n }\n\n return doc\n }\n}\n\nexport const getDeleteFiles =\n ({ adapter, collection, collectionPrefix, useCompositePrefixes }: Args) =>\n async ({\n onError,\n req,\n retainedDoc,\n sourceDoc,\n }: {\n onError?: (error: unknown) => void\n req: PayloadRequest\n retainedDoc?: null | object\n sourceDoc: object\n }) => {\n const cleanupScope = await beginDeferredCleanupScopeIfNeeded({ req })\n const sourceUploadDocument = sourceDoc as UploadDocument\n const retainedUploadDocument = retainedDoc as null | undefined | UploadDocument\n const resolveKey = ({ doc, filename }: { doc: UploadDocument; filename: string }) => {\n const docPrefix = buildPrefixWithObjectKey({\n objectKey: doc._objectKey,\n prefix: doc.prefix,\n })\n\n return buildStoragePathData({\n collectionPrefix,\n docPrefix,\n filename,\n useCompositePrefixes,\n }).storageFilePath\n }\n const retainedStoragePaths = new Set(\n retainedUploadDocument\n ? getFilenames(retainedUploadDocument).map((filename) =>\n resolveKey({ doc: retainedUploadDocument, filename }),\n )\n : [],\n )\n\n const filesToDelete = getFilenames(sourceUploadDocument).flatMap((filename) => {\n const storageFilePath = resolveKey({ doc: sourceUploadDocument, filename })\n\n return retainedStoragePaths.has(storageFilePath) ? [] : [{ filename, storageFilePath }]\n })\n\n try {\n await scheduleAfterTransactionCommit({\n callback: async () => {\n try {\n await Promise.all(\n filesToDelete.map(async ({ filename, storageFilePath }) =>\n adapter.handleDelete({\n collection,\n doc: sourceUploadDocument,\n filename,\n req,\n storageFilePath,\n }),\n ),\n )\n } catch (error) {\n if (onError) {\n onError(error)\n return\n }\n\n throw error\n }\n },\n req,\n })\n\n if (cleanupScope) {\n await flushDeferredCleanupScope({ req, scope: cleanupScope })\n }\n } catch (error) {\n if (cleanupScope) {\n clearDeferredCleanupScope({ req, scope: cleanupScope })\n }\n\n throw error\n }\n }\n\nconst getFilenames = (doc: FileData): string[] =>\n [\n doc.filename,\n ...Object.values(doc.variants || {}).map((variantFileData) => variantFileData?.filename),\n ].filter((filename): filename is string => typeof filename === 'string' && filename.length > 0)\n"],"names":["beginDeferredCleanupScopeIfNeeded","clearDeferredCleanupScope","flushDeferredCleanupScope","scheduleAfterTransactionCommit","buildPrefixWithObjectKey","buildStoragePathData","getAfterDeleteHook","adapter","collection","collectionPrefix","useCompositePrefixes","logDeleteError","doc","err","req","payload","logger","error","msg","slug","id","deleteFiles","getDeleteFiles","managedDeletedUploads","context","_payloadManagedDeletedUploads","versions","Boolean","original","filename","has","JSON","stringify","String","onError","sourceDoc","retainedDoc","cleanupScope","sourceUploadDocument","retainedUploadDocument","resolveKey","docPrefix","objectKey","_objectKey","prefix","storageFilePath","retainedStoragePaths","Set","getFilenames","map","filesToDelete","flatMap","callback","Promise","all","handleDelete","scope","Object","values","variants","variantFileData","filter","length"],"mappings":"AAQA,SACEA,iCAAiC,EACjCC,yBAAyB,EACzBC,yBAAyB,EACzBC,8BAA8B,QACzB,UAAS;AAIhB,SAASC,wBAAwB,QAAQ,2CAA0C;AACnF,SAASC,oBAAoB,QAAQ,uCAAsC;AAW3E,OAAO,MAAMC,qBAAqB,CAAC,EACjCC,OAAO,EACPC,UAAU,EACVC,gBAAgB,EAChBC,oBAAoB,EACf;IACL,MAAMC,iBAAiB,CAAC,EACtBC,GAAG,EACHC,GAAG,EACHC,GAAG,EAKJ;QACCA,IAAIC,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;YACvBJ;YACAK,KAAK,CAAC,uDAAuD,EAAEV,WAAWW,IAAI,CAAC,UAAU,EAAEP,IAAIQ,EAAE,CAAC,CAAC,CAAC;QACtG;IACF;IACA,MAAMC,cAAcC,eAAe;QACjCf;QACAC;QACAC;QACAC;IACF;IAEA,OAAO,OAAO,EAAEU,EAAE,EAAER,GAAG,EAAEE,GAAG,EAAE;QAC5B,0FAA0F;QAC1F,MAAMS,wBAAwBT,IAAIU,OAAO,EAAEC;QAG3C,IACEjB,WAAWkB,QAAQ,IAClBC,QAAQf,IAAIgB,QAAQ,KAAK,OAAOhB,IAAIgB,QAAQ,EAAEC,aAAa,YAC5DN,uBAAuBO,IAAIC,KAAKC,SAAS,CAAC;YAACxB,WAAWW,IAAI;YAAEc,OAAOb;SAAI,IACvE;YACA,OAAOR;QACT;QAEA,IAAI;YACF,MAAMS,YAAY;gBAChBa,SAAS,CAACrB;oBACRF,eAAe;wBAAEC;wBAAKC;wBAAKC;oBAAI;gBACjC;gBACAA;gBACAqB,WAAWvB;YACb;QACF,EAAE,OAAOC,KAAc;YACrBF,eAAe;gBAAEC;gBAAKC;gBAAKC;YAAI;QACjC;QAEA,OAAOF;IACT;AACF,EAAC;AAED,OAAO,MAAMU,iBACX,CAAC,EAAEf,OAAO,EAAEC,UAAU,EAAEC,gBAAgB,EAAEC,oBAAoB,EAAQ,GACtE,OAAO,EACLwB,OAAO,EACPpB,GAAG,EACHsB,WAAW,EACXD,SAAS,EAMV;QACC,MAAME,eAAe,MAAMrC,kCAAkC;YAAEc;QAAI;QACnE,MAAMwB,uBAAuBH;QAC7B,MAAMI,yBAAyBH;QAC/B,MAAMI,aAAa,CAAC,EAAE5B,GAAG,EAAEiB,QAAQ,EAA6C;YAC9E,MAAMY,YAAYrC,yBAAyB;gBACzCsC,WAAW9B,IAAI+B,UAAU;gBACzBC,QAAQhC,IAAIgC,MAAM;YACpB;YAEA,OAAOvC,qBAAqB;gBAC1BI;gBACAgC;gBACAZ;gBACAnB;YACF,GAAGmC,eAAe;QACpB;QACA,MAAMC,uBAAuB,IAAIC,IAC/BR,yBACIS,aAAaT,wBAAwBU,GAAG,CAAC,CAACpB,WACxCW,WAAW;gBAAE5B,KAAK2B;gBAAwBV;YAAS,MAErD,EAAE;QAGR,MAAMqB,gBAAgBF,aAAaV,sBAAsBa,OAAO,CAAC,CAACtB;YAChE,MAAMgB,kBAAkBL,WAAW;gBAAE5B,KAAK0B;gBAAsBT;YAAS;YAEzE,OAAOiB,qBAAqBhB,GAAG,CAACe,mBAAmB,EAAE,GAAG;gBAAC;oBAAEhB;oBAAUgB;gBAAgB;aAAE;QACzF;QAEA,IAAI;YACF,MAAM1C,+BAA+B;gBACnCiD,UAAU;oBACR,IAAI;wBACF,MAAMC,QAAQC,GAAG,CACfJ,cAAcD,GAAG,CAAC,OAAO,EAAEpB,QAAQ,EAAEgB,eAAe,EAAE,GACpDtC,QAAQgD,YAAY,CAAC;gCACnB/C;gCACAI,KAAK0B;gCACLT;gCACAf;gCACA+B;4BACF;oBAGN,EAAE,OAAO5B,OAAO;wBACd,IAAIiB,SAAS;4BACXA,QAAQjB;4BACR;wBACF;wBAEA,MAAMA;oBACR;gBACF;gBACAH;YACF;YAEA,IAAIuB,cAAc;gBAChB,MAAMnC,0BAA0B;oBAAEY;oBAAK0C,OAAOnB;gBAAa;YAC7D;QACF,EAAE,OAAOpB,OAAO;YACd,IAAIoB,cAAc;gBAChBpC,0BAA0B;oBAAEa;oBAAK0C,OAAOnB;gBAAa;YACvD;YAEA,MAAMpB;QACR;IACF,EAAC;AAEH,MAAM+B,eAAe,CAACpC,MACpB;QACEA,IAAIiB,QAAQ;WACT4B,OAAOC,MAAM,CAAC9C,IAAI+C,QAAQ,IAAI,CAAC,GAAGV,GAAG,CAAC,CAACW,kBAAoBA,iBAAiB/B;KAChF,CAACgC,MAAM,CAAC,CAAChC,WAAiC,OAAOA,aAAa,YAAYA,SAASiC,MAAM,GAAG"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAA;AAoBnE,eAAO,MAAM,kBAAkB,kBACb,aAAa,sBACZ,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAA;AAoBnE,eAAO,MAAM,kBAAkB,kBACb,aAAa,sBACZ,MAAM,KAAG,MAqQzB,CAAA"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getFields } from './fields/getFields.js';
|
|
2
2
|
import { getAfterChangeHook } from './hooks/afterChange.js';
|
|
3
|
-
import { getAfterDeleteHook } from './hooks/afterDelete.js';
|
|
3
|
+
import { getAfterDeleteHook, getDeleteFiles } from './hooks/afterDelete.js';
|
|
4
4
|
import { getNormalizeUploadPrefixHook } from './hooks/normalizeUploadPrefix.js';
|
|
5
5
|
import { getPreserveFileDataHook } from './hooks/preserveFileData.js';
|
|
6
6
|
import { getPublicOriginalURLHook } from './hooks/publicOriginalURL.js';
|
|
@@ -200,6 +200,12 @@ export const cloudStoragePlugin = (pluginOptions)=>(incomingConfig)=>{
|
|
|
200
200
|
upload: {
|
|
201
201
|
...typeof existingCollection.upload === 'object' ? existingCollection.upload : {},
|
|
202
202
|
adapter: adapter.name,
|
|
203
|
+
deleteFiles: getDeleteFiles({
|
|
204
|
+
adapter,
|
|
205
|
+
collection: existingCollection,
|
|
206
|
+
collectionPrefix: options.prefix,
|
|
207
|
+
useCompositePrefixes
|
|
208
|
+
}),
|
|
203
209
|
fileOperations: createFileOperations({
|
|
204
210
|
adapter,
|
|
205
211
|
collection: existingCollection,
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport type { Adapter, AllowList, PluginOptions } from './types.js'\n\nimport { getFields } from './fields/getFields.js'\nimport { getAfterChangeHook } from './hooks/afterChange.js'\nimport { getAfterDeleteHook } from './hooks/afterDelete.js'\nimport { getNormalizeUploadPrefixHook } from './hooks/normalizeUploadPrefix.js'\nimport { getPreserveFileDataHook } from './hooks/preserveFileData.js'\nimport { getPublicOriginalURLHook } from './hooks/publicOriginalURL.js'\nimport { createFileOperations } from './utilities/createFileOperations.js'\nimport { getStorageLocationSelect } from './utilities/getStorageLocationSelect.js'\n\n// This plugin extends all targeted collections by offloading uploaded files\n// to cloud storage instead of solely storing files locally.\n\n// It is based on an adapter approach, where adapters can be written for any cloud provider.\n// Adapters are responsible for providing four actions that this plugin will use:\n// 1. handleUpload, 2. handleDelete, 3. generateURL, 4. staticHandler\n\n// Optionally, the adapter can specify any Webpack config overrides if they are necessary.\n\nexport const cloudStoragePlugin =\n (pluginOptions: PluginOptions) =>\n (incomingConfig: Config): Config => {\n const { collections: allCollectionOptions, enabled, useCompositePrefixes } = pluginOptions\n const config = { ...incomingConfig }\n\n // If disabled, only insert fields (e.g. prefix) without full plugin functionality,\n // so the collection schema stays consistent across environments.\n if (enabled === false) {\n return {\n ...config,\n collections: (config.collections || []).map((existingCollection) => {\n const options = allCollectionOptions[existingCollection.slug]\n\n if (options) {\n // If adapter is provided, use it to get fields\n const adapter = options.adapter\n ? options.adapter({\n collection: existingCollection,\n prefix: options.prefix,\n })\n : undefined\n\n const fields = getFields({\n adapter,\n collection: existingCollection,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n generateFileURL: options.generateFileURL,\n prefix: options.prefix,\n useCompositePrefixes,\n })\n\n return {\n ...existingCollection,\n fields,\n }\n }\n\n return existingCollection\n }),\n }\n }\n\n const initFunctions: Array<() => Promise<void> | void> = []\n const endpointPaths = new Map<Adapter, string>()\n\n const collections = (config.collections || []).map((existingCollection) => {\n const options = allCollectionOptions[existingCollection.slug]\n\n if (options?.adapter) {\n const adapter = options.adapter({\n collection: existingCollection,\n prefix: options.prefix,\n })\n\n if (adapter.onInit) {\n initFunctions.push(adapter.onInit)\n }\n\n let uploadInstructions\n\n if (adapter.uploadInstructions) {\n const { adminHandler, enabled, endpoint, ...instructions } = adapter.uploadInstructions\n let endpointPath = endpointPaths.get(options.adapter)\n\n if (enabled && endpoint && !endpointPath) {\n const endpointCount =\n config.endpoints?.filter(({ path }) => path?.startsWith(endpoint.path)).length || 0\n\n endpointPath = endpointCount ? `${endpoint.path}-${endpointCount}` : endpoint.path\n config.endpoints ??= []\n config.endpoints.push({\n handler: endpoint.handler,\n method: 'post',\n path: endpointPath,\n })\n endpointPaths.set(options.adapter, endpointPath)\n }\n\n if (enabled && adminHandler) {\n config.admin ??= {}\n config.admin.components ??= {}\n config.admin.components.providers ??= []\n config.admin.components.providers.push({\n clientProps: {\n collectionSlug: existingCollection.slug,\n endpointPath,\n prefix: options.prefix,\n props: adminHandler.props || {},\n },\n path: adminHandler.path,\n })\n }\n\n if (enabled) {\n uploadInstructions = instructions\n } else if (adminHandler) {\n /** Avoid importMap.js differences when client uploads vary between dev and production. */\n config.admin ??= {}\n config.admin.dependencies ??= {}\n config.admin.dependencies[adminHandler.path] = {\n type: 'component',\n path: adminHandler.path,\n }\n }\n }\n\n const fields = getFields({\n adapter,\n collection: existingCollection,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n generateFileURL: options.generateFileURL,\n prefix: options.prefix,\n useCompositePrefixes,\n })\n\n const handlers = [\n ...(typeof existingCollection.upload === 'object' &&\n Array.isArray(existingCollection.upload.handlers)\n ? existingCollection.upload.handlers\n : []),\n ]\n\n if (!options.disablePayloadAccessControl) {\n handlers.push(adapter.staticHandler)\n // Public files still need a server path when Payload reads them for a transform.\n } else {\n handlers.push((req, args) => {\n if ('uploadReference' in args.params || args.params.operation === 'transform') {\n return adapter.staticHandler(req, args)\n }\n })\n }\n\n const getSkipSafeFetchSetting = (): AllowList | boolean => {\n const isBooleanTrueSkipSafeFetch =\n typeof existingCollection.upload === 'object' &&\n existingCollection.upload.skipSafeFetch === true\n\n const isAllowListSkipSafeFetch =\n typeof existingCollection.upload === 'object' &&\n Array.isArray(existingCollection.upload.skipSafeFetch)\n\n if (isBooleanTrueSkipSafeFetch) {\n return true\n } else if (isAllowListSkipSafeFetch) {\n const existingSkipSafeFetch =\n typeof existingCollection.upload === 'object' &&\n Array.isArray(existingCollection.upload.skipSafeFetch)\n ? existingCollection.upload.skipSafeFetch\n : []\n\n const hasExactLocalhostMatch = existingSkipSafeFetch.some((entry) => {\n const entryKeys = Object.keys(entry)\n return entryKeys.length === 1 && entry.hostname === 'localhost'\n })\n\n const localhostEntry =\n process.env.NODE_ENV !== 'production' && !hasExactLocalhostMatch\n ? [{ hostname: 'localhost' }]\n : []\n\n return [...existingSkipSafeFetch, ...localhostEntry]\n }\n\n if (process.env.NODE_ENV !== 'production') {\n return [{ hostname: 'localhost' }]\n }\n\n return false\n }\n\n return {\n ...existingCollection,\n fields,\n hooks: {\n ...(existingCollection.hooks || {}),\n afterChange: [\n ...(existingCollection.hooks?.afterChange || []),\n getAfterChangeHook({\n adapter,\n collection: existingCollection,\n collectionPrefix: options.prefix,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n hasCustomFileURL: Boolean(options.generateFileURL),\n useCompositePrefixes,\n }),\n ],\n afterDelete: [\n ...(existingCollection.hooks?.afterDelete || []),\n getAfterDeleteHook({\n adapter,\n collection: existingCollection,\n collectionPrefix: options.prefix,\n useCompositePrefixes,\n }),\n ],\n afterRead: [\n ...(existingCollection.hooks?.afterRead || []),\n ...(options.disablePayloadAccessControl &&\n (options.generateFileURL || adapter.generateURL)\n ? [\n getPublicOriginalURLHook({\n adapter,\n collection: existingCollection,\n generateFileURL: options.generateFileURL,\n }),\n ]\n : []),\n ],\n beforeChange: [\n ...(existingCollection.hooks?.beforeChange || []),\n getNormalizeUploadPrefixHook({\n collectionPrefix: options.prefix,\n useCompositePrefixes,\n }),\n getPreserveFileDataHook(),\n ],\n },\n select: getStorageLocationSelect({ select: existingCollection.select }),\n upload: {\n ...(typeof existingCollection.upload === 'object' ? existingCollection.upload : {}),\n adapter: adapter.name,\n fileOperations: createFileOperations({\n adapter,\n collection: existingCollection,\n collectionPrefix: options.prefix,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n generateFileURL: options.generateFileURL,\n useCompositePrefixes,\n }),\n ...(uploadInstructions && {\n uploadInstructions,\n }),\n disableLocalStorage:\n typeof options.disableLocalStorage === 'boolean' ? options.disableLocalStorage : true,\n handlers,\n skipSafeFetch: getSkipSafeFetchSetting(),\n },\n }\n }\n\n return existingCollection\n })\n\n return {\n ...config,\n collections,\n onInit: async (payload) => {\n // Await each init so a provisioning failure fails Payload startup\n // instead of becoming an unhandled rejection.\n await Promise.all(initFunctions.map((fn) => fn()))\n if (config.onInit) {\n await config.onInit(payload)\n }\n },\n }\n }\n"],"names":["getFields","getAfterChangeHook","getAfterDeleteHook","getNormalizeUploadPrefixHook","getPreserveFileDataHook","getPublicOriginalURLHook","createFileOperations","getStorageLocationSelect","cloudStoragePlugin","pluginOptions","incomingConfig","collections","allCollectionOptions","enabled","useCompositePrefixes","config","map","existingCollection","options","slug","adapter","collection","prefix","undefined","fields","disablePayloadAccessControl","generateFileURL","initFunctions","endpointPaths","Map","onInit","push","uploadInstructions","adminHandler","endpoint","instructions","endpointPath","get","endpointCount","endpoints","filter","path","startsWith","length","handler","method","set","admin","components","providers","clientProps","collectionSlug","props","dependencies","type","handlers","upload","Array","isArray","staticHandler","req","args","params","operation","getSkipSafeFetchSetting","isBooleanTrueSkipSafeFetch","skipSafeFetch","isAllowListSkipSafeFetch","existingSkipSafeFetch","hasExactLocalhostMatch","some","entry","entryKeys","Object","keys","hostname","localhostEntry","process","env","NODE_ENV","hooks","afterChange","collectionPrefix","hasCustomFileURL","Boolean","afterDelete","afterRead","generateURL","beforeChange","select","name","fileOperations","disableLocalStorage","payload","Promise","all","fn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport type { Adapter, AllowList, PluginOptions } from './types.js'\n\nimport { getFields } from './fields/getFields.js'\nimport { getAfterChangeHook } from './hooks/afterChange.js'\nimport { getAfterDeleteHook, getDeleteFiles } from './hooks/afterDelete.js'\nimport { getNormalizeUploadPrefixHook } from './hooks/normalizeUploadPrefix.js'\nimport { getPreserveFileDataHook } from './hooks/preserveFileData.js'\nimport { getPublicOriginalURLHook } from './hooks/publicOriginalURL.js'\nimport { createFileOperations } from './utilities/createFileOperations.js'\nimport { getStorageLocationSelect } from './utilities/getStorageLocationSelect.js'\n\n// This plugin extends all targeted collections by offloading uploaded files\n// to cloud storage instead of solely storing files locally.\n\n// It is based on an adapter approach, where adapters can be written for any cloud provider.\n// Adapters are responsible for providing four actions that this plugin will use:\n// 1. handleUpload, 2. handleDelete, 3. generateURL, 4. staticHandler\n\n// Optionally, the adapter can specify any Webpack config overrides if they are necessary.\n\nexport const cloudStoragePlugin =\n (pluginOptions: PluginOptions) =>\n (incomingConfig: Config): Config => {\n const { collections: allCollectionOptions, enabled, useCompositePrefixes } = pluginOptions\n const config = { ...incomingConfig }\n\n // If disabled, only insert fields (e.g. prefix) without full plugin functionality,\n // so the collection schema stays consistent across environments.\n if (enabled === false) {\n return {\n ...config,\n collections: (config.collections || []).map((existingCollection) => {\n const options = allCollectionOptions[existingCollection.slug]\n\n if (options) {\n // If adapter is provided, use it to get fields\n const adapter = options.adapter\n ? options.adapter({\n collection: existingCollection,\n prefix: options.prefix,\n })\n : undefined\n\n const fields = getFields({\n adapter,\n collection: existingCollection,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n generateFileURL: options.generateFileURL,\n prefix: options.prefix,\n useCompositePrefixes,\n })\n\n return {\n ...existingCollection,\n fields,\n }\n }\n\n return existingCollection\n }),\n }\n }\n\n const initFunctions: Array<() => Promise<void> | void> = []\n const endpointPaths = new Map<Adapter, string>()\n\n const collections = (config.collections || []).map((existingCollection) => {\n const options = allCollectionOptions[existingCollection.slug]\n\n if (options?.adapter) {\n const adapter = options.adapter({\n collection: existingCollection,\n prefix: options.prefix,\n })\n\n if (adapter.onInit) {\n initFunctions.push(adapter.onInit)\n }\n\n let uploadInstructions\n\n if (adapter.uploadInstructions) {\n const { adminHandler, enabled, endpoint, ...instructions } = adapter.uploadInstructions\n let endpointPath = endpointPaths.get(options.adapter)\n\n if (enabled && endpoint && !endpointPath) {\n const endpointCount =\n config.endpoints?.filter(({ path }) => path?.startsWith(endpoint.path)).length || 0\n\n endpointPath = endpointCount ? `${endpoint.path}-${endpointCount}` : endpoint.path\n config.endpoints ??= []\n config.endpoints.push({\n handler: endpoint.handler,\n method: 'post',\n path: endpointPath,\n })\n endpointPaths.set(options.adapter, endpointPath)\n }\n\n if (enabled && adminHandler) {\n config.admin ??= {}\n config.admin.components ??= {}\n config.admin.components.providers ??= []\n config.admin.components.providers.push({\n clientProps: {\n collectionSlug: existingCollection.slug,\n endpointPath,\n prefix: options.prefix,\n props: adminHandler.props || {},\n },\n path: adminHandler.path,\n })\n }\n\n if (enabled) {\n uploadInstructions = instructions\n } else if (adminHandler) {\n /** Avoid importMap.js differences when client uploads vary between dev and production. */\n config.admin ??= {}\n config.admin.dependencies ??= {}\n config.admin.dependencies[adminHandler.path] = {\n type: 'component',\n path: adminHandler.path,\n }\n }\n }\n\n const fields = getFields({\n adapter,\n collection: existingCollection,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n generateFileURL: options.generateFileURL,\n prefix: options.prefix,\n useCompositePrefixes,\n })\n\n const handlers = [\n ...(typeof existingCollection.upload === 'object' &&\n Array.isArray(existingCollection.upload.handlers)\n ? existingCollection.upload.handlers\n : []),\n ]\n\n if (!options.disablePayloadAccessControl) {\n handlers.push(adapter.staticHandler)\n // Public files still need a server path when Payload reads them for a transform.\n } else {\n handlers.push((req, args) => {\n if ('uploadReference' in args.params || args.params.operation === 'transform') {\n return adapter.staticHandler(req, args)\n }\n })\n }\n\n const getSkipSafeFetchSetting = (): AllowList | boolean => {\n const isBooleanTrueSkipSafeFetch =\n typeof existingCollection.upload === 'object' &&\n existingCollection.upload.skipSafeFetch === true\n\n const isAllowListSkipSafeFetch =\n typeof existingCollection.upload === 'object' &&\n Array.isArray(existingCollection.upload.skipSafeFetch)\n\n if (isBooleanTrueSkipSafeFetch) {\n return true\n } else if (isAllowListSkipSafeFetch) {\n const existingSkipSafeFetch =\n typeof existingCollection.upload === 'object' &&\n Array.isArray(existingCollection.upload.skipSafeFetch)\n ? existingCollection.upload.skipSafeFetch\n : []\n\n const hasExactLocalhostMatch = existingSkipSafeFetch.some((entry) => {\n const entryKeys = Object.keys(entry)\n return entryKeys.length === 1 && entry.hostname === 'localhost'\n })\n\n const localhostEntry =\n process.env.NODE_ENV !== 'production' && !hasExactLocalhostMatch\n ? [{ hostname: 'localhost' }]\n : []\n\n return [...existingSkipSafeFetch, ...localhostEntry]\n }\n\n if (process.env.NODE_ENV !== 'production') {\n return [{ hostname: 'localhost' }]\n }\n\n return false\n }\n\n return {\n ...existingCollection,\n fields,\n hooks: {\n ...(existingCollection.hooks || {}),\n afterChange: [\n ...(existingCollection.hooks?.afterChange || []),\n getAfterChangeHook({\n adapter,\n collection: existingCollection,\n collectionPrefix: options.prefix,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n hasCustomFileURL: Boolean(options.generateFileURL),\n useCompositePrefixes,\n }),\n ],\n afterDelete: [\n ...(existingCollection.hooks?.afterDelete || []),\n getAfterDeleteHook({\n adapter,\n collection: existingCollection,\n collectionPrefix: options.prefix,\n useCompositePrefixes,\n }),\n ],\n afterRead: [\n ...(existingCollection.hooks?.afterRead || []),\n ...(options.disablePayloadAccessControl &&\n (options.generateFileURL || adapter.generateURL)\n ? [\n getPublicOriginalURLHook({\n adapter,\n collection: existingCollection,\n generateFileURL: options.generateFileURL,\n }),\n ]\n : []),\n ],\n beforeChange: [\n ...(existingCollection.hooks?.beforeChange || []),\n getNormalizeUploadPrefixHook({\n collectionPrefix: options.prefix,\n useCompositePrefixes,\n }),\n getPreserveFileDataHook(),\n ],\n },\n select: getStorageLocationSelect({ select: existingCollection.select }),\n upload: {\n ...(typeof existingCollection.upload === 'object' ? existingCollection.upload : {}),\n adapter: adapter.name,\n deleteFiles: getDeleteFiles({\n adapter,\n collection: existingCollection,\n collectionPrefix: options.prefix,\n useCompositePrefixes,\n }),\n fileOperations: createFileOperations({\n adapter,\n collection: existingCollection,\n collectionPrefix: options.prefix,\n disablePayloadAccessControl: options.disablePayloadAccessControl,\n generateFileURL: options.generateFileURL,\n useCompositePrefixes,\n }),\n ...(uploadInstructions && {\n uploadInstructions,\n }),\n disableLocalStorage:\n typeof options.disableLocalStorage === 'boolean' ? options.disableLocalStorage : true,\n handlers,\n skipSafeFetch: getSkipSafeFetchSetting(),\n },\n }\n }\n\n return existingCollection\n })\n\n return {\n ...config,\n collections,\n onInit: async (payload) => {\n // Await each init so a provisioning failure fails Payload startup\n // instead of becoming an unhandled rejection.\n await Promise.all(initFunctions.map((fn) => fn()))\n if (config.onInit) {\n await config.onInit(payload)\n }\n },\n }\n }\n"],"names":["getFields","getAfterChangeHook","getAfterDeleteHook","getDeleteFiles","getNormalizeUploadPrefixHook","getPreserveFileDataHook","getPublicOriginalURLHook","createFileOperations","getStorageLocationSelect","cloudStoragePlugin","pluginOptions","incomingConfig","collections","allCollectionOptions","enabled","useCompositePrefixes","config","map","existingCollection","options","slug","adapter","collection","prefix","undefined","fields","disablePayloadAccessControl","generateFileURL","initFunctions","endpointPaths","Map","onInit","push","uploadInstructions","adminHandler","endpoint","instructions","endpointPath","get","endpointCount","endpoints","filter","path","startsWith","length","handler","method","set","admin","components","providers","clientProps","collectionSlug","props","dependencies","type","handlers","upload","Array","isArray","staticHandler","req","args","params","operation","getSkipSafeFetchSetting","isBooleanTrueSkipSafeFetch","skipSafeFetch","isAllowListSkipSafeFetch","existingSkipSafeFetch","hasExactLocalhostMatch","some","entry","entryKeys","Object","keys","hostname","localhostEntry","process","env","NODE_ENV","hooks","afterChange","collectionPrefix","hasCustomFileURL","Boolean","afterDelete","afterRead","generateURL","beforeChange","select","name","deleteFiles","fileOperations","disableLocalStorage","payload","Promise","all","fn"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -18,6 +18,10 @@ export type ClientUploadsConfig = {
|
|
|
18
18
|
*/
|
|
19
19
|
export type UploadReference = {
|
|
20
20
|
_objectKey?: string;
|
|
21
|
+
/** Data the adapter signed into the receipt with `resolveSignedURLKey`. Not stored on the document. */
|
|
22
|
+
adapterData?: Record<string, unknown>;
|
|
23
|
+
/** Fields the client added to `uploadReference`. Not verified; check them before use. */
|
|
24
|
+
clientData?: Record<string, unknown>;
|
|
21
25
|
prefix: string;
|
|
22
26
|
signedReceipt: `${string}.${string}`;
|
|
23
27
|
};
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n CollectionConfig,\n Field,\n FileData,\n FileHandlerOperation,\n ImageSize,\n PayloadHandler,\n PayloadRequest,\n SanitizedCollectionConfig,\n TypeWithID,\n UploadCollectionSlug,\n UploadInstructionsAccess,\n UploadInstructionsCapability,\n} from 'payload'\n\nexport type { FileHandlerOperation } from 'payload'\n\nexport interface File {\n buffer: Buffer\n filename: string\n filesize: number\n mimeType: string\n tempFilePath?: string\n uploadReference?: unknown\n}\n\nexport type ClientUploadsConfig = { access?: UploadInstructionsAccess } | boolean\n\n/**\n * Reference to a client-uploaded object, returned by an upload handler and\n * submitted with the document. Always carries the signed receipt; `prefix`\n * locates the stored object.\n */\nexport type UploadReference = {\n _objectKey?: string\n prefix: string\n signedReceipt: `${string}.${string}`\n}\n\nexport type HandleUpload = (args: {\n collection: CollectionConfig\n data: any\n file: File\n req: PayloadRequest\n /**\n * Pre-resolved storage path (`_objectKey` folded in, contained beneath the collection prefix).\n */\n storageFilePath: string\n}) =>\n | Partial<FileData & TypeWithID>\n | Promise<Partial<FileData & TypeWithID>>\n | Promise<void>\n | void\n\nexport interface TypeWithPrefix {\n prefix?: string\n}\n\nexport type HandleDelete = (args: {\n collection: CollectionConfig\n doc: FileData & TypeWithID & TypeWithPrefix\n filename: string\n req: PayloadRequest\n /**\n * Pre-resolved storage path of the object to delete.\n */\n storageFilePath: string\n}) => Promise<void> | void\n\n/** Deletes a stored object without requiring a saved document. */\nexport type DeleteFile = (args: {\n collection: CollectionConfig\n req: PayloadRequest\n /** Complete storage path, with prefixes and `_objectKey` already resolved. */\n storageFilePath: string\n}) => Promise<void> | void\n\n/** Complete storage keys are resolved before invoking a provider operation. */\nexport type FileOperationArgs = {\n collection: SanitizedCollectionConfig\n from: string\n mimeType?: string\n req: PayloadRequest\n to: string\n}\n\nexport type CopyFile = (args: FileOperationArgs) => Promise<void>\nexport type MoveFile = (args: FileOperationArgs) => Promise<void>\n\nexport type GenerateURL = (args: {\n collection: CollectionConfig\n data: any\n filename: string\n prefix?: string\n}) => Promise<string> | string\n\nexport type StaticHandler = (\n req: PayloadRequest,\n args: {\n doc?: TypeWithID\n headers?: Headers\n params: {\n collection: string\n filename: string\n operation?: FileHandlerOperation\n prefix?: string\n uploadReference?: unknown\n }\n },\n) => Promise<Response> | Response\n\nexport interface GeneratedAdapter {\n /** Preserve object metadata and fail if `to` already exists. Rename retains `from` for history. */\n copyFile: CopyFile\n deleteFile: DeleteFile\n /**\n * Additional fields to be injected into the base collection and image sizes\n */\n fields?: Field[]\n /**\n * Generates the public URL for a file\n */\n generateURL?: GenerateURL\n handleDelete: HandleDelete\n handleUpload: HandleUpload\n moveFile?: MoveFile\n name: string\n onInit?: () => Promise<void> | void\n staticHandler: StaticHandler\n /** Reads source files by path when staging server-mediated uploads. */\n supportsTempFiles?: boolean\n /** Generates upload instructions when supported. */\n uploadInstructions?: {\n adminHandler?: {\n path: string\n props?: Record<string, unknown>\n }\n enabled: boolean\n endpoint?: {\n handler: PayloadHandler\n path: `/${string}`\n }\n } & UploadInstructionsCapability\n}\n\nexport type Adapter = (args: { collection: CollectionConfig; prefix?: string }) => GeneratedAdapter\n\nexport type AllowList = Array<{\n hostname: string\n pathname?: string\n port?: string\n protocol?: 'http' | 'https'\n search?: string\n}>\n\nexport type GenerateFileURL = (args: {\n collection: CollectionConfig\n filename: string\n prefix?: string\n size?: ImageSize\n}) => Promise<string> | string\n\nexport interface CollectionOptions {\n adapter: Adapter | null\n disableLocalStorage?: boolean\n disablePayloadAccessControl?: true\n generateFileURL?: GenerateFileURL\n prefix?: string\n}\n\nexport interface PluginOptions {\n collections: Partial<Record<UploadCollectionSlug, CollectionOptions>>\n /**\n * Whether or not to enable the plugin\n *\n * Default: true\n */\n enabled?: boolean\n /**\n * When true (compositional prefixes), the stored `prefix` field is only the\n * document-level segment; the collection prefix comes from plugin options and\n * must not be pre-filled as the field default.\n *\n * Set by storage adapters that support compositional prefixes (e.g. S3, Azure, R2, Vercel Blob, GCS).\n *\n * @default false\n */\n useCompositePrefixes?: boolean\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n CollectionConfig,\n Field,\n FileData,\n FileHandlerOperation,\n ImageSize,\n PayloadHandler,\n PayloadRequest,\n SanitizedCollectionConfig,\n TypeWithID,\n UploadCollectionSlug,\n UploadInstructionsAccess,\n UploadInstructionsCapability,\n} from 'payload'\n\nexport type { FileHandlerOperation } from 'payload'\n\nexport interface File {\n buffer: Buffer\n filename: string\n filesize: number\n mimeType: string\n tempFilePath?: string\n uploadReference?: unknown\n}\n\nexport type ClientUploadsConfig = { access?: UploadInstructionsAccess } | boolean\n\n/**\n * Reference to a client-uploaded object, returned by an upload handler and\n * submitted with the document. Always carries the signed receipt; `prefix`\n * locates the stored object.\n */\nexport type UploadReference = {\n _objectKey?: string\n /** Data the adapter signed into the receipt with `resolveSignedURLKey`. Not stored on the document. */\n adapterData?: Record<string, unknown>\n /** Fields the client added to `uploadReference`. Not verified; check them before use. */\n clientData?: Record<string, unknown>\n prefix: string\n signedReceipt: `${string}.${string}`\n}\n\nexport type HandleUpload = (args: {\n collection: CollectionConfig\n data: any\n file: File\n req: PayloadRequest\n /**\n * Pre-resolved storage path (`_objectKey` folded in, contained beneath the collection prefix).\n */\n storageFilePath: string\n}) =>\n | Partial<FileData & TypeWithID>\n | Promise<Partial<FileData & TypeWithID>>\n | Promise<void>\n | void\n\nexport interface TypeWithPrefix {\n prefix?: string\n}\n\nexport type HandleDelete = (args: {\n collection: CollectionConfig\n doc: FileData & TypeWithID & TypeWithPrefix\n filename: string\n req: PayloadRequest\n /**\n * Pre-resolved storage path of the object to delete.\n */\n storageFilePath: string\n}) => Promise<void> | void\n\n/** Deletes a stored object without requiring a saved document. */\nexport type DeleteFile = (args: {\n collection: CollectionConfig\n req: PayloadRequest\n /** Complete storage path, with prefixes and `_objectKey` already resolved. */\n storageFilePath: string\n}) => Promise<void> | void\n\n/** Complete storage keys are resolved before invoking a provider operation. */\nexport type FileOperationArgs = {\n collection: SanitizedCollectionConfig\n from: string\n mimeType?: string\n req: PayloadRequest\n to: string\n}\n\nexport type CopyFile = (args: FileOperationArgs) => Promise<void>\nexport type MoveFile = (args: FileOperationArgs) => Promise<void>\n\nexport type GenerateURL = (args: {\n collection: CollectionConfig\n data: any\n filename: string\n prefix?: string\n}) => Promise<string> | string\n\nexport type StaticHandler = (\n req: PayloadRequest,\n args: {\n doc?: TypeWithID\n headers?: Headers\n params: {\n collection: string\n filename: string\n operation?: FileHandlerOperation\n prefix?: string\n uploadReference?: unknown\n }\n },\n) => Promise<Response> | Response\n\nexport interface GeneratedAdapter {\n /** Preserve object metadata and fail if `to` already exists. Rename retains `from` for history. */\n copyFile: CopyFile\n deleteFile: DeleteFile\n /**\n * Additional fields to be injected into the base collection and image sizes\n */\n fields?: Field[]\n /**\n * Generates the public URL for a file\n */\n generateURL?: GenerateURL\n handleDelete: HandleDelete\n handleUpload: HandleUpload\n moveFile?: MoveFile\n name: string\n onInit?: () => Promise<void> | void\n staticHandler: StaticHandler\n /** Reads source files by path when staging server-mediated uploads. */\n supportsTempFiles?: boolean\n /** Generates upload instructions when supported. */\n uploadInstructions?: {\n adminHandler?: {\n path: string\n props?: Record<string, unknown>\n }\n enabled: boolean\n endpoint?: {\n handler: PayloadHandler\n path: `/${string}`\n }\n } & UploadInstructionsCapability\n}\n\nexport type Adapter = (args: { collection: CollectionConfig; prefix?: string }) => GeneratedAdapter\n\nexport type AllowList = Array<{\n hostname: string\n pathname?: string\n port?: string\n protocol?: 'http' | 'https'\n search?: string\n}>\n\nexport type GenerateFileURL = (args: {\n collection: CollectionConfig\n filename: string\n prefix?: string\n size?: ImageSize\n}) => Promise<string> | string\n\nexport interface CollectionOptions {\n adapter: Adapter | null\n disableLocalStorage?: boolean\n disablePayloadAccessControl?: true\n generateFileURL?: GenerateFileURL\n prefix?: string\n}\n\nexport interface PluginOptions {\n collections: Partial<Record<UploadCollectionSlug, CollectionOptions>>\n /**\n * Whether or not to enable the plugin\n *\n * Default: true\n */\n enabled?: boolean\n /**\n * When true (compositional prefixes), the stored `prefix` field is only the\n * document-level segment; the collection prefix comes from plugin options and\n * must not be pre-filled as the field default.\n *\n * Set by storage adapters that support compositional prefixes (e.g. S3, Azure, R2, Vercel Blob, GCS).\n *\n * @default false\n */\n useCompositePrefixes?: boolean\n}\n"],"names":[],"mappings":"AA8KA,WAkBC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { PayloadRequest } from 'payload';
|
|
2
2
|
import type { UploadReference } from '../types.js';
|
|
3
3
|
type Args = {
|
|
4
|
+
/** Signed into the receipt and returned to the upload handler as `uploadReference.adapterData`. */
|
|
5
|
+
adapterData?: Record<string, unknown>;
|
|
4
6
|
collectionPrefix?: string;
|
|
5
7
|
collectionSlug: string;
|
|
6
8
|
docPrefix?: string;
|
|
@@ -25,7 +27,7 @@ type Args = {
|
|
|
25
27
|
* key with {@link buildUploadStoragePathData}, so the receipt only ever signs a key
|
|
26
28
|
* beneath the configured collection prefix.
|
|
27
29
|
*/
|
|
28
|
-
export declare function resolveSignedURLKey({ collectionPrefix, collectionSlug, docPrefix, filename, req, useCompositePrefixes, }: Args): Promise<{
|
|
30
|
+
export declare function resolveSignedURLKey({ adapterData, collectionPrefix, collectionSlug, docPrefix, filename, req, useCompositePrefixes, }: Args): Promise<{
|
|
29
31
|
sanitizedDocPrefix: string;
|
|
30
32
|
sanitizedFilename: string;
|
|
31
33
|
storageFilePath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveSignedURLKey.d.ts","sourceRoot":"","sources":["../../src/utilities/resolveSignedURLKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"resolveSignedURLKey.d.ts","sourceRoot":"","sources":["../../src/utilities/resolveSignedURLKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAY7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIlD,KAAK,IAAI,GAAG;IACV,mGAAmG;IACnG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,cAAc,CAAA;IACnB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,WAAW,EACX,gBAAqB,EACrB,cAAc,EACd,SAAS,EACT,QAAQ,EACR,GAAG,EACH,oBAA4B,GAC7B,EAAE,IAAI,GAAG,OAAO,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,iBAAiB,EAAE,MAAM,CAAA;IACzB,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,eAAe,CAAA;CACjC,CAAC,CA2DD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { createClientUploadReceipt, getOriginalFilename, getSafeFileName, incrementName } from 'payload/internal';
|
|
2
|
+
import { createClientUploadReceipt, getOriginalFilename, getSafeFileName, incrementName, truncateFilename } from 'payload/internal';
|
|
3
3
|
import { getSanitizedUploadFilename } from 'payload/shared';
|
|
4
4
|
import { buildUploadPrefix, buildUploadStoragePathData } from './buildStoragePathData.js';
|
|
5
5
|
/**
|
|
@@ -18,9 +18,13 @@ import { buildUploadPrefix, buildUploadStoragePathData } from './buildStoragePat
|
|
|
18
18
|
* The semantic prefix is resolved with {@link buildUploadPrefix} and the final
|
|
19
19
|
* key with {@link buildUploadStoragePathData}, so the receipt only ever signs a key
|
|
20
20
|
* beneath the configured collection prefix.
|
|
21
|
-
*/ export async function resolveSignedURLKey({ collectionPrefix = '', collectionSlug, docPrefix, filename, req, useCompositePrefixes = false }) {
|
|
21
|
+
*/ export async function resolveSignedURLKey({ adapterData, collectionPrefix = '', collectionSlug, docPrefix, filename, req, useCompositePrefixes = false }) {
|
|
22
22
|
// The document stores the -original name, so check collisions against that name.
|
|
23
|
-
let sanitizedFilename =
|
|
23
|
+
let sanitizedFilename = truncateFilename({
|
|
24
|
+
filename: getSanitizedUploadFilename(filename),
|
|
25
|
+
maxBytes: 255 - Buffer.byteLength('-original')
|
|
26
|
+
});
|
|
27
|
+
let attempts = 0;
|
|
24
28
|
let originalFilename = getOriginalFilename({
|
|
25
29
|
filename: sanitizedFilename
|
|
26
30
|
});
|
|
@@ -29,7 +33,14 @@ import { buildUploadPrefix, buildUploadStoragePathData } from './buildStoragePat
|
|
|
29
33
|
desiredFilename: originalFilename,
|
|
30
34
|
req
|
|
31
35
|
}) !== originalFilename){
|
|
32
|
-
|
|
36
|
+
const nextFilename = truncateFilename({
|
|
37
|
+
filename: incrementName(sanitizedFilename),
|
|
38
|
+
maxBytes: 255 - Buffer.byteLength('-original')
|
|
39
|
+
});
|
|
40
|
+
if (++attempts >= 1000 || nextFilename === sanitizedFilename) {
|
|
41
|
+
throw new Error('Unable to find an available upload filename');
|
|
42
|
+
}
|
|
43
|
+
sanitizedFilename = nextFilename;
|
|
33
44
|
originalFilename = getOriginalFilename({
|
|
34
45
|
filename: sanitizedFilename
|
|
35
46
|
});
|
|
@@ -54,6 +65,9 @@ import { buildUploadPrefix, buildUploadStoragePathData } from './buildStoragePat
|
|
|
54
65
|
prefix: sanitizedDocPrefix,
|
|
55
66
|
signedReceipt: createClientUploadReceipt({
|
|
56
67
|
_objectKey,
|
|
68
|
+
...adapterData !== undefined && {
|
|
69
|
+
adapterData
|
|
70
|
+
},
|
|
57
71
|
collectionSlug,
|
|
58
72
|
filename: sanitizedFilename,
|
|
59
73
|
filePrefix: sanitizedDocPrefix,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/resolveSignedURLKey.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { randomUUID } from 'node:crypto'\nimport {\n createClientUploadReceipt,\n getOriginalFilename,\n getSafeFileName,\n incrementName,\n} from 'payload/internal'\nimport { getSanitizedUploadFilename } from 'payload/shared'\n\nimport type { UploadReference } from '../types.js'\n\nimport { buildUploadPrefix, buildUploadStoragePathData } from './buildStoragePathData.js'\n\ntype Args = {\n collectionPrefix?: string\n collectionSlug: string\n docPrefix?: string\n filename: string\n req: PayloadRequest\n useCompositePrefixes?: boolean\n}\n\n/**\n * Resolves the storage key for an upload-instructions request, deduping\n * the filename via {@link getSafeFileName} so a duplicate upload does not\n * overwrite an existing blob.\n *\n * A unique per-upload segment is included in the storage key so each issued\n * key is distinct. The stored `filename` stays clean and the semantic `prefix`\n * stays exactly what the collection configured — the per-upload entropy is\n * persisted separately in `_objectKey`.\n *\n * The resolved `sanitizedFilename` is returned so the browser-side handler\n * can update the form via `updateFilename`.\n *\n * The semantic prefix is resolved with {@link buildUploadPrefix} and the final\n * key with {@link buildUploadStoragePathData}, so the receipt only ever signs a key\n * beneath the configured collection prefix.\n */\nexport async function resolveSignedURLKey({\n collectionPrefix = '',\n collectionSlug,\n docPrefix,\n filename,\n req,\n useCompositePrefixes = false,\n}: Args): Promise<{\n sanitizedDocPrefix: string\n sanitizedFilename: string\n storageFilePath: string\n uploadReference: UploadReference\n}> {\n // The document stores the -original name, so check collisions against that name.\n let sanitizedFilename = getSanitizedUploadFilename(filename)\n let originalFilename = getOriginalFilename({ filename: sanitizedFilename })\n\n while (\n (await getSafeFileName({ collectionSlug, desiredFilename: originalFilename, req })) !==\n originalFilename\n ) {\n
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/resolveSignedURLKey.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { randomUUID } from 'node:crypto'\nimport {\n createClientUploadReceipt,\n getOriginalFilename,\n getSafeFileName,\n incrementName,\n truncateFilename,\n} from 'payload/internal'\nimport { getSanitizedUploadFilename } from 'payload/shared'\n\nimport type { UploadReference } from '../types.js'\n\nimport { buildUploadPrefix, buildUploadStoragePathData } from './buildStoragePathData.js'\n\ntype Args = {\n /** Signed into the receipt and returned to the upload handler as `uploadReference.adapterData`. */\n adapterData?: Record<string, unknown>\n collectionPrefix?: string\n collectionSlug: string\n docPrefix?: string\n filename: string\n req: PayloadRequest\n useCompositePrefixes?: boolean\n}\n\n/**\n * Resolves the storage key for an upload-instructions request, deduping\n * the filename via {@link getSafeFileName} so a duplicate upload does not\n * overwrite an existing blob.\n *\n * A unique per-upload segment is included in the storage key so each issued\n * key is distinct. The stored `filename` stays clean and the semantic `prefix`\n * stays exactly what the collection configured — the per-upload entropy is\n * persisted separately in `_objectKey`.\n *\n * The resolved `sanitizedFilename` is returned so the browser-side handler\n * can update the form via `updateFilename`.\n *\n * The semantic prefix is resolved with {@link buildUploadPrefix} and the final\n * key with {@link buildUploadStoragePathData}, so the receipt only ever signs a key\n * beneath the configured collection prefix.\n */\nexport async function resolveSignedURLKey({\n adapterData,\n collectionPrefix = '',\n collectionSlug,\n docPrefix,\n filename,\n req,\n useCompositePrefixes = false,\n}: Args): Promise<{\n sanitizedDocPrefix: string\n sanitizedFilename: string\n storageFilePath: string\n uploadReference: UploadReference\n}> {\n // The document stores the -original name, so check collisions against that name.\n let sanitizedFilename = truncateFilename({\n filename: getSanitizedUploadFilename(filename),\n maxBytes: 255 - Buffer.byteLength('-original'),\n })\n let attempts = 0\n let originalFilename = getOriginalFilename({ filename: sanitizedFilename })\n\n while (\n (await getSafeFileName({ collectionSlug, desiredFilename: originalFilename, req })) !==\n originalFilename\n ) {\n const nextFilename = truncateFilename({\n filename: incrementName(sanitizedFilename),\n maxBytes: 255 - Buffer.byteLength('-original'),\n })\n\n if (++attempts >= 1000 || nextFilename === sanitizedFilename) {\n throw new Error('Unable to find an available upload filename')\n }\n\n sanitizedFilename = nextFilename\n originalFilename = getOriginalFilename({ filename: sanitizedFilename })\n }\n\n const rawBaseDocPrefix = useCompositePrefixes ? docPrefix : docPrefix || collectionPrefix\n const { sanitizedDocPrefix } = buildUploadPrefix({\n collectionPrefix,\n docPrefix: rawBaseDocPrefix,\n useCompositePrefixes,\n })\n\n const _objectKey = randomUUID()\n // Per-upload segment lives in the key; it is persisted in `_objectKey`, keeping `prefix` semantic.\n const keyedDocPrefix = sanitizedDocPrefix ? `${sanitizedDocPrefix}/${_objectKey}` : _objectKey\n\n const { storageFilePath } = buildUploadStoragePathData({\n collectionPrefix,\n docPrefix: keyedDocPrefix,\n filename: originalFilename,\n useCompositePrefixes,\n })\n\n const uploadReference = {\n _objectKey,\n prefix: sanitizedDocPrefix,\n signedReceipt: createClientUploadReceipt({\n _objectKey,\n ...(adapterData !== undefined && { adapterData }),\n collectionSlug,\n filename: sanitizedFilename,\n filePrefix: sanitizedDocPrefix,\n req,\n storageFilePath,\n }),\n }\n\n return { sanitizedDocPrefix, sanitizedFilename, storageFilePath, uploadReference }\n}\n"],"names":["randomUUID","createClientUploadReceipt","getOriginalFilename","getSafeFileName","incrementName","truncateFilename","getSanitizedUploadFilename","buildUploadPrefix","buildUploadStoragePathData","resolveSignedURLKey","adapterData","collectionPrefix","collectionSlug","docPrefix","filename","req","useCompositePrefixes","sanitizedFilename","maxBytes","Buffer","byteLength","attempts","originalFilename","desiredFilename","nextFilename","Error","rawBaseDocPrefix","sanitizedDocPrefix","_objectKey","keyedDocPrefix","storageFilePath","uploadReference","prefix","signedReceipt","undefined","filePrefix"],"mappings":"AAEA,SAASA,UAAU,QAAQ,cAAa;AACxC,SACEC,yBAAyB,EACzBC,mBAAmB,EACnBC,eAAe,EACfC,aAAa,EACbC,gBAAgB,QACX,mBAAkB;AACzB,SAASC,0BAA0B,QAAQ,iBAAgB;AAI3D,SAASC,iBAAiB,EAAEC,0BAA0B,QAAQ,4BAA2B;AAazF;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,eAAeC,oBAAoB,EACxCC,WAAW,EACXC,mBAAmB,EAAE,EACrBC,cAAc,EACdC,SAAS,EACTC,QAAQ,EACRC,GAAG,EACHC,uBAAuB,KAAK,EACvB;IAML,iFAAiF;IACjF,IAAIC,oBAAoBZ,iBAAiB;QACvCS,UAAUR,2BAA2BQ;QACrCI,UAAU,MAAMC,OAAOC,UAAU,CAAC;IACpC;IACA,IAAIC,WAAW;IACf,IAAIC,mBAAmBpB,oBAAoB;QAAEY,UAAUG;IAAkB;IAEzE,MACE,AAAC,MAAMd,gBAAgB;QAAES;QAAgBW,iBAAiBD;QAAkBP;IAAI,OAChFO,iBACA;QACA,MAAME,eAAenB,iBAAiB;YACpCS,UAAUV,cAAca;YACxBC,UAAU,MAAMC,OAAOC,UAAU,CAAC;QACpC;QAEA,IAAI,EAAEC,YAAY,QAAQG,iBAAiBP,mBAAmB;YAC5D,MAAM,IAAIQ,MAAM;QAClB;QAEAR,oBAAoBO;QACpBF,mBAAmBpB,oBAAoB;YAAEY,UAAUG;QAAkB;IACvE;IAEA,MAAMS,mBAAmBV,uBAAuBH,YAAYA,aAAaF;IACzE,MAAM,EAAEgB,kBAAkB,EAAE,GAAGpB,kBAAkB;QAC/CI;QACAE,WAAWa;QACXV;IACF;IAEA,MAAMY,aAAa5B;IACnB,mGAAmG;IACnG,MAAM6B,iBAAiBF,qBAAqB,GAAGA,mBAAmB,CAAC,EAAEC,YAAY,GAAGA;IAEpF,MAAM,EAAEE,eAAe,EAAE,GAAGtB,2BAA2B;QACrDG;QACAE,WAAWgB;QACXf,UAAUQ;QACVN;IACF;IAEA,MAAMe,kBAAkB;QACtBH;QACAI,QAAQL;QACRM,eAAehC,0BAA0B;YACvC2B;YACA,GAAIlB,gBAAgBwB,aAAa;gBAAExB;YAAY,CAAC;YAChDE;YACAE,UAAUG;YACVkB,YAAYR;YACZZ;YACAe;QACF;IACF;IAEA,OAAO;QAAEH;QAAoBV;QAAmBa;QAAiBC;IAAgB;AACnF"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-cloud-storage",
|
|
3
|
-
"version": "4.0.0-internal.
|
|
3
|
+
"version": "4.0.0-internal.952ed66",
|
|
4
4
|
"description": "The official cloud storage plugin for Payload CMS",
|
|
5
5
|
"homepage": "https://payloadcms.com",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "https://github.com/payloadcms/payload.git",
|
|
9
|
-
"directory": "packages/plugin-cloud-storage"
|
|
10
|
-
},
|
|
11
6
|
"license": "MIT",
|
|
12
7
|
"author": "Payload <dev@payloadcms.com> (https://payloadcms.com)",
|
|
13
8
|
"maintainers": [
|
|
@@ -17,8 +12,20 @@
|
|
|
17
12
|
"url": "https://payloadcms.com"
|
|
18
13
|
}
|
|
19
14
|
],
|
|
20
|
-
"
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/payloadcms/payload.git",
|
|
18
|
+
"directory": "packages/plugin-cloud-storage"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"*.js",
|
|
23
|
+
"*.d.ts"
|
|
24
|
+
],
|
|
21
25
|
"type": "module",
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
22
29
|
"exports": {
|
|
23
30
|
".": {
|
|
24
31
|
"import": "./dist/index.js",
|
|
@@ -41,31 +48,24 @@
|
|
|
41
48
|
"default": "./dist/exports/client.js"
|
|
42
49
|
}
|
|
43
50
|
},
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"dist",
|
|
48
|
-
"*.js",
|
|
49
|
-
"*.d.ts"
|
|
50
|
-
],
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"registry": "https://registry.npmjs.org/"
|
|
53
|
+
},
|
|
51
54
|
"dependencies": {
|
|
55
|
+
"@payloadcms/ui": "4.0.0-internal.952ed66",
|
|
52
56
|
"find-node-modules": "^2.1.3",
|
|
53
|
-
"range-parser": "^1.2.1"
|
|
54
|
-
"@payloadcms/ui": "4.0.0-internal.934870d"
|
|
57
|
+
"range-parser": "^1.2.1"
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@types/find-node-modules": "^2.1.2",
|
|
58
61
|
"@types/react": "19.3.0",
|
|
59
62
|
"@types/react-dom": "19.3.0",
|
|
60
|
-
"payload": "4.0.0-internal.
|
|
63
|
+
"payload": "4.0.0-internal.952ed66"
|
|
61
64
|
},
|
|
62
65
|
"peerDependencies": {
|
|
66
|
+
"payload": "4.0.0-internal.952ed66",
|
|
63
67
|
"react": "^19.0.1 || ^19.1.2 || ^19.2.1",
|
|
64
|
-
"react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1"
|
|
65
|
-
"payload": "4.0.0-internal.934870d"
|
|
66
|
-
},
|
|
67
|
-
"publishConfig": {
|
|
68
|
-
"registry": "https://registry.npmjs.org/"
|
|
68
|
+
"react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "pnpm build:types && pnpm build:swc ",
|
|
@@ -73,8 +73,6 @@
|
|
|
73
73
|
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
74
74
|
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
75
75
|
"clean": "rimraf -g {dist,*.tsbuildinfo}",
|
|
76
|
-
"lint": "eslint .",
|
|
77
|
-
"lint:fix": "eslint . --fix",
|
|
78
76
|
"test": "echo \"No tests available.\""
|
|
79
77
|
}
|
|
80
78
|
}
|