@payloadcms/plugin-cloud-storage 4.0.0-internal.5b1e7cd → 4.0.0-internal.5e065b3
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/LICENSE.md +1 -1
- package/README.md +2 -0
- package/dist/client/createClientUploadHandler.d.ts +8 -7
- package/dist/client/createClientUploadHandler.d.ts.map +1 -1
- package/dist/client/createClientUploadHandler.js +26 -22
- package/dist/client/createClientUploadHandler.js.map +1 -1
- package/dist/exports/client.d.ts +2 -0
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +2 -0
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/utilities.d.ts +2 -2
- package/dist/exports/utilities.d.ts.map +1 -1
- package/dist/exports/utilities.js +2 -2
- package/dist/exports/utilities.js.map +1 -1
- package/dist/fields/getFields.d.ts +1 -5
- package/dist/fields/getFields.d.ts.map +1 -1
- package/dist/fields/getFields.js +54 -22
- package/dist/fields/getFields.js.map +1 -1
- package/dist/hooks/afterChange.d.ts +3 -1
- package/dist/hooks/afterChange.d.ts.map +1 -1
- package/dist/hooks/afterChange.js +118 -41
- package/dist/hooks/afterChange.js.map +1 -1
- package/dist/hooks/afterDelete.d.ts +3 -1
- package/dist/hooks/afterDelete.d.ts.map +1 -1
- package/dist/hooks/afterDelete.js +17 -3
- package/dist/hooks/afterDelete.js.map +1 -1
- package/dist/hooks/afterRead.d.ts.map +1 -1
- package/dist/hooks/afterRead.js +16 -3
- package/dist/hooks/afterRead.js.map +1 -1
- package/dist/hooks/beforeChange.d.ts.map +1 -1
- package/dist/hooks/beforeChange.js +14 -3
- package/dist/hooks/beforeChange.js.map +1 -1
- package/dist/hooks/normalizeUploadPrefix.d.ts +11 -0
- package/dist/hooks/normalizeUploadPrefix.d.ts.map +1 -0
- package/dist/hooks/normalizeUploadPrefix.js +42 -0
- package/dist/hooks/normalizeUploadPrefix.js.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +178 -128
- package/dist/plugin.js.map +1 -1
- package/dist/types.d.ts +37 -21
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/buildPrefixWithObjectKey.d.ts +8 -0
- package/dist/utilities/buildPrefixWithObjectKey.d.ts.map +1 -0
- package/dist/utilities/buildPrefixWithObjectKey.js +13 -0
- package/dist/utilities/buildPrefixWithObjectKey.js.map +1 -0
- package/dist/utilities/buildStoragePathData.d.ts +49 -0
- package/dist/utilities/buildStoragePathData.d.ts.map +1 -0
- package/dist/utilities/buildStoragePathData.js +67 -0
- package/dist/utilities/buildStoragePathData.js.map +1 -0
- package/dist/utilities/getFilePrefix.d.ts +19 -11
- package/dist/utilities/getFilePrefix.d.ts.map +1 -1
- package/dist/utilities/getFilePrefix.js +71 -31
- package/dist/utilities/getFilePrefix.js.map +1 -1
- package/dist/utilities/getIncomingFiles.js +4 -4
- package/dist/utilities/getIncomingFiles.js.map +1 -1
- package/dist/utilities/resolveSignedURLKey.d.ts +35 -0
- package/dist/utilities/resolveSignedURLKey.d.ts.map +1 -0
- package/dist/utilities/resolveSignedURLKey.js +64 -0
- package/dist/utilities/resolveSignedURLKey.js.map +1 -0
- package/dist/utilities/sanitizePrefix.d.ts +1 -9
- package/dist/utilities/sanitizePrefix.d.ts.map +1 -1
- package/dist/utilities/sanitizePrefix.js +1 -21
- package/dist/utilities/sanitizePrefix.js.map +1 -1
- package/package.json +6 -6
- package/dist/admin/fields/getFields.d.ts +0 -17
- package/dist/admin/fields/getFields.d.ts.map +0 -1
- package/dist/admin/fields/getFields.js +0 -98
- package/dist/admin/fields/getFields.js.map +0 -1
- package/dist/admin/index.d.ts +0 -4
- package/dist/admin/index.d.ts.map +0 -1
- package/dist/admin/index.js +0 -34
- package/dist/admin/index.js.map +0 -1
- package/dist/utilities/getFileKey.d.ts +0 -22
- package/dist/utilities/getFileKey.d.ts.map +0 -1
- package/dist/utilities/getFileKey.js +0 -23
- package/dist/utilities/getFileKey.js.map +0 -1
- package/dist/utilities/getFileKey.spec.js +0 -174
- package/dist/utilities/getFileKey.spec.js.map +0 -1
- package/dist/utilities/getFilePrefix.spec.js +0 -105
- package/dist/utilities/getFilePrefix.spec.js.map +0 -1
- package/dist/utilities/initClientUploads.d.ts +0 -13
- package/dist/utilities/initClientUploads.d.ts.map +0 -1
- package/dist/utilities/initClientUploads.js +0 -63
- package/dist/utilities/initClientUploads.js.map +0 -1
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2018-
|
|
3
|
+
Copyright (c) 2018-2026 Payload CMS, LLC <info@payloadcms.com>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
6
|
a copy of this software and associated documentation files (the
|
package/README.md
CHANGED
|
@@ -98,6 +98,8 @@ Instead, all uploads will still be reached from the default `/:collectionSlug/fi
|
|
|
98
98
|
|
|
99
99
|
If this does not apply to you (your upload collection has `read: () => true` or similar) you can disable this functionality by setting `disablePayloadAccessControl` to `true`. When this setting is in place, this plugin will update your file URLs to point directly to your cloud host.
|
|
100
100
|
|
|
101
|
+
`disablePayloadAccessControl` does not disable safe outbound fetching. If Payload needs to fetch files from a private or internal storage endpoint, configure the upload collection's [`skipSafeFetch`](https://payloadcms.com/docs/upload/overview#skip-safe-fetch) option with an explicit allowlist for the trusted destination. Set `skipSafeFetch: true` only when every URL accepted by the collection is trusted.
|
|
102
|
+
|
|
101
103
|
## Credit
|
|
102
104
|
|
|
103
105
|
This plugin was created with significant help, and code, from [Alex Bechmann](https://github.com/alexbechmann) and [Richard VanBergen](https://github.com/richardvanbergen). Thank you!!
|
|
@@ -3,23 +3,24 @@ import { type ReactNode } from 'react';
|
|
|
3
3
|
type ClientUploadHandlerProps<T extends Record<string, unknown>> = {
|
|
4
4
|
children: ReactNode;
|
|
5
5
|
collectionSlug: UploadCollectionSlug;
|
|
6
|
-
|
|
7
|
-
extra: T;
|
|
6
|
+
endpointPath?: `/${string}`;
|
|
8
7
|
prefix?: string;
|
|
9
|
-
|
|
8
|
+
props: T;
|
|
10
9
|
};
|
|
11
|
-
export declare const createClientUploadHandler: <T extends Record<string, unknown>>({ handler, }: {
|
|
10
|
+
export declare const createClientUploadHandler: <T extends Record<string, unknown>>({ name, handler, }: {
|
|
12
11
|
handler: (args: {
|
|
13
12
|
apiRoute: string;
|
|
14
13
|
collectionSlug: UploadCollectionSlug;
|
|
14
|
+
data?: unknown;
|
|
15
15
|
docPrefix?: string;
|
|
16
|
-
|
|
16
|
+
endpointPath?: `/${string}`;
|
|
17
17
|
file: File;
|
|
18
18
|
prefix?: string;
|
|
19
|
-
|
|
19
|
+
props: T;
|
|
20
20
|
serverURL: string;
|
|
21
21
|
updateFilename: (value: string) => void;
|
|
22
22
|
}) => Promise<unknown>;
|
|
23
|
-
|
|
23
|
+
name: string;
|
|
24
|
+
}) => ({ children, collectionSlug, endpointPath, prefix, props, }: ClientUploadHandlerProps<T>) => import("react").JSX.Element;
|
|
24
25
|
export {};
|
|
25
26
|
//# sourceMappingURL=createClientUploadHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createClientUploadHandler.d.ts","sourceRoot":"","sources":["../../src/client/createClientUploadHandler.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAGnD,OAAO,EAAY,KAAK,SAAS,EAAa,MAAM,OAAO,CAAA;AAE3D,KAAK,wBAAwB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACjE,QAAQ,EAAE,SAAS,CAAA;IACnB,cAAc,EAAE,oBAAoB,CAAA;IACpC,
|
|
1
|
+
{"version":3,"file":"createClientUploadHandler.d.ts","sourceRoot":"","sources":["../../src/client/createClientUploadHandler.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAGnD,OAAO,EAAY,KAAK,SAAS,EAAa,MAAM,OAAO,CAAA;AAE3D,KAAK,wBAAwB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACjE,QAAQ,EAAE,SAAS,CAAA;IACnB,cAAc,EAAE,oBAAoB,CAAA;IACpC,YAAY,CAAC,EAAE,IAAI,MAAM,EAAE,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,CAAC,CAAA;CACT,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,sBAGxE;IACD,OAAO,EAAE,CAAC,IAAI,EAAE;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,cAAc,EAAE,oBAAoB,CAAA;QACpC,IAAI,CAAC,EAAE,OAAO,CAAA;QACd,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,YAAY,CAAC,EAAE,IAAI,MAAM,EAAE,CAAA;QAC3B,IAAI,EAAE,IAAI,CAAA;QACV,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,EAAE,CAAC,CAAA;QACR,SAAS,EAAE,MAAM,CAAA;QACjB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;KACxC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;CACb,kEAOI,wBAAwB,CAAC,CAAC,CAAC,gCAmD/B,CAAA"}
|
|
@@ -1,33 +1,37 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useConfig, useEffectEvent
|
|
3
|
+
import { useConfig, useEffectEvent } from '@payloadcms/ui';
|
|
4
4
|
import { Fragment, useEffect } from 'react';
|
|
5
|
-
export const createClientUploadHandler = ({ handler })=>{
|
|
6
|
-
return function ClientUploadHandler({ children, collectionSlug,
|
|
7
|
-
const { setUploadHandler } = useUploadHandlers();
|
|
5
|
+
export const createClientUploadHandler = ({ name, handler })=>{
|
|
6
|
+
return function ClientUploadHandler({ children, collectionSlug, endpointPath, prefix, props }) {
|
|
8
7
|
const { config: { routes: { api: apiRoute }, serverURL } } = useConfig();
|
|
9
8
|
const initializeHandler = useEffectEvent(()=>{
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const listener = (event)=>{
|
|
10
|
+
const customEvent = event;
|
|
11
|
+
if (customEvent.detail.collectionSlug !== collectionSlug) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
customEvent.preventDefault();
|
|
15
|
+
void handler({
|
|
16
|
+
apiRoute,
|
|
12
17
|
collectionSlug,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
18
|
+
data: customEvent.detail.data,
|
|
19
|
+
docPrefix: customEvent.detail.docPrefix,
|
|
20
|
+
endpointPath,
|
|
21
|
+
file: customEvent.detail.file,
|
|
22
|
+
prefix,
|
|
23
|
+
props,
|
|
24
|
+
serverURL,
|
|
25
|
+
updateFilename: customEvent.detail.updateFilename
|
|
26
|
+
}).then(customEvent.detail.resolve, customEvent.detail.reject);
|
|
27
|
+
};
|
|
28
|
+
const eventName = `payload:upload:${name}`;
|
|
29
|
+
const eventTarget = globalThis;
|
|
30
|
+
eventTarget.addEventListener(eventName, listener);
|
|
31
|
+
return ()=>eventTarget.removeEventListener(eventName, listener);
|
|
28
32
|
});
|
|
29
33
|
useEffect(()=>{
|
|
30
|
-
initializeHandler();
|
|
34
|
+
return initializeHandler();
|
|
31
35
|
}, []);
|
|
32
36
|
return /*#__PURE__*/ _jsx(Fragment, {
|
|
33
37
|
children: children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client/createClientUploadHandler.tsx"],"sourcesContent":["'use client'\n\nimport type { UploadCollectionSlug } from 'payload'\n\nimport { useConfig, useEffectEvent
|
|
1
|
+
{"version":3,"sources":["../../src/client/createClientUploadHandler.tsx"],"sourcesContent":["'use client'\n\nimport type { UploadCollectionSlug } from 'payload'\n\nimport { useConfig, useEffectEvent } from '@payloadcms/ui'\nimport { Fragment, type ReactNode, useEffect } from 'react'\n\ntype ClientUploadHandlerProps<T extends Record<string, unknown>> = {\n children: ReactNode\n collectionSlug: UploadCollectionSlug\n endpointPath?: `/${string}`\n prefix?: string\n props: T\n}\n\nexport const createClientUploadHandler = <T extends Record<string, unknown>>({\n name,\n handler,\n}: {\n handler: (args: {\n apiRoute: string\n collectionSlug: UploadCollectionSlug\n data?: unknown\n docPrefix?: string\n endpointPath?: `/${string}`\n file: File\n prefix?: string\n props: T\n serverURL: string\n updateFilename: (value: string) => void\n }) => Promise<unknown>\n name: string\n}) => {\n return function ClientUploadHandler({\n children,\n collectionSlug,\n endpointPath,\n prefix,\n props,\n }: ClientUploadHandlerProps<T>) {\n const {\n config: {\n routes: { api: apiRoute },\n serverURL,\n },\n } = useConfig()\n\n const initializeHandler = useEffectEvent(() => {\n const listener = (event: Event) => {\n const customEvent = event as CustomEvent<{\n collectionSlug: UploadCollectionSlug\n data?: unknown\n docPrefix?: string\n file: File\n reject: (reason?: unknown) => void\n resolve: (value: unknown) => void\n updateFilename: (value: string) => void\n }>\n\n if (customEvent.detail.collectionSlug !== collectionSlug) {\n return\n }\n\n customEvent.preventDefault()\n void handler({\n apiRoute,\n collectionSlug,\n data: customEvent.detail.data,\n docPrefix: customEvent.detail.docPrefix,\n endpointPath,\n file: customEvent.detail.file,\n prefix,\n props,\n serverURL,\n updateFilename: customEvent.detail.updateFilename,\n }).then(customEvent.detail.resolve, customEvent.detail.reject)\n }\n\n const eventName = `payload:upload:${name}`\n const eventTarget = globalThis as unknown as EventTarget\n eventTarget.addEventListener(eventName, listener)\n return () => eventTarget.removeEventListener(eventName, listener)\n })\n\n useEffect(() => {\n return initializeHandler()\n }, [])\n\n return <Fragment>{children}</Fragment>\n }\n}\n"],"names":["useConfig","useEffectEvent","Fragment","useEffect","createClientUploadHandler","name","handler","ClientUploadHandler","children","collectionSlug","endpointPath","prefix","props","config","routes","api","apiRoute","serverURL","initializeHandler","listener","event","customEvent","detail","preventDefault","data","docPrefix","file","updateFilename","then","resolve","reject","eventName","eventTarget","globalThis","addEventListener","removeEventListener"],"mappings":"AAAA;;AAIA,SAASA,SAAS,EAAEC,cAAc,QAAQ,iBAAgB;AAC1D,SAASC,QAAQ,EAAkBC,SAAS,QAAQ,QAAO;AAU3D,OAAO,MAAMC,4BAA4B,CAAoC,EAC3EC,IAAI,EACJC,OAAO,EAeR;IACC,OAAO,SAASC,oBAAoB,EAClCC,QAAQ,EACRC,cAAc,EACdC,YAAY,EACZC,MAAM,EACNC,KAAK,EACuB;QAC5B,MAAM,EACJC,QAAQ,EACNC,QAAQ,EAAEC,KAAKC,QAAQ,EAAE,EACzBC,SAAS,EACV,EACF,GAAGjB;QAEJ,MAAMkB,oBAAoBjB,eAAe;YACvC,MAAMkB,WAAW,CAACC;gBAChB,MAAMC,cAAcD;gBAUpB,IAAIC,YAAYC,MAAM,CAACb,cAAc,KAAKA,gBAAgB;oBACxD;gBACF;gBAEAY,YAAYE,cAAc;gBAC1B,KAAKjB,QAAQ;oBACXU;oBACAP;oBACAe,MAAMH,YAAYC,MAAM,CAACE,IAAI;oBAC7BC,WAAWJ,YAAYC,MAAM,CAACG,SAAS;oBACvCf;oBACAgB,MAAML,YAAYC,MAAM,CAACI,IAAI;oBAC7Bf;oBACAC;oBACAK;oBACAU,gBAAgBN,YAAYC,MAAM,CAACK,cAAc;gBACnD,GAAGC,IAAI,CAACP,YAAYC,MAAM,CAACO,OAAO,EAAER,YAAYC,MAAM,CAACQ,MAAM;YAC/D;YAEA,MAAMC,YAAY,CAAC,eAAe,EAAE1B,MAAM;YAC1C,MAAM2B,cAAcC;YACpBD,YAAYE,gBAAgB,CAACH,WAAWZ;YACxC,OAAO,IAAMa,YAAYG,mBAAmB,CAACJ,WAAWZ;QAC1D;QAEAhB,UAAU;YACR,OAAOe;QACT,GAAG,EAAE;QAEL,qBAAO,KAAChB;sBAAUM;;IACpB;AACF,EAAC"}
|
package/dist/exports/client.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { createClientUploadHandler } from '../client/createClientUploadHandler.js';
|
|
2
|
+
export { buildStoragePathData, buildUploadStoragePathData, } from '../utilities/buildStoragePathData.js';
|
|
3
|
+
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
2
4
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAA"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAA;AAClF,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,sCAAsC,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA"}
|
package/dist/exports/client.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { createClientUploadHandler } from '../client/createClientUploadHandler.js';
|
|
2
|
+
export { buildStoragePathData, buildUploadStoragePathData } from '../utilities/buildStoragePathData.js';
|
|
3
|
+
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
2
4
|
|
|
3
5
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { createClientUploadHandler } from '../client/createClientUploadHandler.js'\n"],"names":["createClientUploadHandler"],"mappings":"AAAA,SAASA,yBAAyB,QAAQ,yCAAwC"}
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { createClientUploadHandler } from '../client/createClientUploadHandler.js'\nexport {\n buildStoragePathData,\n buildUploadStoragePathData,\n} from '../utilities/buildStoragePathData.js'\nexport { sanitizePrefix } from '../utilities/sanitizePrefix.js'\n"],"names":["createClientUploadHandler","buildStoragePathData","buildUploadStoragePathData","sanitizePrefix"],"mappings":"AAAA,SAASA,yBAAyB,QAAQ,yCAAwC;AAClF,SACEC,oBAAoB,EACpBC,0BAA0B,QACrB,uCAAsC;AAC7C,SAASC,cAAc,QAAQ,iCAAgC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { buildStoragePathData, buildUploadStoragePathData, isStoragePathWithinCollectionPrefix, } from '../utilities/buildStoragePathData.js';
|
|
2
2
|
export { getFilePrefix } from '../utilities/getFilePrefix.js';
|
|
3
|
-
export {
|
|
3
|
+
export { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js';
|
|
4
4
|
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
5
5
|
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/exports/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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,6 +1,6 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { buildStoragePathData, buildUploadStoragePathData, isStoragePathWithinCollectionPrefix } from '../utilities/buildStoragePathData.js';
|
|
2
2
|
export { getFilePrefix } from '../utilities/getFilePrefix.js';
|
|
3
|
-
export {
|
|
3
|
+
export { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js';
|
|
4
4
|
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
5
5
|
|
|
6
6
|
//# sourceMappingURL=utilities.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/utilities.ts"],"sourcesContent":["export {
|
|
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"}
|
|
@@ -2,10 +2,6 @@ import type { CollectionConfig, Field } from 'payload';
|
|
|
2
2
|
import type { GeneratedAdapter, GenerateFileURL } from '../types.js';
|
|
3
3
|
interface Args {
|
|
4
4
|
adapter?: GeneratedAdapter;
|
|
5
|
-
/**
|
|
6
|
-
* When true, always insert the prefix field regardless of whether a prefix is configured.
|
|
7
|
-
*/
|
|
8
|
-
alwaysInsertFields?: boolean;
|
|
9
5
|
collection: CollectionConfig;
|
|
10
6
|
disablePayloadAccessControl?: true;
|
|
11
7
|
generateFileURL?: GenerateFileURL;
|
|
@@ -16,6 +12,6 @@ interface Args {
|
|
|
16
12
|
*/
|
|
17
13
|
useCompositePrefixes?: boolean;
|
|
18
14
|
}
|
|
19
|
-
export declare const getFields: ({ adapter,
|
|
15
|
+
export declare const getFields: ({ adapter, collection, disablePayloadAccessControl, generateFileURL, prefix, useCompositePrefixes, }: Args) => Field[];
|
|
20
16
|
export {};
|
|
21
17
|
//# sourceMappingURL=getFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../src/fields/getFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../src/fields/getFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAgD,MAAM,SAAS,CAAA;AAIpG,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAMpE,UAAU,IAAI;IACZ,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,UAAU,EAAE,gBAAgB,CAAA;IAC5B,2BAA2B,CAAC,EAAE,IAAI,CAAA;IAClC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,eAAO,MAAM,SAAS,yGAOnB,IAAI,KAAG,KAAK,EAkNd,CAAA"}
|
package/dist/fields/getFields.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { getAfterReadHook } from '../hooks/afterRead.js';
|
|
3
3
|
import { getBeforeChangeHook } from '../hooks/beforeChange.js';
|
|
4
|
-
|
|
4
|
+
import { getNormalizeUploadPrefixFieldHook } from '../hooks/normalizeUploadPrefix.js';
|
|
5
|
+
export const getFields = ({ adapter, collection, disablePayloadAccessControl, generateFileURL, prefix, useCompositePrefixes = false })=>{
|
|
5
6
|
const baseURLField = {
|
|
6
7
|
name: 'url',
|
|
7
8
|
type: 'text',
|
|
@@ -15,10 +16,22 @@ export const getFields = ({ adapter, alwaysInsertFields, collection, disablePayl
|
|
|
15
16
|
name: 'prefix',
|
|
16
17
|
type: 'text',
|
|
17
18
|
admin: {
|
|
19
|
+
disabled: {
|
|
20
|
+
bulkEdit: true,
|
|
21
|
+
column: true,
|
|
22
|
+
filter: true,
|
|
23
|
+
groupBy: true
|
|
24
|
+
},
|
|
18
25
|
hidden: true,
|
|
19
26
|
readOnly: true
|
|
20
27
|
}
|
|
21
28
|
};
|
|
29
|
+
// Server-owned key segment; hidden from the API and admin, read internally via showHiddenFields.
|
|
30
|
+
const baseObjectKeyField = {
|
|
31
|
+
name: '_objectKey',
|
|
32
|
+
type: 'text',
|
|
33
|
+
hidden: true
|
|
34
|
+
};
|
|
22
35
|
const fields = [
|
|
23
36
|
...collection.fields,
|
|
24
37
|
...adapter?.fields || []
|
|
@@ -67,10 +80,13 @@ export const getFields = ({ adapter, alwaysInsertFields, collection, disablePayl
|
|
|
67
80
|
...existingURLField || {}
|
|
68
81
|
});
|
|
69
82
|
}
|
|
70
|
-
|
|
83
|
+
// Storage adapters add these fields during their `init`, after transformers (e.g. Sharp) have
|
|
84
|
+
// written each collection's image sizes onto its upload config.
|
|
85
|
+
const variants = typeof collection.upload === 'object' ? collection.upload.variants : undefined;
|
|
86
|
+
if (variants) {
|
|
71
87
|
let existingSizesFieldIndex = -1;
|
|
72
88
|
const existingSizesField = fields.find((existingField, i)=>{
|
|
73
|
-
if ('name' in existingField && existingField.name === '
|
|
89
|
+
if ('name' in existingField && existingField.name === 'variants') {
|
|
74
90
|
existingSizesFieldIndex = i;
|
|
75
91
|
return true;
|
|
76
92
|
}
|
|
@@ -81,12 +97,12 @@ export const getFields = ({ adapter, alwaysInsertFields, collection, disablePayl
|
|
|
81
97
|
}
|
|
82
98
|
const sizesField = {
|
|
83
99
|
...existingSizesField || {},
|
|
84
|
-
name: '
|
|
100
|
+
name: 'variants',
|
|
85
101
|
type: 'group',
|
|
86
102
|
admin: {
|
|
87
103
|
hidden: true
|
|
88
104
|
},
|
|
89
|
-
fields:
|
|
105
|
+
fields: variants.map((size)=>{
|
|
90
106
|
const existingSizeField = existingSizesField?.fields.find((existingField)=>'name' in existingField && existingField.name === size.name);
|
|
91
107
|
const existingSizeURLField = existingSizeField?.fields.find((existingField)=>'name' in existingField && existingField.name === 'url');
|
|
92
108
|
// Only add afterRead hook if adapter is provided
|
|
@@ -132,25 +148,41 @@ export const getFields = ({ adapter, alwaysInsertFields, collection, disablePayl
|
|
|
132
148
|
};
|
|
133
149
|
fields.push(sizesField);
|
|
134
150
|
}
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
return false;
|
|
144
|
-
});
|
|
145
|
-
if (existingPrefixFieldIndex > -1) {
|
|
146
|
-
fields.splice(existingPrefixFieldIndex, 1);
|
|
151
|
+
// Always insert the prefix field so the schema stays consistent regardless of
|
|
152
|
+
// whether the plugin is enabled or a prefix is configured.
|
|
153
|
+
let existingPrefixFieldIndex = -1;
|
|
154
|
+
const existingPrefixField = fields.find((existingField, i)=>{
|
|
155
|
+
if ('name' in existingField && existingField.name === 'prefix') {
|
|
156
|
+
existingPrefixFieldIndex = i;
|
|
157
|
+
return true;
|
|
147
158
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
});
|
|
159
|
+
return false;
|
|
160
|
+
});
|
|
161
|
+
if (existingPrefixFieldIndex > -1) {
|
|
162
|
+
fields.splice(existingPrefixFieldIndex, 1);
|
|
153
163
|
}
|
|
164
|
+
fields.push({
|
|
165
|
+
...basePrefixField,
|
|
166
|
+
...existingPrefixField || {},
|
|
167
|
+
defaultValue: existingPrefixField?.defaultValue ?? (useCompositePrefixes ? '' : prefix ? path.posix.join(prefix) : ''),
|
|
168
|
+
hooks: {
|
|
169
|
+
...existingPrefixField?.hooks,
|
|
170
|
+
beforeChange: [
|
|
171
|
+
...existingPrefixField?.hooks?.beforeChange || [],
|
|
172
|
+
getNormalizeUploadPrefixFieldHook({
|
|
173
|
+
collectionPrefix: prefix,
|
|
174
|
+
useCompositePrefixes
|
|
175
|
+
})
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
const existingObjectKeyFieldIndex = fields.findIndex((existingField)=>'name' in existingField && existingField.name === '_objectKey');
|
|
180
|
+
if (existingObjectKeyFieldIndex > -1) {
|
|
181
|
+
fields.splice(existingObjectKeyFieldIndex, 1);
|
|
182
|
+
}
|
|
183
|
+
fields.push({
|
|
184
|
+
...baseObjectKeyField
|
|
185
|
+
});
|
|
154
186
|
return fields;
|
|
155
187
|
};
|
|
156
188
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/getFields.ts"],"sourcesContent":["import type { CollectionConfig, Field, GroupField, 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'\n\ninterface Args {\n adapter?: GeneratedAdapter\n /**\n * When true, always insert the prefix field regardless of whether a prefix is configured.\n */\n alwaysInsertFields?: boolean\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 alwaysInsertFields,\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 hidden: true,\n readOnly: 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 if (typeof collection.upload === 'object' && collection.upload.imageSizes) {\n let existingSizesFieldIndex = -1\n\n const existingSizesField = fields.find((existingField, i) => {\n if ('name' in existingField && existingField.name === 'sizes') {\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: 'sizes',\n type: 'group',\n admin: {\n hidden: true,\n },\n fields: collection.upload.imageSizes.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: [...(adapter?.fields || []), sizeURLField],\n } as Field\n }),\n }\n\n fields.push(sizesField)\n }\n\n // If prefix is enabled or alwaysInsertFields is true, save it to db\n if (typeof prefix !== 'undefined' || alwaysInsertFields) {\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: useCompositePrefixes ? '' : prefix ? path.posix.join(prefix) : '',\n } as TextField)\n }\n\n return fields\n}\n"],"names":["path","getAfterReadHook","getBeforeChangeHook","getFields","adapter","alwaysInsertFields","collection","disablePayloadAccessControl","generateFileURL","prefix","useCompositePrefixes","baseURLField","name","type","admin","hidden","readOnly","label","basePrefixField","fields","existingURLFieldIndex","existingURLField","find","existingField","i","splice","push","hooks","afterRead","beforeChange","upload","imageSizes","existingSizesFieldIndex","existingSizesField","sizesField","map","size","existingSizeField","existingSizeURLField","sizeURLField","existingPrefixFieldIndex","existingPrefixField","defaultValue","posix","join"],"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; hidden from the API and admin, read internally via showHiddenFields.\n const baseObjectKeyField: TextField = {\n name: '_objectKey',\n type: 'text',\n hidden: true,\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 // 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: [...(adapter?.fields || []), sizeURLField],\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","fields","existingURLFieldIndex","existingURLField","find","existingField","i","splice","push","hooks","afterRead","beforeChange","variants","upload","undefined","existingSizesFieldIndex","existingSizesField","sizesField","map","size","existingSizeField","existingSizeURLField","sizeURLField","existingPrefixFieldIndex","existingPrefixField","defaultValue","posix","join","collectionPrefix","existingObjectKeyFieldIndex","findIndex"],"mappings":"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"}
|
|
@@ -3,7 +3,9 @@ import type { GeneratedAdapter } from '../types.js';
|
|
|
3
3
|
interface Args {
|
|
4
4
|
adapter: GeneratedAdapter;
|
|
5
5
|
collection: CollectionConfig;
|
|
6
|
+
collectionPrefix?: string;
|
|
7
|
+
useCompositePrefixes?: boolean;
|
|
6
8
|
}
|
|
7
|
-
export declare const getAfterChangeHook: ({ adapter, collection }: Args) => CollectionAfterChangeHook<FileData & TypeWithID>;
|
|
9
|
+
export declare const getAfterChangeHook: ({ adapter, collection, collectionPrefix, useCompositePrefixes, }: Args) => CollectionAfterChangeHook<FileData & TypeWithID>;
|
|
8
10
|
export {};
|
|
9
11
|
//# sourceMappingURL=afterChange.d.ts.map
|
|
@@ -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;
|
|
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;AASnD,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;AAQD,eAAO,MAAM,kBAAkB,qEAM1B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,CA8KxD,CAAA"}
|
|
@@ -1,73 +1,150 @@
|
|
|
1
|
+
import { deepMergeWithSourceArrays } from 'payload';
|
|
2
|
+
import { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js';
|
|
3
|
+
import { buildStoragePathData, buildUploadStoragePathData } from '../utilities/buildStoragePathData.js';
|
|
1
4
|
import { getIncomingFiles } from '../utilities/getIncomingFiles.js';
|
|
2
|
-
|
|
5
|
+
// The object's folder: semantic prefix + `_objectKey` segment.
|
|
6
|
+
const getObjectFolder = (data)=>{
|
|
7
|
+
const record = data ?? {};
|
|
8
|
+
return buildPrefixWithObjectKey({
|
|
9
|
+
objectKey: record._objectKey,
|
|
10
|
+
prefix: record.prefix
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
export const getAfterChangeHook = ({ adapter, collection, collectionPrefix, useCompositePrefixes })=>async ({ data, doc, operation, previousDoc, req, select })=>{
|
|
3
14
|
// Skip if this is an internal update to prevent infinite loop
|
|
4
15
|
if (req.context?.skipCloudStorage) {
|
|
5
16
|
return doc;
|
|
6
17
|
}
|
|
18
|
+
// Restore upload metadata removed by select, including partially selected image sizes.
|
|
19
|
+
const uploadData = select ? deepMergeWithSourceArrays(data, doc) : doc;
|
|
20
|
+
const isDraftSave = uploadData._status === 'draft';
|
|
21
|
+
const isDraftOverPublished = isDraftSave && previousDoc?._status === 'published';
|
|
7
22
|
try {
|
|
8
23
|
const files = getIncomingFiles({
|
|
9
|
-
data:
|
|
24
|
+
data: uploadData,
|
|
10
25
|
req
|
|
11
26
|
});
|
|
12
27
|
if (files.length > 0) {
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
if (typeof previousDoc.sizes === 'object') {
|
|
21
|
-
filesToDelete = filesToDelete.concat(Object.values(previousDoc?.sizes || []).map((resizedFileData)=>resizedFileData?.filename));
|
|
22
|
-
}
|
|
23
|
-
const deletionPromises = filesToDelete.map(async (filename)=>{
|
|
24
|
-
if (filename) {
|
|
25
|
-
await adapter.handleDelete({
|
|
26
|
-
collection,
|
|
27
|
-
doc: previousDoc,
|
|
28
|
-
filename,
|
|
29
|
-
req
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
await Promise.all(deletionPromises);
|
|
34
|
-
}
|
|
35
|
-
const uploadResults = await Promise.all(files.filter((file)=>!file.clientUploadContext).map((file)=>adapter.handleUpload({
|
|
36
|
-
clientUploadContext: file.clientUploadContext,
|
|
28
|
+
// Fold `_objectKey` so generated sizes land in the same folder as the original.
|
|
29
|
+
const dataForUpload = {
|
|
30
|
+
...uploadData,
|
|
31
|
+
prefix: getObjectFolder(uploadData)
|
|
32
|
+
};
|
|
33
|
+
const uploadResults = await Promise.all(files.filter((file)=>!file.uploadReference).map((file)=>adapter.handleUpload({
|
|
37
34
|
collection,
|
|
38
|
-
data:
|
|
35
|
+
data: dataForUpload,
|
|
39
36
|
file,
|
|
40
|
-
req
|
|
37
|
+
req,
|
|
38
|
+
storageFilePath: buildUploadStoragePathData({
|
|
39
|
+
collectionPrefix,
|
|
40
|
+
docPrefix: dataForUpload.prefix,
|
|
41
|
+
filename: file.filename,
|
|
42
|
+
useCompositePrefixes
|
|
43
|
+
}).storageFilePath
|
|
41
44
|
})));
|
|
42
45
|
const uploadMetadata = uploadResults.filter((result)=>result != null && typeof result === 'object').reduce((acc, metadata)=>({
|
|
43
46
|
...acc,
|
|
44
47
|
...metadata
|
|
45
48
|
}), {});
|
|
49
|
+
// Adapters may echo `data` back as metadata; keep the document's own `prefix`/`_objectKey`.
|
|
50
|
+
delete uploadMetadata.prefix;
|
|
51
|
+
delete uploadMetadata._objectKey;
|
|
52
|
+
let docWithMetadata = doc;
|
|
46
53
|
if (Object.keys(uploadMetadata).length > 0) {
|
|
54
|
+
if (!req.context) {
|
|
55
|
+
req.context = {};
|
|
56
|
+
}
|
|
57
|
+
req.context.skipCloudStorage = true;
|
|
58
|
+
// Clear to prevent re-processing
|
|
59
|
+
req.file = undefined;
|
|
60
|
+
req.payloadUploadSizes = undefined;
|
|
47
61
|
try {
|
|
48
|
-
|
|
49
|
-
req.context = {};
|
|
50
|
-
}
|
|
51
|
-
req.context.skipCloudStorage = true;
|
|
52
|
-
// Clear to prevent re-processing
|
|
53
|
-
req.file = undefined;
|
|
54
|
-
req.payloadUploadSizes = undefined;
|
|
55
|
-
await req.payload.update({
|
|
62
|
+
const updatedDoc = await req.payload.update({
|
|
56
63
|
id: doc.id,
|
|
57
64
|
collection: collection.slug,
|
|
58
65
|
data: uploadMetadata,
|
|
59
66
|
depth: 0,
|
|
60
|
-
|
|
67
|
+
draft: isDraftSave,
|
|
68
|
+
overrideAccess: true,
|
|
69
|
+
req,
|
|
70
|
+
select
|
|
61
71
|
});
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
// Persist all adapter metadata, but do not add unselected fields to the response.
|
|
73
|
+
docWithMetadata = select ? {
|
|
74
|
+
...doc,
|
|
75
|
+
...updatedDoc
|
|
76
|
+
} : {
|
|
64
77
|
...doc,
|
|
65
78
|
...uploadMetadata
|
|
66
79
|
};
|
|
67
|
-
}
|
|
68
|
-
req.
|
|
80
|
+
} finally{
|
|
81
|
+
delete req.context.skipCloudStorage;
|
|
69
82
|
}
|
|
70
83
|
}
|
|
84
|
+
// Delete previous files only after the new upload and metadata
|
|
85
|
+
// persistence have succeeded. Deleting earlier would orphan the
|
|
86
|
+
// record if a later step throws (e.g. a user-defined afterChange
|
|
87
|
+
// hook on the same collection).
|
|
88
|
+
if (previousDoc && operation === 'update' && !isDraftOverPublished) {
|
|
89
|
+
let filesToDelete = [];
|
|
90
|
+
if (typeof previousDoc?.filename === 'string') {
|
|
91
|
+
filesToDelete.push(previousDoc.filename);
|
|
92
|
+
}
|
|
93
|
+
if (typeof previousDoc.variants === 'object') {
|
|
94
|
+
filesToDelete = filesToDelete.concat(Object.values(previousDoc?.variants || []).map((resizedFileData)=>resizedFileData?.filename));
|
|
95
|
+
}
|
|
96
|
+
// Compare full locations: a replacement can reuse a filename while moving
|
|
97
|
+
// a legacy object beneath the collection prefix.
|
|
98
|
+
const newFileData = {
|
|
99
|
+
...uploadData,
|
|
100
|
+
...uploadMetadata
|
|
101
|
+
};
|
|
102
|
+
const newFilenames = new Set();
|
|
103
|
+
if (typeof newFileData.filename === 'string') {
|
|
104
|
+
newFilenames.add(newFileData.filename);
|
|
105
|
+
}
|
|
106
|
+
if (typeof newFileData.variants === 'object') {
|
|
107
|
+
for (const size of Object.values(newFileData.variants || {})){
|
|
108
|
+
if (size?.filename && typeof size.filename === 'string') {
|
|
109
|
+
newFilenames.add(size.filename);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const resolveKey = ({ data, filename })=>buildStoragePathData({
|
|
114
|
+
collectionPrefix,
|
|
115
|
+
docPrefix: getObjectFolder(data),
|
|
116
|
+
filename,
|
|
117
|
+
useCompositePrefixes
|
|
118
|
+
}).storageFilePath;
|
|
119
|
+
const newKeys = new Set([
|
|
120
|
+
...newFilenames
|
|
121
|
+
].map((filename)=>resolveKey({
|
|
122
|
+
data: newFileData,
|
|
123
|
+
filename
|
|
124
|
+
})));
|
|
125
|
+
const deletionPromises = filesToDelete.map(async (filename)=>{
|
|
126
|
+
if (!filename) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const storageFilePath = resolveKey({
|
|
130
|
+
data: previousDoc,
|
|
131
|
+
filename
|
|
132
|
+
});
|
|
133
|
+
if (!newKeys.has(storageFilePath)) {
|
|
134
|
+
await adapter.handleDelete({
|
|
135
|
+
collection,
|
|
136
|
+
doc: previousDoc,
|
|
137
|
+
filename,
|
|
138
|
+
req,
|
|
139
|
+
storageFilePath
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
await Promise.all(deletionPromises);
|
|
144
|
+
}
|
|
145
|
+
if (docWithMetadata !== doc) {
|
|
146
|
+
return docWithMetadata;
|
|
147
|
+
}
|
|
71
148
|
}
|
|
72
149
|
} catch (err) {
|
|
73
150
|
req.payload.logger.error(`There was an error while uploading files corresponding to the collection ${collection.slug} with filename ${doc.filename}:`);
|