@payloadcms/plugin-cloud-storage 4.0.0-internal.40de3ec → 4.0.0-internal.435b2d6
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/dist/admin/fields/getFields.d.ts.map +1 -1
- package/dist/admin/index.d.ts.map +1 -1
- 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 +0 -1
- package/dist/exports/utilities.d.ts.map +1 -1
- package/dist/exports/utilities.js +0 -1
- package/dist/exports/utilities.js.map +1 -1
- package/dist/fields/getFields.d.ts.map +1 -1
- package/dist/hooks/afterChange.d.ts.map +1 -1
- package/dist/hooks/afterChange.js +5 -3
- package/dist/hooks/afterChange.js.map +1 -1
- package/dist/hooks/afterDelete.d.ts.map +1 -1
- package/dist/hooks/afterRead.d.ts.map +1 -1
- package/dist/hooks/beforeChange.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +45 -4
- package/dist/plugin.js.map +1 -1
- package/dist/types.d.ts +15 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/getFilePrefix.d.ts +3 -3
- package/dist/utilities/getFilePrefix.d.ts.map +1 -1
- package/dist/utilities/getFilePrefix.js +5 -5
- package/dist/utilities/getFilePrefix.js.map +1 -1
- package/dist/utilities/getFilePrefix.spec.js +3 -3
- package/dist/utilities/getFilePrefix.spec.js.map +1 -1
- package/dist/utilities/getIncomingFiles.js +1 -1
- package/dist/utilities/getIncomingFiles.js.map +1 -1
- package/dist/utilities/resolveSignedURLKey.d.ts +1 -1
- package/dist/utilities/resolveSignedURLKey.js +1 -1
- package/dist/utilities/resolveSignedURLKey.js.map +1 -1
- package/package.json +4 -4
- 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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../../src/admin/fields/getFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAyB,MAAM,SAAS,CAAA;AAI7E,UAAU,IAAI;IACZ;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,UAAU,EAAE,gBAAgB,CAAA;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../../src/admin/fields/getFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAyB,MAAM,SAAS,CAAA;AAI7E,UAAU,IAAI;IACZ;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,UAAU,EAAE,gBAAgB,CAAA;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,eAAO,MAAM,SAAS,sEAKnB,IAAI,KAAG,KAAK,EAsHd,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAOhD,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAOhD,eAAO,MAAM,YAAY,kBACP,aAAa,sBACZ,MAAM,KAAG,MA+BzB,CAAA"}
|
|
@@ -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 +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,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA"}
|
package/dist/exports/client.js
CHANGED
|
@@ -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 { getFileKey } from '../utilities/getFileKey.js'\nexport { sanitizePrefix } from '../utilities/sanitizePrefix.js'\n"],"names":["createClientUploadHandler","getFileKey","sanitizePrefix"],"mappings":"AAAA,SAASA,yBAAyB,QAAQ,yCAAwC;AAClF,SAASC,UAAU,QAAQ,6BAA4B;AACvD,SAASC,cAAc,QAAQ,iCAAgC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { getFileKey } from '../utilities/getFileKey.js';
|
|
2
2
|
export { getFilePrefix } from '../utilities/getFilePrefix.js';
|
|
3
|
-
export { initClientUploads } from '../utilities/initClientUploads.js';
|
|
4
3
|
export { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js';
|
|
5
4
|
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
6
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,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAC7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/exports/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AACvD,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,5 @@
|
|
|
1
1
|
export { getFileKey } from '../utilities/getFileKey.js';
|
|
2
2
|
export { getFilePrefix } from '../utilities/getFilePrefix.js';
|
|
3
|
-
export { initClientUploads } from '../utilities/initClientUploads.js';
|
|
4
3
|
export { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js';
|
|
5
4
|
export { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
6
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/utilities.ts"],"sourcesContent":["export { getFileKey } from '../utilities/getFileKey.js'\nexport { getFilePrefix } from '../utilities/getFilePrefix.js'\nexport {
|
|
1
|
+
{"version":3,"sources":["../../src/exports/utilities.ts"],"sourcesContent":["export { getFileKey } from '../utilities/getFileKey.js'\nexport { getFilePrefix } from '../utilities/getFilePrefix.js'\nexport { resolveSignedURLKey } from '../utilities/resolveSignedURLKey.js'\nexport { sanitizePrefix } from '../utilities/sanitizePrefix.js'\n"],"names":["getFileKey","getFilePrefix","resolveSignedURLKey","sanitizePrefix"],"mappings":"AAAA,SAASA,UAAU,QAAQ,6BAA4B;AACvD,SAASC,aAAa,QAAQ,gCAA+B;AAC7D,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,cAAc,QAAQ,iCAAgC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../src/fields/getFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAyB,MAAM,SAAS,CAAA;AAI7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAKpE,UAAU,IAAI;IACZ,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,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,
|
|
1
|
+
{"version":3,"file":"getFields.d.ts","sourceRoot":"","sources":["../../src/fields/getFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAyB,MAAM,SAAS,CAAA;AAI7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAKpE,UAAU,IAAI;IACZ,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B;;OAEG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,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,6HAQnB,IAAI,KAAG,KAAK,EA+Kd,CAAA"}
|
|
@@ -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;AAEhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAInD,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED,eAAO,MAAM,kBAAkB,
|
|
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;AAEhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAInD,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED,eAAO,MAAM,kBAAkB,4BACH,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,CAyH/E,CAAA"}
|
|
@@ -4,14 +4,15 @@ export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, opera
|
|
|
4
4
|
if (req.context?.skipCloudStorage) {
|
|
5
5
|
return doc;
|
|
6
6
|
}
|
|
7
|
+
const isDraftSave = doc._status === 'draft';
|
|
8
|
+
const isDraftOverPublished = isDraftSave && previousDoc?._status === 'published';
|
|
7
9
|
try {
|
|
8
10
|
const files = getIncomingFiles({
|
|
9
11
|
data: doc,
|
|
10
12
|
req
|
|
11
13
|
});
|
|
12
14
|
if (files.length > 0) {
|
|
13
|
-
const uploadResults = await Promise.all(files.filter((file)=>!file.
|
|
14
|
-
clientUploadContext: file.clientUploadContext,
|
|
15
|
+
const uploadResults = await Promise.all(files.filter((file)=>!file.directUpload).map((file)=>adapter.handleUpload({
|
|
15
16
|
collection,
|
|
16
17
|
data: doc,
|
|
17
18
|
file,
|
|
@@ -36,6 +37,7 @@ export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, opera
|
|
|
36
37
|
collection: collection.slug,
|
|
37
38
|
data: uploadMetadata,
|
|
38
39
|
depth: 0,
|
|
40
|
+
draft: isDraftSave,
|
|
39
41
|
req
|
|
40
42
|
});
|
|
41
43
|
} finally{
|
|
@@ -50,7 +52,7 @@ export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, opera
|
|
|
50
52
|
// persistence have succeeded. Deleting earlier would orphan the
|
|
51
53
|
// record if a later step throws (e.g. a user-defined afterChange
|
|
52
54
|
// hook on the same collection).
|
|
53
|
-
if (previousDoc && operation === 'update') {
|
|
55
|
+
if (previousDoc && operation === 'update' && !isDraftOverPublished) {
|
|
54
56
|
let filesToDelete = [];
|
|
55
57
|
if (typeof previousDoc?.filename === 'string') {
|
|
56
58
|
filesToDelete.push(previousDoc.filename);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/afterChange.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport type { GeneratedAdapter } from '../types.js'\n\nimport { getIncomingFiles } from '../utilities/getIncomingFiles.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n}\n\nexport const getAfterChangeHook =\n ({ adapter, collection }: Args): CollectionAfterChangeHook<FileData & TypeWithID> =>\n async ({ doc, operation, previousDoc, req }) => {\n // Skip if this is an internal update to prevent infinite loop\n if (req.context?.skipCloudStorage) {\n return doc\n }\n\n try {\n const files = getIncomingFiles({ data: doc, req })\n\n if (files.length > 0) {\n const uploadResults = await Promise.all(\n files\n .filter((file) => !file.
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/afterChange.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport type { GeneratedAdapter } from '../types.js'\n\nimport { getIncomingFiles } from '../utilities/getIncomingFiles.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n}\n\nexport const getAfterChangeHook =\n ({ adapter, collection }: Args): CollectionAfterChangeHook<FileData & TypeWithID> =>\n async ({ doc, operation, previousDoc, req }) => {\n // Skip if this is an internal update to prevent infinite loop\n if (req.context?.skipCloudStorage) {\n return doc\n }\n\n const isDraftSave = (doc as { _status?: string })._status === 'draft'\n const isDraftOverPublished =\n isDraftSave && (previousDoc as { _status?: string } | undefined)?._status === 'published'\n\n try {\n const files = getIncomingFiles({ data: doc, req })\n\n if (files.length > 0) {\n const uploadResults = await Promise.all(\n files\n .filter((file) => !file.directUpload)\n .map((file) =>\n adapter.handleUpload({\n collection,\n data: doc,\n file,\n req,\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 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 await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: uploadMetadata,\n depth: 0,\n draft: isDraftSave,\n req,\n })\n } finally {\n delete req.context.skipCloudStorage\n }\n\n docWithMetadata = { ...doc, ...uploadMetadata }\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 (previousDoc && operation === 'update' && !isDraftOverPublished) {\n let filesToDelete: string[] = []\n\n if (typeof previousDoc?.filename === 'string') {\n filesToDelete.push(previousDoc.filename)\n }\n\n if (typeof previousDoc.sizes === 'object') {\n filesToDelete = filesToDelete.concat(\n Object.values(previousDoc?.sizes || []).map(\n (resizedFileData) => resizedFileData?.filename as string,\n ),\n )\n }\n\n // Collect new filenames (main + sizes) so we don't delete a\n // file that the new upload reused (e.g. same filename on reupload\n // where Payload overwrites in place).\n const newFilenames = new Set<string>()\n if (typeof docWithMetadata.filename === 'string') {\n newFilenames.add(docWithMetadata.filename)\n }\n if (typeof docWithMetadata.sizes === 'object') {\n for (const size of Object.values(docWithMetadata.sizes || {})) {\n if (size?.filename && typeof size.filename === 'string') {\n newFilenames.add(size.filename)\n }\n }\n }\n\n const deletionPromises = filesToDelete.map(async (filename) => {\n if (filename && !newFilenames.has(filename)) {\n await adapter.handleDelete({ collection, doc: previousDoc, filename, req })\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":["getIncomingFiles","getAfterChangeHook","adapter","collection","doc","operation","previousDoc","req","context","skipCloudStorage","isDraftSave","_status","isDraftOverPublished","files","data","length","uploadResults","Promise","all","filter","file","directUpload","map","handleUpload","uploadMetadata","result","reduce","acc","metadata","docWithMetadata","Object","keys","undefined","payloadUploadSizes","payload","update","id","slug","depth","draft","filesToDelete","filename","push","sizes","concat","values","resizedFileData","newFilenames","Set","add","size","deletionPromises","has","handleDelete","err","logger","error"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEnE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEnE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED,eAAO,MAAM,kBAAkB,6BAG5B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,GAAG,cAAc,CAyBzE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"afterRead.d.ts","sourceRoot":"","sources":["../../src/hooks/afterRead.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEpE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"afterRead.d.ts","sourceRoot":"","sources":["../../src/hooks/afterRead.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEpE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,eAAO,MAAM,gBAAgB,gFACmD,IAAI,KAAG,SA4BpF,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beforeChange.d.ts","sourceRoot":"","sources":["../../src/hooks/beforeChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEpE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"beforeChange.d.ts","sourceRoot":"","sources":["../../src/hooks/beforeChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAEpE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,eAAO,MAAM,mBAAmB,gFACgD,IAAI,KAAG,SA2BpF,CAAA"}
|
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,
|
|
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;AAgBnE,eAAO,MAAM,kBAAkB,kBACb,aAAa,sBACZ,MAAM,KAAG,MA4NzB,CAAA"}
|
package/dist/plugin.js
CHANGED
|
@@ -47,6 +47,7 @@ export const cloudStoragePlugin = (pluginOptions)=>(incomingConfig)=>{
|
|
|
47
47
|
return config;
|
|
48
48
|
}
|
|
49
49
|
const initFunctions = [];
|
|
50
|
+
const endpointPaths = new Map();
|
|
50
51
|
return {
|
|
51
52
|
...config,
|
|
52
53
|
collections: (config.collections || []).map((existingCollection)=>{
|
|
@@ -59,6 +60,37 @@ export const cloudStoragePlugin = (pluginOptions)=>(incomingConfig)=>{
|
|
|
59
60
|
if (adapter.onInit) {
|
|
60
61
|
initFunctions.push(adapter.onInit);
|
|
61
62
|
}
|
|
63
|
+
let uploadInstructions;
|
|
64
|
+
if (adapter.uploadInstructions) {
|
|
65
|
+
const { adminHandler, endpoint, ...instructions } = adapter.uploadInstructions;
|
|
66
|
+
let endpointPath = endpointPaths.get(options.adapter);
|
|
67
|
+
if (endpoint && !endpointPath) {
|
|
68
|
+
const endpointCount = config.endpoints?.filter(({ path })=>path?.startsWith(endpoint.path)).length || 0;
|
|
69
|
+
endpointPath = endpointCount ? `${endpoint.path}-${endpointCount}` : endpoint.path;
|
|
70
|
+
config.endpoints ??= [];
|
|
71
|
+
config.endpoints.push({
|
|
72
|
+
handler: endpoint.handler,
|
|
73
|
+
method: 'post',
|
|
74
|
+
path: endpointPath
|
|
75
|
+
});
|
|
76
|
+
endpointPaths.set(options.adapter, endpointPath);
|
|
77
|
+
}
|
|
78
|
+
if (adminHandler) {
|
|
79
|
+
config.admin ??= {};
|
|
80
|
+
config.admin.components ??= {};
|
|
81
|
+
config.admin.components.providers ??= [];
|
|
82
|
+
config.admin.components.providers.push({
|
|
83
|
+
clientProps: {
|
|
84
|
+
collectionSlug: existingCollection.slug,
|
|
85
|
+
endpointPath,
|
|
86
|
+
prefix: options.prefix,
|
|
87
|
+
props: adminHandler.props || {}
|
|
88
|
+
},
|
|
89
|
+
path: adminHandler.path
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
uploadInstructions = instructions;
|
|
93
|
+
}
|
|
62
94
|
const fields = getFields({
|
|
63
95
|
adapter,
|
|
64
96
|
collection: existingCollection,
|
|
@@ -72,11 +104,11 @@ export const cloudStoragePlugin = (pluginOptions)=>(incomingConfig)=>{
|
|
|
72
104
|
];
|
|
73
105
|
if (!options.disablePayloadAccessControl) {
|
|
74
106
|
handlers.push(adapter.staticHandler);
|
|
75
|
-
// Else if disablePayloadAccessControl: true and
|
|
76
|
-
// Build the "proxied" handler that
|
|
77
|
-
} else if (adapter.
|
|
107
|
+
// Else if disablePayloadAccessControl: true and upload instructions are used
|
|
108
|
+
// Build the "proxied" handler that responds only when addDataAndFileToRequest fetches the uploaded file
|
|
109
|
+
} else if (adapter.uploadInstructions) {
|
|
78
110
|
handlers.push((req, args)=>{
|
|
79
|
-
if ('
|
|
111
|
+
if ('directUpload' in args.params) {
|
|
80
112
|
return adapter.staticHandler(req, args);
|
|
81
113
|
}
|
|
82
114
|
});
|
|
@@ -141,6 +173,9 @@ export const cloudStoragePlugin = (pluginOptions)=>(incomingConfig)=>{
|
|
|
141
173
|
upload: {
|
|
142
174
|
...typeof existingCollection.upload === 'object' ? existingCollection.upload : {},
|
|
143
175
|
adapter: adapter.name,
|
|
176
|
+
...uploadInstructions && {
|
|
177
|
+
uploadInstructions
|
|
178
|
+
},
|
|
144
179
|
disableLocalStorage: typeof options.disableLocalStorage === 'boolean' ? options.disableLocalStorage : true,
|
|
145
180
|
handlers,
|
|
146
181
|
skipSafeFetch: getSkipSafeFetchSetting()
|
|
@@ -149,6 +184,12 @@ export const cloudStoragePlugin = (pluginOptions)=>(incomingConfig)=>{
|
|
|
149
184
|
}
|
|
150
185
|
return existingCollection;
|
|
151
186
|
}),
|
|
187
|
+
...config.admin && {
|
|
188
|
+
admin: config.admin
|
|
189
|
+
},
|
|
190
|
+
...config.endpoints && {
|
|
191
|
+
endpoints: config.endpoints
|
|
192
|
+
},
|
|
152
193
|
onInit: async (payload)=>{
|
|
153
194
|
initFunctions.forEach((fn)=>fn());
|
|
154
195
|
if (config.onInit) {
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { Config } from 'payload'\n\nimport type { 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 { getPreserveFileDataHook } from './hooks/preserveFileData.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 {\n alwaysInsertFields,\n collections: allCollectionOptions,\n enabled,\n useCompositePrefixes,\n } = pluginOptions\n const config = { ...incomingConfig }\n\n // If disabled but alwaysInsertFields is true, only insert fields without full plugin functionality\n if (enabled === false) {\n if (alwaysInsertFields) {\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 alwaysInsertFields: true,\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 return config\n }\n\n const initFunctions: Array<() => void> = []\n\n return {\n ...config,\n 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 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 // Else if disablePayloadAccessControl: true and clientUploads is used\n // Build the \"proxied\" handler that responses only when the file was requested by client upload in addDataAndFileToRequest\n } else if (adapter.clientUploads) {\n handlers.push((req, args) => {\n if ('clientUploadContext' in args.params) {\n return adapter.staticHandler(req, args)\n }\n })\n }\n\n const getSkipSafeFetchSetting = (): AllowList | boolean => {\n if (options.disablePayloadAccessControl) {\n return true\n }\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({ adapter, collection: existingCollection }),\n ],\n afterDelete: [\n ...(existingCollection.hooks?.afterDelete || []),\n getAfterDeleteHook({ adapter, collection: existingCollection }),\n ],\n beforeChange: [\n ...(existingCollection.hooks?.beforeChange || []),\n getPreserveFileDataHook(),\n ],\n },\n upload: {\n ...(typeof existingCollection.upload === 'object' ? existingCollection.upload : {}),\n adapter: adapter.name,\n disableLocalStorage:\n typeof options.disableLocalStorage === 'boolean'\n ? options.disableLocalStorage\n : true,\n handlers,\n skipSafeFetch: getSkipSafeFetchSetting(),\n },\n }\n }\n\n return existingCollection\n }),\n onInit: async (payload) => {\n initFunctions.forEach((fn) => fn())\n if (config.onInit) {\n await config.onInit(payload)\n }\n },\n }\n }\n"],"names":["getFields","getAfterChangeHook","getAfterDeleteHook","getPreserveFileDataHook","cloudStoragePlugin","pluginOptions","incomingConfig","alwaysInsertFields","collections","allCollectionOptions","enabled","useCompositePrefixes","config","map","existingCollection","options","slug","adapter","collection","prefix","undefined","fields","disablePayloadAccessControl","generateFileURL","initFunctions","onInit","push","handlers","upload","Array","isArray","staticHandler","clientUploads","req","args","params","getSkipSafeFetchSetting","isBooleanTrueSkipSafeFetch","skipSafeFetch","isAllowListSkipSafeFetch","existingSkipSafeFetch","hasExactLocalhostMatch","some","entry","entryKeys","Object","keys","length","hostname","localhostEntry","process","env","NODE_ENV","hooks","afterChange","afterDelete","beforeChange","name","disableLocalStorage","payload","forEach","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 } from './hooks/afterDelete.js'\nimport { getPreserveFileDataHook } from './hooks/preserveFileData.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 {\n alwaysInsertFields,\n collections: allCollectionOptions,\n enabled,\n useCompositePrefixes,\n } = pluginOptions\n const config = { ...incomingConfig }\n\n // If disabled but alwaysInsertFields is true, only insert fields without full plugin functionality\n if (enabled === false) {\n if (alwaysInsertFields) {\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 alwaysInsertFields: true,\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 return config\n }\n\n const initFunctions: Array<() => void> = []\n const endpointPaths = new Map<Adapter, string>()\n\n return {\n ...config,\n 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, endpoint, ...instructions } = adapter.uploadInstructions\n let endpointPath = endpointPaths.get(options.adapter)\n\n if (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 (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 uploadInstructions = instructions\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 // Else if disablePayloadAccessControl: true and upload instructions are used\n // Build the \"proxied\" handler that responds only when addDataAndFileToRequest fetches the uploaded file\n } else if (adapter.uploadInstructions) {\n handlers.push((req, args) => {\n if ('directUpload' in args.params) {\n return adapter.staticHandler(req, args)\n }\n })\n }\n\n const getSkipSafeFetchSetting = (): AllowList | boolean => {\n if (options.disablePayloadAccessControl) {\n return true\n }\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({ adapter, collection: existingCollection }),\n ],\n afterDelete: [\n ...(existingCollection.hooks?.afterDelete || []),\n getAfterDeleteHook({ adapter, collection: existingCollection }),\n ],\n beforeChange: [\n ...(existingCollection.hooks?.beforeChange || []),\n getPreserveFileDataHook(),\n ],\n },\n upload: {\n ...(typeof existingCollection.upload === 'object' ? existingCollection.upload : {}),\n adapter: adapter.name,\n ...(uploadInstructions && {\n uploadInstructions,\n }),\n disableLocalStorage:\n typeof options.disableLocalStorage === 'boolean'\n ? options.disableLocalStorage\n : true,\n handlers,\n skipSafeFetch: getSkipSafeFetchSetting(),\n },\n }\n }\n\n return existingCollection\n }),\n ...(config.admin && { admin: config.admin }),\n ...(config.endpoints && { endpoints: config.endpoints }),\n onInit: async (payload) => {\n initFunctions.forEach((fn) => fn())\n if (config.onInit) {\n await config.onInit(payload)\n }\n },\n }\n }\n"],"names":["getFields","getAfterChangeHook","getAfterDeleteHook","getPreserveFileDataHook","cloudStoragePlugin","pluginOptions","incomingConfig","alwaysInsertFields","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","handlers","upload","Array","isArray","staticHandler","req","args","params","getSkipSafeFetchSetting","isBooleanTrueSkipSafeFetch","skipSafeFetch","isAllowListSkipSafeFetch","existingSkipSafeFetch","hasExactLocalhostMatch","some","entry","entryKeys","Object","keys","hostname","localhostEntry","process","env","NODE_ENV","hooks","afterChange","afterDelete","beforeChange","name","disableLocalStorage","payload","forEach","fn"],"mappings":"AAIA,SAASA,SAAS,QAAQ,wBAAuB;AACjD,SAASC,kBAAkB,QAAQ,yBAAwB;AAC3D,SAASC,kBAAkB,QAAQ,yBAAwB;AAC3D,SAASC,uBAAuB,QAAQ,8BAA6B;AAErE,4EAA4E;AAC5E,4DAA4D;AAE5D,4FAA4F;AAC5F,iFAAiF;AACjF,qEAAqE;AAErE,0FAA0F;AAE1F,OAAO,MAAMC,qBACX,CAACC,gBACD,CAACC;QACC,MAAM,EACJC,kBAAkB,EAClBC,aAAaC,oBAAoB,EACjCC,OAAO,EACPC,oBAAoB,EACrB,GAAGN;QACJ,MAAMO,SAAS;YAAE,GAAGN,cAAc;QAAC;QAEnC,mGAAmG;QACnG,IAAII,YAAY,OAAO;YACrB,IAAIH,oBAAoB;gBACtB,OAAO;oBACL,GAAGK,MAAM;oBACTJ,aAAa,AAACI,CAAAA,OAAOJ,WAAW,IAAI,EAAE,AAAD,EAAGK,GAAG,CAAC,CAACC;wBAC3C,MAAMC,UAAUN,oBAAoB,CAACK,mBAAmBE,IAAI,CAAC;wBAE7D,IAAID,SAAS;4BACX,+CAA+C;4BAC/C,MAAME,UAAUF,QAAQE,OAAO,GAC3BF,QAAQE,OAAO,CAAC;gCACdC,YAAYJ;gCACZK,QAAQJ,QAAQI,MAAM;4BACxB,KACAC;4BAEJ,MAAMC,SAASrB,UAAU;gCACvBiB;gCACAV,oBAAoB;gCACpBW,YAAYJ;gCACZQ,6BAA6BP,QAAQO,2BAA2B;gCAChEC,iBAAiBR,QAAQQ,eAAe;gCACxCJ,QAAQJ,QAAQI,MAAM;gCACtBR;4BACF;4BAEA,OAAO;gCACL,GAAGG,kBAAkB;gCACrBO;4BACF;wBACF;wBAEA,OAAOP;oBACT;gBACF;YACF;YAEA,OAAOF;QACT;QAEA,MAAMY,gBAAmC,EAAE;QAC3C,MAAMC,gBAAgB,IAAIC;QAE1B,OAAO;YACL,GAAGd,MAAM;YACTJ,aAAa,AAACI,CAAAA,OAAOJ,WAAW,IAAI,EAAE,AAAD,EAAGK,GAAG,CAAC,CAACC;gBAC3C,MAAMC,UAAUN,oBAAoB,CAACK,mBAAmBE,IAAI,CAAC;gBAE7D,IAAID,SAASE,SAAS;oBACpB,MAAMA,UAAUF,QAAQE,OAAO,CAAC;wBAC9BC,YAAYJ;wBACZK,QAAQJ,QAAQI,MAAM;oBACxB;oBAEA,IAAIF,QAAQU,MAAM,EAAE;wBAClBH,cAAcI,IAAI,CAACX,QAAQU,MAAM;oBACnC;oBAEA,IAAIE;oBAEJ,IAAIZ,QAAQY,kBAAkB,EAAE;wBAC9B,MAAM,EAAEC,YAAY,EAAEC,QAAQ,EAAE,GAAGC,cAAc,GAAGf,QAAQY,kBAAkB;wBAC9E,IAAII,eAAeR,cAAcS,GAAG,CAACnB,QAAQE,OAAO;wBAEpD,IAAIc,YAAY,CAACE,cAAc;4BAC7B,MAAME,gBACJvB,OAAOwB,SAAS,EAAEC,OAAO,CAAC,EAAEC,IAAI,EAAE,GAAKA,MAAMC,WAAWR,SAASO,IAAI,GAAGE,UAAU;4BAEpFP,eAAeE,gBAAgB,GAAGJ,SAASO,IAAI,CAAC,CAAC,EAAEH,eAAe,GAAGJ,SAASO,IAAI;4BAClF1B,OAAOwB,SAAS,KAAK,EAAE;4BACvBxB,OAAOwB,SAAS,CAACR,IAAI,CAAC;gCACpBa,SAASV,SAASU,OAAO;gCACzBC,QAAQ;gCACRJ,MAAML;4BACR;4BACAR,cAAckB,GAAG,CAAC5B,QAAQE,OAAO,EAAEgB;wBACrC;wBAEA,IAAIH,cAAc;4BAChBlB,OAAOgC,KAAK,KAAK,CAAC;4BAClBhC,OAAOgC,KAAK,CAACC,UAAU,KAAK,CAAC;4BAC7BjC,OAAOgC,KAAK,CAACC,UAAU,CAACC,SAAS,KAAK,EAAE;4BACxClC,OAAOgC,KAAK,CAACC,UAAU,CAACC,SAAS,CAAClB,IAAI,CAAC;gCACrCmB,aAAa;oCACXC,gBAAgBlC,mBAAmBE,IAAI;oCACvCiB;oCACAd,QAAQJ,QAAQI,MAAM;oCACtB8B,OAAOnB,aAAamB,KAAK,IAAI,CAAC;gCAChC;gCACAX,MAAMR,aAAaQ,IAAI;4BACzB;wBACF;wBAEAT,qBAAqBG;oBACvB;oBAEA,MAAMX,SAASrB,UAAU;wBACvBiB;wBACAC,YAAYJ;wBACZQ,6BAA6BP,QAAQO,2BAA2B;wBAChEC,iBAAiBR,QAAQQ,eAAe;wBACxCJ,QAAQJ,QAAQI,MAAM;wBACtBR;oBACF;oBAEA,MAAMuC,WAAW;2BACX,OAAOpC,mBAAmBqC,MAAM,KAAK,YACzCC,MAAMC,OAAO,CAACvC,mBAAmBqC,MAAM,CAACD,QAAQ,IAC5CpC,mBAAmBqC,MAAM,CAACD,QAAQ,GAClC,EAAE;qBACP;oBAED,IAAI,CAACnC,QAAQO,2BAA2B,EAAE;wBACxC4B,SAAStB,IAAI,CAACX,QAAQqC,aAAa;oBACnC,6EAA6E;oBAC7E,wGAAwG;oBAC1G,OAAO,IAAIrC,QAAQY,kBAAkB,EAAE;wBACrCqB,SAAStB,IAAI,CAAC,CAAC2B,KAAKC;4BAClB,IAAI,kBAAkBA,KAAKC,MAAM,EAAE;gCACjC,OAAOxC,QAAQqC,aAAa,CAACC,KAAKC;4BACpC;wBACF;oBACF;oBAEA,MAAME,0BAA0B;wBAC9B,IAAI3C,QAAQO,2BAA2B,EAAE;4BACvC,OAAO;wBACT;wBACA,MAAMqC,6BACJ,OAAO7C,mBAAmBqC,MAAM,KAAK,YACrCrC,mBAAmBqC,MAAM,CAACS,aAAa,KAAK;wBAE9C,MAAMC,2BACJ,OAAO/C,mBAAmBqC,MAAM,KAAK,YACrCC,MAAMC,OAAO,CAACvC,mBAAmBqC,MAAM,CAACS,aAAa;wBAEvD,IAAID,4BAA4B;4BAC9B,OAAO;wBACT,OAAO,IAAIE,0BAA0B;4BACnC,MAAMC,wBACJ,OAAOhD,mBAAmBqC,MAAM,KAAK,YACrCC,MAAMC,OAAO,CAACvC,mBAAmBqC,MAAM,CAACS,aAAa,IACjD9C,mBAAmBqC,MAAM,CAACS,aAAa,GACvC,EAAE;4BAER,MAAMG,yBAAyBD,sBAAsBE,IAAI,CAAC,CAACC;gCACzD,MAAMC,YAAYC,OAAOC,IAAI,CAACH;gCAC9B,OAAOC,UAAU1B,MAAM,KAAK,KAAKyB,MAAMI,QAAQ,KAAK;4BACtD;4BAEA,MAAMC,iBACJC,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBAAgB,CAACV,yBACtC;gCAAC;oCAAEM,UAAU;gCAAY;6BAAE,GAC3B,EAAE;4BAER,OAAO;mCAAIP;mCAA0BQ;6BAAe;wBACtD;wBAEA,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;4BACzC,OAAO;gCAAC;oCAAEJ,UAAU;gCAAY;6BAAE;wBACpC;wBAEA,OAAO;oBACT;oBAEA,OAAO;wBACL,GAAGvD,kBAAkB;wBACrBO;wBACAqD,OAAO;4BACL,GAAI5D,mBAAmB4D,KAAK,IAAI,CAAC,CAAC;4BAClCC,aAAa;mCACP7D,mBAAmB4D,KAAK,EAAEC,eAAe,EAAE;gCAC/C1E,mBAAmB;oCAAEgB;oCAASC,YAAYJ;gCAAmB;6BAC9D;4BACD8D,aAAa;mCACP9D,mBAAmB4D,KAAK,EAAEE,eAAe,EAAE;gCAC/C1E,mBAAmB;oCAAEe;oCAASC,YAAYJ;gCAAmB;6BAC9D;4BACD+D,cAAc;mCACR/D,mBAAmB4D,KAAK,EAAEG,gBAAgB,EAAE;gCAChD1E;6BACD;wBACH;wBACAgD,QAAQ;4BACN,GAAI,OAAOrC,mBAAmBqC,MAAM,KAAK,WAAWrC,mBAAmBqC,MAAM,GAAG,CAAC,CAAC;4BAClFlC,SAASA,QAAQ6D,IAAI;4BACrB,GAAIjD,sBAAsB;gCACxBA;4BACF,CAAC;4BACDkD,qBACE,OAAOhE,QAAQgE,mBAAmB,KAAK,YACnChE,QAAQgE,mBAAmB,GAC3B;4BACN7B;4BACAU,eAAeF;wBACjB;oBACF;gBACF;gBAEA,OAAO5C;YACT;YACA,GAAIF,OAAOgC,KAAK,IAAI;gBAAEA,OAAOhC,OAAOgC,KAAK;YAAC,CAAC;YAC3C,GAAIhC,OAAOwB,SAAS,IAAI;gBAAEA,WAAWxB,OAAOwB,SAAS;YAAC,CAAC;YACvDT,QAAQ,OAAOqD;gBACbxD,cAAcyD,OAAO,CAAC,CAACC,KAAOA;gBAC9B,IAAItE,OAAOe,MAAM,EAAE;oBACjB,MAAMf,OAAOe,MAAM,CAACqD;gBACtB;YACF;QACF;IACF,EAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import type { CollectionConfig, Field, FileData, ImageSize, PayloadRequest, TypeWithID, UploadCollectionSlug } from 'payload';
|
|
1
|
+
import type { CollectionConfig, Field, FileData, ImageSize, PayloadHandler, PayloadRequest, TypeWithID, UploadCollectionSlug, UploadInstructionsAccess, UploadInstructionsCapability } from 'payload';
|
|
2
2
|
export interface File {
|
|
3
3
|
buffer: Buffer;
|
|
4
|
-
|
|
4
|
+
directUpload?: unknown;
|
|
5
5
|
filename: string;
|
|
6
6
|
filesize: number;
|
|
7
7
|
mimeType: string;
|
|
8
8
|
tempFilePath?: string;
|
|
9
9
|
}
|
|
10
|
-
export type ClientUploadsAccess = (args: {
|
|
11
|
-
collectionSlug: UploadCollectionSlug;
|
|
12
|
-
req: PayloadRequest;
|
|
13
|
-
}) => boolean | Promise<boolean>;
|
|
14
10
|
export type ClientUploadsConfig = {
|
|
15
|
-
access?:
|
|
11
|
+
access?: UploadInstructionsAccess;
|
|
16
12
|
} | boolean;
|
|
17
13
|
export type HandleUpload = (args: {
|
|
18
|
-
clientUploadContext: unknown;
|
|
19
14
|
collection: CollectionConfig;
|
|
20
15
|
data: any;
|
|
21
16
|
file: File;
|
|
@@ -40,14 +35,13 @@ export type StaticHandler = (req: PayloadRequest, args: {
|
|
|
40
35
|
doc?: TypeWithID;
|
|
41
36
|
headers?: Headers;
|
|
42
37
|
params: {
|
|
43
|
-
clientUploadContext?: unknown;
|
|
44
38
|
collection: string;
|
|
39
|
+
directUpload?: unknown;
|
|
45
40
|
filename: string;
|
|
46
41
|
prefix?: string;
|
|
47
42
|
};
|
|
48
43
|
}) => Promise<Response> | Response;
|
|
49
44
|
export interface GeneratedAdapter {
|
|
50
|
-
clientUploads?: ClientUploadsConfig;
|
|
51
45
|
/**
|
|
52
46
|
* Additional fields to be injected into the base collection and image sizes
|
|
53
47
|
*/
|
|
@@ -61,6 +55,17 @@ export interface GeneratedAdapter {
|
|
|
61
55
|
name: string;
|
|
62
56
|
onInit?: () => void;
|
|
63
57
|
staticHandler: StaticHandler;
|
|
58
|
+
/** Generates instructions for direct uploads when supported. */
|
|
59
|
+
uploadInstructions?: {
|
|
60
|
+
adminHandler?: {
|
|
61
|
+
path: string;
|
|
62
|
+
props?: Record<string, unknown>;
|
|
63
|
+
};
|
|
64
|
+
endpoint?: {
|
|
65
|
+
handler: PayloadHandler;
|
|
66
|
+
path: `/${string}`;
|
|
67
|
+
};
|
|
68
|
+
} & UploadInstructionsCapability;
|
|
64
69
|
}
|
|
65
70
|
export type Adapter = (args: {
|
|
66
71
|
collection: CollectionConfig;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,KAAK,EACL,QAAQ,EACR,SAAS,EACT,cAAc,EACd,UAAU,EACV,oBAAoB,
|
|
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 ImageSize,\n PayloadRequest,\n TypeWithID,\n UploadCollectionSlug,\n} from 'payload'\n\nexport interface File {\n buffer: Buffer\n
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type {\n CollectionConfig,\n Field,\n FileData,\n ImageSize,\n PayloadHandler,\n PayloadRequest,\n TypeWithID,\n UploadCollectionSlug,\n UploadInstructionsAccess,\n UploadInstructionsCapability,\n} from 'payload'\n\nexport interface File {\n buffer: Buffer\n directUpload?: unknown\n filename: string\n filesize: number\n mimeType: string\n tempFilePath?: string\n}\n\nexport type ClientUploadsConfig = { access?: UploadInstructionsAccess } | boolean\n\nexport type HandleUpload = (args: {\n collection: CollectionConfig\n data: any\n file: File\n req: PayloadRequest\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}) => Promise<void> | 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: { collection: string; directUpload?: unknown; filename: string; prefix?: string }\n },\n) => Promise<Response> | Response\n\nexport interface GeneratedAdapter {\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 name: string\n onInit?: () => void\n staticHandler: StaticHandler\n /** Generates instructions for direct uploads when supported. */\n uploadInstructions?: {\n adminHandler?: {\n path: string\n props?: Record<string, unknown>\n }\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 /**\n * When enabled, fields (like the prefix field) will always be inserted into\n * the collection schema regardless of whether the plugin is enabled. This\n * ensures a consistent schema across all environments.\n *\n * This will be enabled by default in Payload v4.\n *\n * @default false\n */\n alwaysInsertFields?: boolean\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":"AAkHA,WA4BC"}
|
|
@@ -5,14 +5,14 @@ import type { CollectionConfig, PayloadRequest } from 'payload';
|
|
|
5
5
|
*
|
|
6
6
|
* Resolution order:
|
|
7
7
|
* 1. `prefixQueryParam`
|
|
8
|
-
* 2. `
|
|
8
|
+
* 2. `directUpload.prefix`
|
|
9
9
|
* 3. Stored document `prefix` from the database
|
|
10
10
|
*
|
|
11
11
|
* Resolved values are passed through `sanitizePrefix`.
|
|
12
12
|
*/
|
|
13
|
-
export declare function getFilePrefix({
|
|
14
|
-
clientUploadContext?: unknown;
|
|
13
|
+
export declare function getFilePrefix({ collection, directUpload, filename, prefixQueryParam, req, }: {
|
|
15
14
|
collection: CollectionConfig;
|
|
15
|
+
directUpload?: unknown;
|
|
16
16
|
filename: string;
|
|
17
17
|
prefixQueryParam?: string;
|
|
18
18
|
req: PayloadRequest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFilePrefix.d.ts","sourceRoot":"","sources":["../../src/utilities/getFilePrefix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAgB,MAAM,SAAS,CAAA;AAI7E;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,EAClC,
|
|
1
|
+
{"version":3,"file":"getFilePrefix.d.ts","sourceRoot":"","sources":["../../src/utilities/getFilePrefix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAgB,MAAM,SAAS,CAAA;AAI7E;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,EAClC,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,GAAG,GACJ,EAAE;IACD,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,GAAG,EAAE,cAAc,CAAA;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoClB"}
|
|
@@ -5,17 +5,17 @@ import { sanitizePrefix } from './sanitizePrefix.js';
|
|
|
5
5
|
*
|
|
6
6
|
* Resolution order:
|
|
7
7
|
* 1. `prefixQueryParam`
|
|
8
|
-
* 2. `
|
|
8
|
+
* 2. `directUpload.prefix`
|
|
9
9
|
* 3. Stored document `prefix` from the database
|
|
10
10
|
*
|
|
11
11
|
* Resolved values are passed through `sanitizePrefix`.
|
|
12
|
-
*/ export async function getFilePrefix({
|
|
12
|
+
*/ export async function getFilePrefix({ collection, directUpload, filename, prefixQueryParam, req }) {
|
|
13
13
|
if (typeof prefixQueryParam === 'string') {
|
|
14
14
|
return sanitizePrefix(prefixQueryParam);
|
|
15
15
|
}
|
|
16
|
-
// Prioritize
|
|
17
|
-
if (
|
|
18
|
-
return sanitizePrefix(
|
|
16
|
+
// Prioritize the direct upload prefix if there is one.
|
|
17
|
+
if (directUpload && typeof directUpload === 'object' && 'prefix' in directUpload && typeof directUpload.prefix === 'string') {
|
|
18
|
+
return sanitizePrefix(directUpload.prefix);
|
|
19
19
|
}
|
|
20
20
|
const imageSizes = collection?.upload?.imageSizes || [];
|
|
21
21
|
const files = await req.payload.find({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getFilePrefix.ts"],"sourcesContent":["import type { CollectionConfig, PayloadRequest, UploadConfig } from 'payload'\n\nimport { sanitizePrefix } from './sanitizePrefix.js'\n\n/**\n * Resolves the file prefix from the highest-priority available source and\n * always returns a sanitized value.\n *\n * Resolution order:\n * 1. `prefixQueryParam`\n * 2. `
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getFilePrefix.ts"],"sourcesContent":["import type { CollectionConfig, PayloadRequest, UploadConfig } from 'payload'\n\nimport { sanitizePrefix } from './sanitizePrefix.js'\n\n/**\n * Resolves the file prefix from the highest-priority available source and\n * always returns a sanitized value.\n *\n * Resolution order:\n * 1. `prefixQueryParam`\n * 2. `directUpload.prefix`\n * 3. Stored document `prefix` from the database\n *\n * Resolved values are passed through `sanitizePrefix`.\n */\nexport async function getFilePrefix({\n collection,\n directUpload,\n filename,\n prefixQueryParam,\n req,\n}: {\n collection: CollectionConfig\n directUpload?: unknown\n filename: string\n prefixQueryParam?: string\n req: PayloadRequest\n}): Promise<string> {\n if (typeof prefixQueryParam === 'string') {\n return sanitizePrefix(prefixQueryParam)\n }\n\n // Prioritize the direct upload prefix if there is one.\n if (\n directUpload &&\n typeof directUpload === 'object' &&\n 'prefix' in directUpload &&\n typeof directUpload.prefix === 'string'\n ) {\n return sanitizePrefix(directUpload.prefix)\n }\n\n const imageSizes = (collection?.upload as UploadConfig)?.imageSizes || []\n\n const files = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n draft: true,\n limit: 1,\n pagination: false,\n where: {\n or: [\n {\n filename: { equals: filename },\n },\n ...imageSizes.map((imageSize) => ({\n [`sizes.${imageSize.name}.filename`]: { equals: filename },\n })),\n ],\n },\n })\n const prefix = files?.docs?.[0]?.prefix\n return prefix ? sanitizePrefix(prefix as string) : ''\n}\n"],"names":["sanitizePrefix","getFilePrefix","collection","directUpload","filename","prefixQueryParam","req","prefix","imageSizes","upload","files","payload","find","slug","depth","draft","limit","pagination","where","or","equals","map","imageSize","name","docs"],"mappings":"AAEA,SAASA,cAAc,QAAQ,sBAAqB;AAEpD;;;;;;;;;;CAUC,GACD,OAAO,eAAeC,cAAc,EAClCC,UAAU,EACVC,YAAY,EACZC,QAAQ,EACRC,gBAAgB,EAChBC,GAAG,EAOJ;IACC,IAAI,OAAOD,qBAAqB,UAAU;QACxC,OAAOL,eAAeK;IACxB;IAEA,uDAAuD;IACvD,IACEF,gBACA,OAAOA,iBAAiB,YACxB,YAAYA,gBACZ,OAAOA,aAAaI,MAAM,KAAK,UAC/B;QACA,OAAOP,eAAeG,aAAaI,MAAM;IAC3C;IAEA,MAAMC,aAAa,AAACN,YAAYO,QAAyBD,cAAc,EAAE;IAEzE,MAAME,QAAQ,MAAMJ,IAAIK,OAAO,CAACC,IAAI,CAAC;QACnCV,YAAYA,WAAWW,IAAI;QAC3BC,OAAO;QACPC,OAAO;QACPC,OAAO;QACPC,YAAY;QACZC,OAAO;YACLC,IAAI;gBACF;oBACEf,UAAU;wBAAEgB,QAAQhB;oBAAS;gBAC/B;mBACGI,WAAWa,GAAG,CAAC,CAACC,YAAe,CAAA;wBAChC,CAAC,CAAC,MAAM,EAAEA,UAAUC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE;4BAAEH,QAAQhB;wBAAS;oBAC3D,CAAA;aACD;QACH;IACF;IACA,MAAMG,SAASG,OAAOc,MAAM,CAAC,EAAE,EAAEjB;IACjC,OAAOA,SAASP,eAAeO,UAAoB;AACrD"}
|
|
@@ -82,17 +82,17 @@ describe('getFilePrefix', ()=>{
|
|
|
82
82
|
});
|
|
83
83
|
expect(result).toBe('');
|
|
84
84
|
});
|
|
85
|
-
it('should prioritize
|
|
85
|
+
it('should prioritize the direct upload prefix over the database query', async ()=>{
|
|
86
86
|
const req = makeReq([
|
|
87
87
|
{
|
|
88
88
|
prefix: 'db-prefix'
|
|
89
89
|
}
|
|
90
90
|
]);
|
|
91
91
|
const result = await getFilePrefix({
|
|
92
|
-
|
|
92
|
+
collection: makeCollection(),
|
|
93
|
+
directUpload: {
|
|
93
94
|
prefix: 'context-prefix'
|
|
94
95
|
},
|
|
95
|
-
collection: makeCollection(),
|
|
96
96
|
filename: 'logo.png',
|
|
97
97
|
req
|
|
98
98
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getFilePrefix.spec.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest'\n\nimport type { CollectionConfig, PayloadRequest } from 'payload'\n\nimport { getFilePrefix } from './getFilePrefix.js'\n\nconst makeReq = (docs: unknown[] = []) =>\n ({\n payload: {\n find: vi.fn().mockResolvedValue({ docs }),\n },\n }) as unknown as PayloadRequest\n\nconst makeCollection = (): CollectionConfig =>\n ({ slug: 'media', upload: {} }) as unknown as CollectionConfig\n\ndescribe('getFilePrefix', () => {\n describe('prefixQueryParam shortcut', () => {\n it('should return prefixQueryParam immediately without querying the database', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: 'uuid-prefix',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('uuid-prefix')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('should return an empty string when prefixQueryParam is an empty string', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: '',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('should reject multi-encoded values', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: '%252e%252e%252fsecret%252f..%252fok',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('should reject malformed percent-encoding', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: '%E0%A4%A',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n })\n\n describe('database fallback', () => {\n it('should query the database when prefixQueryParam is not provided', async () => {\n const req = makeReq([{ prefix: 'db-prefix' }])\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('db-prefix')\n expect(req.payload.find).toHaveBeenCalledOnce()\n })\n\n it('should return empty string when no document is found', async () => {\n const req = makeReq([])\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n })\n\n it('should prioritize
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getFilePrefix.spec.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest'\n\nimport type { CollectionConfig, PayloadRequest } from 'payload'\n\nimport { getFilePrefix } from './getFilePrefix.js'\n\nconst makeReq = (docs: unknown[] = []) =>\n ({\n payload: {\n find: vi.fn().mockResolvedValue({ docs }),\n },\n }) as unknown as PayloadRequest\n\nconst makeCollection = (): CollectionConfig =>\n ({ slug: 'media', upload: {} }) as unknown as CollectionConfig\n\ndescribe('getFilePrefix', () => {\n describe('prefixQueryParam shortcut', () => {\n it('should return prefixQueryParam immediately without querying the database', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: 'uuid-prefix',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('uuid-prefix')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('should return an empty string when prefixQueryParam is an empty string', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: '',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('should reject multi-encoded values', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: '%252e%252e%252fsecret%252f..%252fok',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('should reject malformed percent-encoding', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n prefixQueryParam: '%E0%A4%A',\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n })\n\n describe('database fallback', () => {\n it('should query the database when prefixQueryParam is not provided', async () => {\n const req = makeReq([{ prefix: 'db-prefix' }])\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('db-prefix')\n expect(req.payload.find).toHaveBeenCalledOnce()\n })\n\n it('should return empty string when no document is found', async () => {\n const req = makeReq([])\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n })\n\n it('should prioritize the direct upload prefix over the database query', async () => {\n const req = makeReq([{ prefix: 'db-prefix' }])\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n directUpload: { prefix: 'context-prefix' },\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('context-prefix')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n })\n})\n"],"names":["describe","expect","it","vi","getFilePrefix","makeReq","docs","payload","find","fn","mockResolvedValue","makeCollection","slug","upload","req","result","collection","prefixQueryParam","filename","toBe","not","toHaveBeenCalled","prefix","toHaveBeenCalledOnce","directUpload"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAIjD,SAASC,aAAa,QAAQ,qBAAoB;AAElD,MAAMC,UAAU,CAACC,OAAkB,EAAE,GAClC,CAAA;QACCC,SAAS;YACPC,MAAML,GAAGM,EAAE,GAAGC,iBAAiB,CAAC;gBAAEJ;YAAK;QACzC;IACF,CAAA;AAEF,MAAMK,iBAAiB,IACpB,CAAA;QAAEC,MAAM;QAASC,QAAQ,CAAC;IAAE,CAAA;AAE/Bb,SAAS,iBAAiB;IACxBA,SAAS,6BAA6B;QACpCE,GAAG,4EAA4E;YAC7E,MAAMY,MAAMT;YAEZ,MAAMU,SAAS,MAAMX,cAAc;gBACjCY,YAAYL;gBACZM,kBAAkB;gBAClBC,UAAU;gBACVJ;YACF;YAEAb,OAAOc,QAAQI,IAAI,CAAC;YACpBlB,OAAOa,IAAIP,OAAO,CAACC,IAAI,EAAEY,GAAG,CAACC,gBAAgB;QAC/C;QAEAnB,GAAG,0EAA0E;YAC3E,MAAMY,MAAMT;YAEZ,MAAMU,SAAS,MAAMX,cAAc;gBACjCY,YAAYL;gBACZM,kBAAkB;gBAClBC,UAAU;gBACVJ;YACF;YAEAb,OAAOc,QAAQI,IAAI,CAAC;YACpBlB,OAAOa,IAAIP,OAAO,CAACC,IAAI,EAAEY,GAAG,CAACC,gBAAgB;QAC/C;QAEAnB,GAAG,sCAAsC;YACvC,MAAMY,MAAMT;YAEZ,MAAMU,SAAS,MAAMX,cAAc;gBACjCY,YAAYL;gBACZM,kBAAkB;gBAClBC,UAAU;gBACVJ;YACF;YAEAb,OAAOc,QAAQI,IAAI,CAAC;YACpBlB,OAAOa,IAAIP,OAAO,CAACC,IAAI,EAAEY,GAAG,CAACC,gBAAgB;QAC/C;QAEAnB,GAAG,4CAA4C;YAC7C,MAAMY,MAAMT;YAEZ,MAAMU,SAAS,MAAMX,cAAc;gBACjCY,YAAYL;gBACZM,kBAAkB;gBAClBC,UAAU;gBACVJ;YACF;YAEAb,OAAOc,QAAQI,IAAI,CAAC;YACpBlB,OAAOa,IAAIP,OAAO,CAACC,IAAI,EAAEY,GAAG,CAACC,gBAAgB;QAC/C;IACF;IAEArB,SAAS,qBAAqB;QAC5BE,GAAG,mEAAmE;YACpE,MAAMY,MAAMT,QAAQ;gBAAC;oBAAEiB,QAAQ;gBAAY;aAAE;YAE7C,MAAMP,SAAS,MAAMX,cAAc;gBACjCY,YAAYL;gBACZO,UAAU;gBACVJ;YACF;YAEAb,OAAOc,QAAQI,IAAI,CAAC;YACpBlB,OAAOa,IAAIP,OAAO,CAACC,IAAI,EAAEe,oBAAoB;QAC/C;QAEArB,GAAG,wDAAwD;YACzD,MAAMY,MAAMT,QAAQ,EAAE;YAEtB,MAAMU,SAAS,MAAMX,cAAc;gBACjCY,YAAYL;gBACZO,UAAU;gBACVJ;YACF;YAEAb,OAAOc,QAAQI,IAAI,CAAC;QACtB;QAEAjB,GAAG,sEAAsE;YACvE,MAAMY,MAAMT,QAAQ;gBAAC;oBAAEiB,QAAQ;gBAAY;aAAE;YAE7C,MAAMP,SAAS,MAAMX,cAAc;gBACjCY,YAAYL;gBACZa,cAAc;oBAAEF,QAAQ;gBAAiB;gBACzCJ,UAAU;gBACVJ;YACF;YAEAb,OAAOc,QAAQI,IAAI,CAAC;YACpBlB,OAAOa,IAAIP,OAAO,CAACC,IAAI,EAAEY,GAAG,CAACC,gBAAgB;QAC/C;IACF;AACF"}
|
|
@@ -7,7 +7,7 @@ export function getIncomingFiles({ data, req }) {
|
|
|
7
7
|
if (file && data.filename && data.mimeType) {
|
|
8
8
|
const mainFile = {
|
|
9
9
|
buffer: file.data,
|
|
10
|
-
|
|
10
|
+
directUpload: file.directUpload,
|
|
11
11
|
filename: data.filename,
|
|
12
12
|
filesize: file.size,
|
|
13
13
|
mimeType: data.mimeType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/getIncomingFiles.ts"],"sourcesContent":["import type { FileData, PayloadRequest } from 'payload'\n\nimport type { File } from '../types.js'\n\ninterface CloudStorageContext {\n file: PayloadRequest['file']\n uploadSizes: PayloadRequest['payloadUploadSizes']\n}\n\nexport function getIncomingFiles({\n data,\n req,\n}: {\n data: Partial<FileData>\n req: PayloadRequest\n}): File[] {\n // Fall back to context if req.file was cleared\n const ctx = req.context?._payloadCloudStorage as CloudStorageContext | undefined\n const file = req.file ?? ctx?.file\n const payloadUploadSizes = req.payloadUploadSizes ?? ctx?.uploadSizes\n\n let files: File[] = []\n\n if (file && data.filename && data.mimeType) {\n const mainFile: File = {\n buffer: file.data,\n
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/getIncomingFiles.ts"],"sourcesContent":["import type { FileData, PayloadRequest } from 'payload'\n\nimport type { File } from '../types.js'\n\ninterface CloudStorageContext {\n file: PayloadRequest['file']\n uploadSizes: PayloadRequest['payloadUploadSizes']\n}\n\nexport function getIncomingFiles({\n data,\n req,\n}: {\n data: Partial<FileData>\n req: PayloadRequest\n}): File[] {\n // Fall back to context if req.file was cleared\n const ctx = req.context?._payloadCloudStorage as CloudStorageContext | undefined\n const file = req.file ?? ctx?.file\n const payloadUploadSizes = req.payloadUploadSizes ?? ctx?.uploadSizes\n\n let files: File[] = []\n\n if (file && data.filename && data.mimeType) {\n const mainFile: File = {\n buffer: file.data,\n directUpload: file.directUpload,\n filename: data.filename,\n filesize: file.size,\n mimeType: data.mimeType,\n tempFilePath: file.tempFilePath,\n }\n\n files = [mainFile]\n\n if (data?.sizes) {\n Object.entries(data.sizes).forEach(([key, resizedFileData]) => {\n if (payloadUploadSizes?.[key] && resizedFileData.mimeType) {\n files = files.concat([\n {\n buffer: payloadUploadSizes[key],\n filename: `${resizedFileData.filename}`,\n filesize: payloadUploadSizes[key].length,\n mimeType: resizedFileData.mimeType,\n },\n ])\n }\n })\n }\n }\n\n return files\n}\n"],"names":["getIncomingFiles","data","req","ctx","context","_payloadCloudStorage","file","payloadUploadSizes","uploadSizes","files","filename","mimeType","mainFile","buffer","directUpload","filesize","size","tempFilePath","sizes","Object","entries","forEach","key","resizedFileData","concat","length"],"mappings":"AASA,OAAO,SAASA,iBAAiB,EAC/BC,IAAI,EACJC,GAAG,EAIJ;IACC,+CAA+C;IAC/C,MAAMC,MAAMD,IAAIE,OAAO,EAAEC;IACzB,MAAMC,OAAOJ,IAAII,IAAI,IAAIH,KAAKG;IAC9B,MAAMC,qBAAqBL,IAAIK,kBAAkB,IAAIJ,KAAKK;IAE1D,IAAIC,QAAgB,EAAE;IAEtB,IAAIH,QAAQL,KAAKS,QAAQ,IAAIT,KAAKU,QAAQ,EAAE;QAC1C,MAAMC,WAAiB;YACrBC,QAAQP,KAAKL,IAAI;YACjBa,cAAcR,KAAKQ,YAAY;YAC/BJ,UAAUT,KAAKS,QAAQ;YACvBK,UAAUT,KAAKU,IAAI;YACnBL,UAAUV,KAAKU,QAAQ;YACvBM,cAAcX,KAAKW,YAAY;QACjC;QAEAR,QAAQ;YAACG;SAAS;QAElB,IAAIX,MAAMiB,OAAO;YACfC,OAAOC,OAAO,CAACnB,KAAKiB,KAAK,EAAEG,OAAO,CAAC,CAAC,CAACC,KAAKC,gBAAgB;gBACxD,IAAIhB,oBAAoB,CAACe,IAAI,IAAIC,gBAAgBZ,QAAQ,EAAE;oBACzDF,QAAQA,MAAMe,MAAM,CAAC;wBACnB;4BACEX,QAAQN,kBAAkB,CAACe,IAAI;4BAC/BZ,UAAU,GAAGa,gBAAgBb,QAAQ,EAAE;4BACvCK,UAAUR,kBAAkB,CAACe,IAAI,CAACG,MAAM;4BACxCd,UAAUY,gBAAgBZ,QAAQ;wBACpC;qBACD;gBACH;YACF;QACF;IACF;IAEA,OAAOF;AACT"}
|
|
@@ -8,7 +8,7 @@ type Args = {
|
|
|
8
8
|
useCompositePrefixes?: boolean;
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
* Resolves the storage key for
|
|
11
|
+
* Resolves the storage key for an upload-instructions request, deduping
|
|
12
12
|
* the filename via {@link getSafeFileName} so a duplicate upload does not
|
|
13
13
|
* overwrite an existing blob.
|
|
14
14
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getSafeFileName } from 'payload/internal';
|
|
2
2
|
import { getFileKey } from './getFileKey.js';
|
|
3
3
|
/**
|
|
4
|
-
* Resolves the storage key for
|
|
4
|
+
* Resolves the storage key for an upload-instructions request, deduping
|
|
5
5
|
* the filename via {@link getSafeFileName} so a duplicate upload does not
|
|
6
6
|
* overwrite an existing blob.
|
|
7
7
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/resolveSignedURLKey.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { getSafeFileName } from 'payload/internal'\n\nimport { getFileKey } from './getFileKey.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
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/resolveSignedURLKey.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { getSafeFileName } from 'payload/internal'\n\nimport { getFileKey } from './getFileKey.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 * The resolved `sanitizedFilename` is returned so the browser-side handler\n * can update the form via `updateFilename`.\n */\nexport async function resolveSignedURLKey({\n collectionPrefix = '',\n collectionSlug,\n docPrefix,\n filename,\n req,\n useCompositePrefixes = false,\n}: Args) {\n const sanitizedFilename = await getSafeFileName({\n collectionSlug,\n desiredFilename: filename,\n prefix: docPrefix,\n req,\n })\n\n const { fileKey, sanitizedDocPrefix } = getFileKey({\n collectionPrefix,\n docPrefix,\n filename: sanitizedFilename,\n useCompositePrefixes,\n })\n\n return { fileKey, sanitizedDocPrefix, sanitizedFilename }\n}\n"],"names":["getSafeFileName","getFileKey","resolveSignedURLKey","collectionPrefix","collectionSlug","docPrefix","filename","req","useCompositePrefixes","sanitizedFilename","desiredFilename","prefix","fileKey","sanitizedDocPrefix"],"mappings":"AAEA,SAASA,eAAe,QAAQ,mBAAkB;AAElD,SAASC,UAAU,QAAQ,kBAAiB;AAW5C;;;;;;;CAOC,GACD,OAAO,eAAeC,oBAAoB,EACxCC,mBAAmB,EAAE,EACrBC,cAAc,EACdC,SAAS,EACTC,QAAQ,EACRC,GAAG,EACHC,uBAAuB,KAAK,EACvB;IACL,MAAMC,oBAAoB,MAAMT,gBAAgB;QAC9CI;QACAM,iBAAiBJ;QACjBK,QAAQN;QACRE;IACF;IAEA,MAAM,EAAEK,OAAO,EAAEC,kBAAkB,EAAE,GAAGZ,WAAW;QACjDE;QACAE;QACAC,UAAUG;QACVD;IACF;IAEA,OAAO;QAAEI;QAASC;QAAoBJ;IAAkB;AAC1D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/plugin-cloud-storage",
|
|
3
|
-
"version": "4.0.0-internal.
|
|
3
|
+
"version": "4.0.0-internal.435b2d6",
|
|
4
4
|
"description": "The official cloud storage plugin for Payload CMS",
|
|
5
5
|
"homepage": "https://payloadcms.com",
|
|
6
6
|
"repository": {
|
|
@@ -51,18 +51,18 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"find-node-modules": "^2.1.3",
|
|
53
53
|
"range-parser": "^1.2.1",
|
|
54
|
-
"@payloadcms/ui": "4.0.0-internal.
|
|
54
|
+
"@payloadcms/ui": "4.0.0-internal.435b2d6"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/find-node-modules": "^2.1.2",
|
|
58
58
|
"@types/react": "19.2.14",
|
|
59
59
|
"@types/react-dom": "19.2.3",
|
|
60
|
-
"payload": "4.0.0-internal.
|
|
60
|
+
"payload": "4.0.0-internal.435b2d6"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"react": "^19.0.1 || ^19.1.2 || ^19.2.1",
|
|
64
64
|
"react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1",
|
|
65
|
-
"payload": "4.0.0-internal.
|
|
65
|
+
"payload": "4.0.0-internal.435b2d6"
|
|
66
66
|
},
|
|
67
67
|
"publishConfig": {
|
|
68
68
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Config, PayloadHandler } from 'payload';
|
|
2
|
-
export declare const initClientUploads: <ExtraProps extends Record<string, unknown>, T>({ clientHandler, collections, config, enabled, extraClientHandlerProps, serverHandler, serverHandlerPath, }: {
|
|
3
|
-
/** Path to clientHandler component */
|
|
4
|
-
clientHandler: string;
|
|
5
|
-
collections: Record<string, T>;
|
|
6
|
-
config: Config;
|
|
7
|
-
enabled: boolean;
|
|
8
|
-
/** extra props to pass to the client handler */
|
|
9
|
-
extraClientHandlerProps?: (collection: T) => ExtraProps;
|
|
10
|
-
serverHandler: PayloadHandler;
|
|
11
|
-
serverHandlerPath: string;
|
|
12
|
-
}) => void;
|
|
13
|
-
//# sourceMappingURL=initClientUploads.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"initClientUploads.d.ts","sourceRoot":"","sources":["../../src/utilities/initClientUploads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAErD,eAAO,MAAM,iBAAiB,GAAI,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,6GAQ9E;IACD,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,gDAAgD;IAChD,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,KAAK,UAAU,CAAA;IACvD,aAAa,EAAE,cAAc,CAAA;IAC7B,iBAAiB,EAAE,MAAM,CAAA;CAC1B,SA8EA,CAAA"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
export const initClientUploads = ({ clientHandler, collections, config, enabled, extraClientHandlerProps, serverHandler, serverHandlerPath })=>{
|
|
2
|
-
if (enabled) {
|
|
3
|
-
if (!config.endpoints) {
|
|
4
|
-
config.endpoints = [];
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Tracks how many times the same handler was already applied.
|
|
8
|
-
* This allows to apply the same plugin multiple times, for example
|
|
9
|
-
* to use different buckets for different collections.
|
|
10
|
-
*/ let handlerCount = 0;
|
|
11
|
-
for (const endpoint of config.endpoints){
|
|
12
|
-
// We want to match on 'path', 'path-1', 'path-2', etc.
|
|
13
|
-
if (endpoint.path?.startsWith(serverHandlerPath)) {
|
|
14
|
-
handlerCount++;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
if (handlerCount) {
|
|
18
|
-
serverHandlerPath = `${serverHandlerPath}-${handlerCount}`;
|
|
19
|
-
}
|
|
20
|
-
config.endpoints.push({
|
|
21
|
-
handler: serverHandler,
|
|
22
|
-
method: 'post',
|
|
23
|
-
path: serverHandlerPath
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
if (!config.admin) {
|
|
27
|
-
config.admin = {};
|
|
28
|
-
}
|
|
29
|
-
if (!config.admin.dependencies) {
|
|
30
|
-
config.admin.dependencies = {};
|
|
31
|
-
}
|
|
32
|
-
// Ensure client handler is always part of the import map, to avoid
|
|
33
|
-
// import map discrepancies between dev and prod
|
|
34
|
-
config.admin.dependencies[clientHandler] = {
|
|
35
|
-
type: 'function',
|
|
36
|
-
path: clientHandler
|
|
37
|
-
};
|
|
38
|
-
if (!config.admin.components) {
|
|
39
|
-
config.admin.components = {};
|
|
40
|
-
}
|
|
41
|
-
if (!config.admin.components.providers) {
|
|
42
|
-
config.admin.components.providers = [];
|
|
43
|
-
}
|
|
44
|
-
for(const collectionSlug in collections){
|
|
45
|
-
const collection = collections[collectionSlug];
|
|
46
|
-
let collectionPrefix;
|
|
47
|
-
if (collection && typeof collection === 'object' && 'prefix' in collection && typeof collection.prefix === 'string') {
|
|
48
|
-
collectionPrefix = collection.prefix;
|
|
49
|
-
}
|
|
50
|
-
config.admin.components.providers.push({
|
|
51
|
-
clientProps: {
|
|
52
|
-
collectionSlug,
|
|
53
|
-
enabled,
|
|
54
|
-
extra: extraClientHandlerProps ? extraClientHandlerProps(collection) : undefined,
|
|
55
|
-
prefix: collectionPrefix,
|
|
56
|
-
serverHandlerPath
|
|
57
|
-
},
|
|
58
|
-
path: clientHandler
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
//# sourceMappingURL=initClientUploads.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/initClientUploads.ts"],"sourcesContent":["import type { Config, PayloadHandler } from 'payload'\n\nexport const initClientUploads = <ExtraProps extends Record<string, unknown>, T>({\n clientHandler,\n collections,\n config,\n enabled,\n extraClientHandlerProps,\n serverHandler,\n serverHandlerPath,\n}: {\n /** Path to clientHandler component */\n clientHandler: string\n collections: Record<string, T>\n config: Config\n enabled: boolean\n /** extra props to pass to the client handler */\n extraClientHandlerProps?: (collection: T) => ExtraProps\n serverHandler: PayloadHandler\n serverHandlerPath: string\n}) => {\n if (enabled) {\n if (!config.endpoints) {\n config.endpoints = []\n }\n\n /**\n * Tracks how many times the same handler was already applied.\n * This allows to apply the same plugin multiple times, for example\n * to use different buckets for different collections.\n */\n let handlerCount = 0\n\n for (const endpoint of config.endpoints) {\n // We want to match on 'path', 'path-1', 'path-2', etc.\n if (endpoint.path?.startsWith(serverHandlerPath)) {\n handlerCount++\n }\n }\n\n if (handlerCount) {\n serverHandlerPath = `${serverHandlerPath}-${handlerCount}`\n }\n\n config.endpoints.push({\n handler: serverHandler,\n method: 'post',\n path: serverHandlerPath,\n })\n }\n\n if (!config.admin) {\n config.admin = {}\n }\n\n if (!config.admin.dependencies) {\n config.admin.dependencies = {}\n }\n // Ensure client handler is always part of the import map, to avoid\n // import map discrepancies between dev and prod\n config.admin.dependencies[clientHandler] = {\n type: 'function',\n path: clientHandler,\n }\n\n if (!config.admin.components) {\n config.admin.components = {}\n }\n\n if (!config.admin.components.providers) {\n config.admin.components.providers = []\n }\n\n for (const collectionSlug in collections) {\n const collection = collections[collectionSlug]\n\n let collectionPrefix: string | undefined\n\n if (\n collection &&\n typeof collection === 'object' &&\n 'prefix' in collection &&\n typeof collection.prefix === 'string'\n ) {\n collectionPrefix = collection.prefix\n }\n\n config.admin.components.providers.push({\n clientProps: {\n collectionSlug,\n enabled,\n extra: extraClientHandlerProps ? extraClientHandlerProps(collection!) : undefined,\n prefix: collectionPrefix,\n serverHandlerPath,\n },\n path: clientHandler,\n })\n }\n}\n"],"names":["initClientUploads","clientHandler","collections","config","enabled","extraClientHandlerProps","serverHandler","serverHandlerPath","endpoints","handlerCount","endpoint","path","startsWith","push","handler","method","admin","dependencies","type","components","providers","collectionSlug","collection","collectionPrefix","prefix","clientProps","extra","undefined"],"mappings":"AAEA,OAAO,MAAMA,oBAAoB,CAAgD,EAC/EC,aAAa,EACbC,WAAW,EACXC,MAAM,EACNC,OAAO,EACPC,uBAAuB,EACvBC,aAAa,EACbC,iBAAiB,EAWlB;IACC,IAAIH,SAAS;QACX,IAAI,CAACD,OAAOK,SAAS,EAAE;YACrBL,OAAOK,SAAS,GAAG,EAAE;QACvB;QAEA;;;;KAIC,GACD,IAAIC,eAAe;QAEnB,KAAK,MAAMC,YAAYP,OAAOK,SAAS,CAAE;YACvC,uDAAuD;YACvD,IAAIE,SAASC,IAAI,EAAEC,WAAWL,oBAAoB;gBAChDE;YACF;QACF;QAEA,IAAIA,cAAc;YAChBF,oBAAoB,GAAGA,kBAAkB,CAAC,EAAEE,cAAc;QAC5D;QAEAN,OAAOK,SAAS,CAACK,IAAI,CAAC;YACpBC,SAASR;YACTS,QAAQ;YACRJ,MAAMJ;QACR;IACF;IAEA,IAAI,CAACJ,OAAOa,KAAK,EAAE;QACjBb,OAAOa,KAAK,GAAG,CAAC;IAClB;IAEA,IAAI,CAACb,OAAOa,KAAK,CAACC,YAAY,EAAE;QAC9Bd,OAAOa,KAAK,CAACC,YAAY,GAAG,CAAC;IAC/B;IACA,mEAAmE;IACnE,gDAAgD;IAChDd,OAAOa,KAAK,CAACC,YAAY,CAAChB,cAAc,GAAG;QACzCiB,MAAM;QACNP,MAAMV;IACR;IAEA,IAAI,CAACE,OAAOa,KAAK,CAACG,UAAU,EAAE;QAC5BhB,OAAOa,KAAK,CAACG,UAAU,GAAG,CAAC;IAC7B;IAEA,IAAI,CAAChB,OAAOa,KAAK,CAACG,UAAU,CAACC,SAAS,EAAE;QACtCjB,OAAOa,KAAK,CAACG,UAAU,CAACC,SAAS,GAAG,EAAE;IACxC;IAEA,IAAK,MAAMC,kBAAkBnB,YAAa;QACxC,MAAMoB,aAAapB,WAAW,CAACmB,eAAe;QAE9C,IAAIE;QAEJ,IACED,cACA,OAAOA,eAAe,YACtB,YAAYA,cACZ,OAAOA,WAAWE,MAAM,KAAK,UAC7B;YACAD,mBAAmBD,WAAWE,MAAM;QACtC;QAEArB,OAAOa,KAAK,CAACG,UAAU,CAACC,SAAS,CAACP,IAAI,CAAC;YACrCY,aAAa;gBACXJ;gBACAjB;gBACAsB,OAAOrB,0BAA0BA,wBAAwBiB,cAAeK;gBACxEH,QAAQD;gBACRhB;YACF;YACAI,MAAMV;QACR;IACF;AACF,EAAC"}
|