@humaan/payload-storage-imagekit 2.3.1

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.
Files changed (37) hide show
  1. package/README.md +142 -0
  2. package/dist/clientUploads.d.ts +16 -0
  3. package/dist/clientUploads.js +10 -0
  4. package/dist/clientUploads.js.map +1 -0
  5. package/dist/components/BeforeDashboardClient.d.ts +1 -0
  6. package/dist/components/BeforeDashboardClient.js +40 -0
  7. package/dist/components/BeforeDashboardClient.js.map +1 -0
  8. package/dist/components/BeforeDashboardServer.d.ts +2 -0
  9. package/dist/components/BeforeDashboardServer.js +22 -0
  10. package/dist/components/BeforeDashboardServer.js.map +1 -0
  11. package/dist/components/BeforeDashboardServer.module.css +5 -0
  12. package/dist/components/ImageKitUploadHandler.d.ts +2 -0
  13. package/dist/components/ImageKitUploadHandler.js +77 -0
  14. package/dist/components/ImageKitUploadHandler.js.map +1 -0
  15. package/dist/endpoints/createImageKitUploadAuthHandler.d.ts +8 -0
  16. package/dist/endpoints/createImageKitUploadAuthHandler.js +47 -0
  17. package/dist/endpoints/createImageKitUploadAuthHandler.js.map +1 -0
  18. package/dist/endpoints/customEndpointHandler.d.ts +8 -0
  19. package/dist/endpoints/customEndpointHandler.js +26 -0
  20. package/dist/endpoints/customEndpointHandler.js.map +1 -0
  21. package/dist/exports/client.d.ts +3 -0
  22. package/dist/exports/client.js +4 -0
  23. package/dist/exports/client.js.map +1 -0
  24. package/dist/exports/rsc.d.ts +1 -0
  25. package/dist/exports/rsc.js +3 -0
  26. package/dist/exports/rsc.js.map +1 -0
  27. package/dist/getAdminThumbnailURL.d.ts +1 -0
  28. package/dist/getAdminThumbnailURL.js +22 -0
  29. package/dist/getAdminThumbnailURL.js.map +1 -0
  30. package/dist/imagekitTransforms.d.ts +15 -0
  31. package/dist/index.d.ts +17 -0
  32. package/dist/index.js +275 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/migrate.d.ts +44 -0
  35. package/dist/migrate.js +258 -0
  36. package/dist/migrate.js.map +1 -0
  37. package/package.json +102 -0
package/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # payload-storage-imagekit
2
+
3
+ ImageKit storage adapter plugin for Payload CMS uploads.
4
+
5
+ This plugin integrates `@payloadcms/plugin-cloud-storage` with ImageKit and provides:
6
+
7
+ - Uploads to ImageKit per collection
8
+ - Optional client-side uploads for Payload admin to bypass request size limits on platforms like Vercel
9
+ - Required root folder with per-collection subfolders
10
+ - Stored ImageKit references (`imagekit.fileId`, `imagekit.url`, `imagekit.thumbnailUrl`)
11
+ - `crop: false` for configured upload collections
12
+ - Admin thumbnails using ImageKit transforms (`tr=w-300,h-300`)
13
+ - Built-in thumbnail path for videos and PDFs in admin previews
14
+ - Migration utility for copying collection files between ImageKit folders
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pnpm add @humaan/payload-storage-imagekit
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```ts
25
+ import { buildConfig } from 'payload'
26
+ import { imagekitStorage } from '@humaan/payload-storage-imagekit'
27
+
28
+ export default buildConfig({
29
+ collections: [
30
+ {
31
+ slug: 'media',
32
+ upload: true,
33
+ fields: [],
34
+ },
35
+ ],
36
+ plugins: [
37
+ imagekitStorage({
38
+ clientUploads: true,
39
+ folder: '/payload-uploads',
40
+ collections: {
41
+ media: true,
42
+ },
43
+ privateKey: process.env.IMAGEKIT_PRIVATE_KEY || '',
44
+ publicKey: process.env.IMAGEKIT_PUBLIC_KEY || '',
45
+ urlEndpoint: process.env.IMAGEKIT_URL_ENDPOINT || '',
46
+ }),
47
+ ],
48
+ })
49
+ ```
50
+
51
+ ## Configuration
52
+
53
+ `imagekitStorage(options)` options:
54
+
55
+ - `collections` (required): `Partial<Record<UploadCollectionSlug, true>>`
56
+ - `folder` (required): root upload folder in ImageKit, e.g. `/payload-uploads`
57
+ - `privateKey` (required): ImageKit private API key
58
+ - `publicKey` (required): ImageKit public key
59
+ - `urlEndpoint` (required): ImageKit URL endpoint, e.g. `https://ik.imagekit.io/your_id`
60
+ - `clientUploads` (optional): when `true`, Payload admin uploads go directly from the browser to ImageKit before Payload fetches the file back for persistence and image-size generation. This helps avoid server request body limits such as Vercel's.
61
+ Duplicate filenames still follow Payload's normal safe-name behavior, so a second `pug.jpg` becomes `pug-1.jpg` instead of overwriting the first asset in ImageKit.
62
+ - `enabled` (optional): enable / disable plugin
63
+ - `alwaysInsertFields` (optional): pass-through to cloud storage plugin
64
+ - `disablePayloadAccessControl` (optional): pass-through to cloud storage plugin
65
+
66
+ ## Exports
67
+
68
+ - `imagekitStorage` (primary)
69
+ - `migrateFolder`
70
+ - `payloadStorageImagekit` (alias of `imagekitStorage`)
71
+
72
+ ## Folder Migration
73
+
74
+ Use `migrateFolder` to copy uploads from one ImageKit root folder to another (e.g. staging to production).
75
+
76
+ Behavior:
77
+
78
+ - Copies files one-by-one per collection
79
+ - Creates destination folders automatically if they do not exist
80
+ - Optional database update via Payload local API
81
+ - Dry-run is enabled by default (`dryRun: true`)
82
+ - Copies from the configured source folder path first, with stored `imagekit.url` as a fallback only when the source file cannot be found
83
+
84
+ Example:
85
+
86
+ ```ts
87
+ import { migrateFolder } from '@humaan/payload-storage-imagekit'
88
+ import config from '@payload-config'
89
+ import { getPayload } from 'payload'
90
+
91
+ const payload = await getPayload({ config })
92
+
93
+ const results = await migrateFolder({
94
+ collections: { media: true },
95
+ dryRun: true,
96
+ from: process.env.IMAGEKIT_FOLDER!,
97
+ payload,
98
+ privateKey: process.env.IMAGEKIT_PRIVATE_KEY!,
99
+ to: process.env.IMAGEKIT_FOLDER_MIGRATION_DESTINATION!,
100
+ urlEndpoint: process.env.IMAGEKIT_URL_ENDPOINT!,
101
+ })
102
+
103
+ console.log(results)
104
+ await payload.destroy()
105
+ ```
106
+
107
+ `migrateFolder(options)` options:
108
+
109
+ - `collections` (required): `Partial<Record<UploadCollectionSlug, true>>`
110
+ - `from` (required): source root folder, e.g. `/payload-uploads-staging`
111
+ - `to` (required): destination root folder, e.g. `/payload-uploads-production`
112
+ - `privateKey` (required): ImageKit private API key
113
+ - `urlEndpoint` (required): ImageKit URL endpoint
114
+ - `dryRun` (optional, default `true`): when `true`, logs what would happen without writes
115
+ - `payload` (optional): when provided and `dryRun` is `false`, updates `url` + `imagekit.*` fields
116
+
117
+ Run a migration script:
118
+
119
+ ```bash
120
+ # dry-run (default)
121
+ pnpx tsx --env-file=../.env imagekit-migration.ts
122
+
123
+ # live run
124
+ DRY_RUN=false pnpx tsx --env-file=../.env imagekit-migration.ts
125
+ ```
126
+
127
+ ## Notes
128
+
129
+ - Files are uploaded under: `<folder>/<collectionSlug>/<filename>`.
130
+ - With `clientUploads: true`, the browser uploads the original file directly to ImageKit, then Payload continues its normal document save flow using the uploaded asset.
131
+ - Deletion prefers stored `imagekit.fileId`, with path lookup fallback.
132
+ - Admin thumbnail behavior:
133
+ - Images: `<imagekit.url>?tr=w-300,h-300`
134
+ - Videos / PDFs: `<imagekit.url>/ik-thumbnail.jpg?tr=w-300,h-300`
135
+
136
+ ## Development
137
+
138
+ ```bash
139
+ pnpm dev
140
+ pnpm test:int
141
+ pnpm build
142
+ ```
@@ -0,0 +1,16 @@
1
+ export declare const imageKitUploadAuthBasePath = "/imagekit-upload-auth";
2
+ export declare const getImageKitUploadAuthPath: (collectionSlug: string) => `/${string}`;
3
+ export type ImageKitClientUploadContext = {
4
+ fileId?: string;
5
+ filePath?: string;
6
+ name?: string;
7
+ thumbnailUrl?: string;
8
+ url?: string;
9
+ };
10
+ export type ImageKitUploadHandlerProps = {
11
+ authPath: `/${string}`;
12
+ collectionSlug: string;
13
+ folder: string;
14
+ publicKey: string;
15
+ };
16
+ export declare const isImageKitClientUploadContext: (value: unknown) => value is ImageKitClientUploadContext;
@@ -0,0 +1,10 @@
1
+ export const imageKitUploadAuthBasePath = '/imagekit-upload-auth';
2
+ export const getImageKitUploadAuthPath = (collectionSlug)=>`${imageKitUploadAuthBasePath}/${collectionSlug}`;
3
+ export const isImageKitClientUploadContext = (value)=>{
4
+ if (!value || typeof value !== 'object') {
5
+ return false;
6
+ }
7
+ return 'fileId' in value || 'thumbnailUrl' in value || 'url' in value;
8
+ };
9
+
10
+ //# sourceMappingURL=clientUploads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/clientUploads.ts"],"sourcesContent":["export const imageKitUploadAuthBasePath = '/imagekit-upload-auth'\n\nexport const getImageKitUploadAuthPath = (collectionSlug: string): `/${string}` =>\n `${imageKitUploadAuthBasePath}/${collectionSlug}`\n\nexport type ImageKitClientUploadContext = {\n fileId?: string\n filePath?: string\n name?: string\n thumbnailUrl?: string\n url?: string\n}\n\nexport type ImageKitUploadHandlerProps = {\n authPath: `/${string}`\n collectionSlug: string\n folder: string\n publicKey: string\n}\n\nexport const isImageKitClientUploadContext = (\n value: unknown,\n): value is ImageKitClientUploadContext => {\n if (!value || typeof value !== 'object') {\n return false\n }\n\n return 'fileId' in value || 'thumbnailUrl' in value || 'url' in value\n}\n"],"names":["imageKitUploadAuthBasePath","getImageKitUploadAuthPath","collectionSlug","isImageKitClientUploadContext","value"],"mappings":"AAAA,OAAO,MAAMA,6BAA6B,wBAAuB;AAEjE,OAAO,MAAMC,4BAA4B,CAACC,iBACxC,GAAGF,2BAA2B,CAAC,EAAEE,gBAAgB,CAAA;AAiBnD,OAAO,MAAMC,gCAAgC,CAC3CC;IAEA,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU;QACvC,OAAO;IACT;IAEA,OAAO,YAAYA,SAAS,kBAAkBA,SAAS,SAASA;AAClE,EAAC"}
@@ -0,0 +1 @@
1
+ export declare const BeforeDashboardClient: () => import("react").JSX.Element;
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useConfig } from '@payloadcms/ui';
4
+ import { formatAdminURL } from 'payload/shared';
5
+ import { useEffect, useState } from 'react';
6
+ export const BeforeDashboardClient = ()=>{
7
+ const { config } = useConfig();
8
+ const [message, setMessage] = useState('');
9
+ useEffect(()=>{
10
+ const fetchMessage = async ()=>{
11
+ const response = await fetch(formatAdminURL({
12
+ apiRoute: config.routes.api,
13
+ path: '/my-plugin-endpoint'
14
+ }));
15
+ const result = await response.json();
16
+ setMessage(result.message);
17
+ };
18
+ void fetchMessage();
19
+ }, [
20
+ config.serverURL,
21
+ config.routes.api
22
+ ]);
23
+ return /*#__PURE__*/ _jsxs("div", {
24
+ children: [
25
+ /*#__PURE__*/ _jsx("h1", {
26
+ children: "Added by the plugin: Before Dashboard Client"
27
+ }),
28
+ /*#__PURE__*/ _jsxs("div", {
29
+ children: [
30
+ "Message from the endpoint:",
31
+ /*#__PURE__*/ _jsx("div", {
32
+ children: message || 'Loading...'
33
+ })
34
+ ]
35
+ })
36
+ ]
37
+ });
38
+ };
39
+
40
+ //# sourceMappingURL=BeforeDashboardClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/BeforeDashboardClient.tsx"],"sourcesContent":["'use client'\nimport { useConfig } from '@payloadcms/ui'\nimport { formatAdminURL } from 'payload/shared'\nimport { useEffect, useState } from 'react'\n\nexport const BeforeDashboardClient = () => {\n const { config } = useConfig()\n\n const [message, setMessage] = useState('')\n\n useEffect(() => {\n const fetchMessage = async () => {\n const response = await fetch(\n formatAdminURL({\n apiRoute: config.routes.api,\n path: '/my-plugin-endpoint',\n }),\n )\n const result = await response.json()\n setMessage(result.message)\n }\n\n void fetchMessage()\n }, [config.serverURL, config.routes.api])\n\n return (\n <div>\n <h1>Added by the plugin: Before Dashboard Client</h1>\n <div>\n Message from the endpoint:\n <div>{message || 'Loading...'}</div>\n </div>\n </div>\n )\n}\n"],"names":["useConfig","formatAdminURL","useEffect","useState","BeforeDashboardClient","config","message","setMessage","fetchMessage","response","fetch","apiRoute","routes","api","path","result","json","serverURL","div","h1"],"mappings":"AAAA;;AACA,SAASA,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAE3C,OAAO,MAAMC,wBAAwB;IACnC,MAAM,EAAEC,MAAM,EAAE,GAAGL;IAEnB,MAAM,CAACM,SAASC,WAAW,GAAGJ,SAAS;IAEvCD,UAAU;QACR,MAAMM,eAAe;YACnB,MAAMC,WAAW,MAAMC,MACrBT,eAAe;gBACbU,UAAUN,OAAOO,MAAM,CAACC,GAAG;gBAC3BC,MAAM;YACR;YAEF,MAAMC,SAAS,MAAMN,SAASO,IAAI;YAClCT,WAAWQ,OAAOT,OAAO;QAC3B;QAEA,KAAKE;IACP,GAAG;QAACH,OAAOY,SAAS;QAAEZ,OAAOO,MAAM,CAACC,GAAG;KAAC;IAExC,qBACE,MAACK;;0BACC,KAACC;0BAAG;;0BACJ,MAACD;;oBAAI;kCAEH,KAACA;kCAAKZ,WAAW;;;;;;AAIzB,EAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ServerComponentProps } from 'payload';
2
+ export declare const BeforeDashboardServer: (props: ServerComponentProps) => Promise<import("react").JSX.Element>;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import styles from './BeforeDashboardServer.module.css';
3
+ export const BeforeDashboardServer = async (props)=>{
4
+ const { payload } = props;
5
+ const { docs } = await payload.find({
6
+ collection: 'plugin-collection'
7
+ });
8
+ return /*#__PURE__*/ _jsxs("div", {
9
+ className: styles.wrapper,
10
+ children: [
11
+ /*#__PURE__*/ _jsx("h1", {
12
+ children: "Added by the plugin: Before Dashboard Server"
13
+ }),
14
+ "Docs from Local API:",
15
+ docs.map((doc)=>/*#__PURE__*/ _jsx("div", {
16
+ children: doc.id
17
+ }, doc.id))
18
+ ]
19
+ });
20
+ };
21
+
22
+ //# sourceMappingURL=BeforeDashboardServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/BeforeDashboardServer.tsx"],"sourcesContent":["import type { ServerComponentProps } from 'payload'\n\nimport styles from './BeforeDashboardServer.module.css'\n\nexport const BeforeDashboardServer = async (props: ServerComponentProps) => {\n const { payload } = props\n\n const { docs } = await payload.find({ collection: 'plugin-collection' })\n\n return (\n <div className={styles.wrapper}>\n <h1>Added by the plugin: Before Dashboard Server</h1>\n Docs from Local API:\n {docs.map((doc) => (\n <div key={doc.id}>{doc.id}</div>\n ))}\n </div>\n )\n}\n"],"names":["styles","BeforeDashboardServer","props","payload","docs","find","collection","div","className","wrapper","h1","map","doc","id"],"mappings":";AAEA,OAAOA,YAAY,qCAAoC;AAEvD,OAAO,MAAMC,wBAAwB,OAAOC;IAC1C,MAAM,EAAEC,OAAO,EAAE,GAAGD;IAEpB,MAAM,EAAEE,IAAI,EAAE,GAAG,MAAMD,QAAQE,IAAI,CAAC;QAAEC,YAAY;IAAoB;IAEtE,qBACE,MAACC;QAAIC,WAAWR,OAAOS,OAAO;;0BAC5B,KAACC;0BAAG;;YAAiD;YAEpDN,KAAKO,GAAG,CAAC,CAACC,oBACT,KAACL;8BAAkBK,IAAIC,EAAE;mBAAfD,IAAIC,EAAE;;;AAIxB,EAAC"}
@@ -0,0 +1,5 @@
1
+ .wrapper {
2
+ display: flex;
3
+ gap: 5px;
4
+ flex-direction: column;
5
+ }
@@ -0,0 +1,2 @@
1
+ import type { ImageKitUploadHandlerProps } from '../clientUploads.js';
2
+ export declare const ImageKitUploadHandler: ({ authPath, collectionSlug, folder, publicKey, }: ImageKitUploadHandlerProps) => null;
@@ -0,0 +1,77 @@
1
+ 'use client';
2
+ import { useConfig, useUploadHandlers } from '@payloadcms/ui';
3
+ import { formatAdminURL } from 'payload/shared';
4
+ import { useEffect } from 'react';
5
+ const uploadAPIURL = 'https://upload.imagekit.io/api/v1/files/upload';
6
+ const readErrorMessage = async (response, fallback)=>{
7
+ try {
8
+ const result = await response.json();
9
+ if (typeof result.message === 'string' && result.message.trim().length > 0) {
10
+ return result.message;
11
+ }
12
+ } catch {
13
+ // Ignore non-JSON responses and fall back to the default message.
14
+ }
15
+ return fallback;
16
+ };
17
+ export const ImageKitUploadHandler = ({ authPath, collectionSlug, folder, publicKey })=>{
18
+ const { config } = useConfig();
19
+ const { setUploadHandler } = useUploadHandlers();
20
+ useEffect(()=>{
21
+ const authURL = formatAdminURL({
22
+ apiRoute: config.routes.api,
23
+ path: authPath
24
+ });
25
+ setUploadHandler({
26
+ collectionSlug,
27
+ handler: async ({ file, updateFilename })=>{
28
+ const authRequestURL = new URL(authURL, window.location.origin);
29
+ authRequestURL.searchParams.set('filename', file.name);
30
+ const authResponse = await fetch(authRequestURL, {
31
+ credentials: 'include'
32
+ });
33
+ if (!authResponse.ok) {
34
+ throw new Error(await readErrorMessage(authResponse, 'Failed to authenticate direct ImageKit upload.'));
35
+ }
36
+ const auth = await authResponse.json();
37
+ const safeFilename = typeof auth.fileName === 'string' && auth.fileName.length > 0 ? auth.fileName : file.name;
38
+ const formData = new FormData();
39
+ formData.set('expire', String(auth.expire));
40
+ formData.set('file', file);
41
+ formData.set('fileName', safeFilename);
42
+ formData.set('folder', folder);
43
+ formData.set('publicKey', publicKey);
44
+ formData.set('signature', auth.signature);
45
+ formData.set('token', auth.token);
46
+ formData.set('useUniqueFileName', 'false');
47
+ const uploadResponse = await fetch(uploadAPIURL, {
48
+ body: formData,
49
+ method: 'POST'
50
+ });
51
+ if (!uploadResponse.ok) {
52
+ throw new Error(await readErrorMessage(uploadResponse, 'Failed to upload file to ImageKit.'));
53
+ }
54
+ const uploaded = await uploadResponse.json();
55
+ const uploadedFilename = typeof uploaded.name === 'string' && uploaded.name.length > 0 ? uploaded.name : safeFilename;
56
+ updateFilename(uploadedFilename);
57
+ return {
58
+ name: uploadedFilename,
59
+ fileId: uploaded.fileId,
60
+ filePath: uploaded.filePath,
61
+ thumbnailUrl: uploaded.thumbnailUrl,
62
+ url: uploaded.url
63
+ };
64
+ }
65
+ });
66
+ }, [
67
+ authPath,
68
+ collectionSlug,
69
+ config.routes.api,
70
+ folder,
71
+ publicKey,
72
+ setUploadHandler
73
+ ]);
74
+ return null;
75
+ };
76
+
77
+ //# sourceMappingURL=ImageKitUploadHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/ImageKitUploadHandler.tsx"],"sourcesContent":["'use client'\n\nimport { useConfig, useUploadHandlers } from '@payloadcms/ui'\nimport { formatAdminURL } from 'payload/shared'\nimport { useEffect } from 'react'\n\nimport type {\n ImageKitClientUploadContext,\n ImageKitUploadHandlerProps,\n} from '../clientUploads.js'\n\ntype ImageKitAuthResponse = {\n expire: number\n fileName?: string\n signature: string\n token: string\n}\n\ntype ImageKitUploadResponse = {\n message?: string\n name?: string\n} & ImageKitClientUploadContext\n\nconst uploadAPIURL = 'https://upload.imagekit.io/api/v1/files/upload'\n\nconst readErrorMessage = async (response: Response, fallback: string): Promise<string> => {\n try {\n const result = (await response.json()) as { message?: string }\n\n if (typeof result.message === 'string' && result.message.trim().length > 0) {\n return result.message\n }\n } catch {\n // Ignore non-JSON responses and fall back to the default message.\n }\n\n return fallback\n}\n\nexport const ImageKitUploadHandler = ({\n authPath,\n collectionSlug,\n folder,\n publicKey,\n}: ImageKitUploadHandlerProps) => {\n const { config } = useConfig()\n const { setUploadHandler } = useUploadHandlers()\n\n useEffect(() => {\n const authURL = formatAdminURL({\n apiRoute: config.routes.api,\n path: authPath,\n })\n\n setUploadHandler({\n collectionSlug,\n handler: async ({ file, updateFilename }) => {\n const authRequestURL = new URL(authURL, window.location.origin)\n\n authRequestURL.searchParams.set('filename', file.name)\n\n const authResponse = await fetch(authRequestURL, {\n credentials: 'include',\n })\n\n if (!authResponse.ok) {\n throw new Error(\n await readErrorMessage(\n authResponse,\n 'Failed to authenticate direct ImageKit upload.',\n ),\n )\n }\n\n const auth = (await authResponse.json()) as ImageKitAuthResponse\n const safeFilename =\n typeof auth.fileName === 'string' && auth.fileName.length > 0 ? auth.fileName : file.name\n const formData = new FormData()\n\n formData.set('expire', String(auth.expire))\n formData.set('file', file)\n formData.set('fileName', safeFilename)\n formData.set('folder', folder)\n formData.set('publicKey', publicKey)\n formData.set('signature', auth.signature)\n formData.set('token', auth.token)\n formData.set('useUniqueFileName', 'false')\n\n const uploadResponse = await fetch(uploadAPIURL, {\n body: formData,\n method: 'POST',\n })\n\n if (!uploadResponse.ok) {\n throw new Error(\n await readErrorMessage(uploadResponse, 'Failed to upload file to ImageKit.'),\n )\n }\n\n const uploaded = (await uploadResponse.json()) as ImageKitUploadResponse\n const uploadedFilename =\n typeof uploaded.name === 'string' && uploaded.name.length > 0 ? uploaded.name : safeFilename\n\n updateFilename(uploadedFilename)\n\n return {\n name: uploadedFilename,\n fileId: uploaded.fileId,\n filePath: uploaded.filePath,\n thumbnailUrl: uploaded.thumbnailUrl,\n url: uploaded.url,\n }\n },\n })\n }, [authPath, collectionSlug, config.routes.api, folder, publicKey, setUploadHandler])\n\n return null\n}\n"],"names":["useConfig","useUploadHandlers","formatAdminURL","useEffect","uploadAPIURL","readErrorMessage","response","fallback","result","json","message","trim","length","ImageKitUploadHandler","authPath","collectionSlug","folder","publicKey","config","setUploadHandler","authURL","apiRoute","routes","api","path","handler","file","updateFilename","authRequestURL","URL","window","location","origin","searchParams","set","name","authResponse","fetch","credentials","ok","Error","auth","safeFilename","fileName","formData","FormData","String","expire","signature","token","uploadResponse","body","method","uploaded","uploadedFilename","fileId","filePath","thumbnailUrl","url"],"mappings":"AAAA;AAEA,SAASA,SAAS,EAAEC,iBAAiB,QAAQ,iBAAgB;AAC7D,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,SAASC,SAAS,QAAQ,QAAO;AAmBjC,MAAMC,eAAe;AAErB,MAAMC,mBAAmB,OAAOC,UAAoBC;IAClD,IAAI;QACF,MAAMC,SAAU,MAAMF,SAASG,IAAI;QAEnC,IAAI,OAAOD,OAAOE,OAAO,KAAK,YAAYF,OAAOE,OAAO,CAACC,IAAI,GAAGC,MAAM,GAAG,GAAG;YAC1E,OAAOJ,OAAOE,OAAO;QACvB;IACF,EAAE,OAAM;IACN,kEAAkE;IACpE;IAEA,OAAOH;AACT;AAEA,OAAO,MAAMM,wBAAwB,CAAC,EACpCC,QAAQ,EACRC,cAAc,EACdC,MAAM,EACNC,SAAS,EACkB;IAC3B,MAAM,EAAEC,MAAM,EAAE,GAAGlB;IACnB,MAAM,EAAEmB,gBAAgB,EAAE,GAAGlB;IAE7BE,UAAU;QACR,MAAMiB,UAAUlB,eAAe;YAC7BmB,UAAUH,OAAOI,MAAM,CAACC,GAAG;YAC3BC,MAAMV;QACR;QAEAK,iBAAiB;YACfJ;YACAU,SAAS,OAAO,EAAEC,IAAI,EAAEC,cAAc,EAAE;gBACtC,MAAMC,iBAAiB,IAAIC,IAAIT,SAASU,OAAOC,QAAQ,CAACC,MAAM;gBAE9DJ,eAAeK,YAAY,CAACC,GAAG,CAAC,YAAYR,KAAKS,IAAI;gBAErD,MAAMC,eAAe,MAAMC,MAAMT,gBAAgB;oBAC/CU,aAAa;gBACf;gBAEA,IAAI,CAACF,aAAaG,EAAE,EAAE;oBACpB,MAAM,IAAIC,MACR,MAAMnC,iBACJ+B,cACA;gBAGN;gBAEA,MAAMK,OAAQ,MAAML,aAAa3B,IAAI;gBACrC,MAAMiC,eACJ,OAAOD,KAAKE,QAAQ,KAAK,YAAYF,KAAKE,QAAQ,CAAC/B,MAAM,GAAG,IAAI6B,KAAKE,QAAQ,GAAGjB,KAAKS,IAAI;gBAC3F,MAAMS,WAAW,IAAIC;gBAErBD,SAASV,GAAG,CAAC,UAAUY,OAAOL,KAAKM,MAAM;gBACzCH,SAASV,GAAG,CAAC,QAAQR;gBACrBkB,SAASV,GAAG,CAAC,YAAYQ;gBACzBE,SAASV,GAAG,CAAC,UAAUlB;gBACvB4B,SAASV,GAAG,CAAC,aAAajB;gBAC1B2B,SAASV,GAAG,CAAC,aAAaO,KAAKO,SAAS;gBACxCJ,SAASV,GAAG,CAAC,SAASO,KAAKQ,KAAK;gBAChCL,SAASV,GAAG,CAAC,qBAAqB;gBAElC,MAAMgB,iBAAiB,MAAMb,MAAMjC,cAAc;oBAC/C+C,MAAMP;oBACNQ,QAAQ;gBACV;gBAEA,IAAI,CAACF,eAAeX,EAAE,EAAE;oBACtB,MAAM,IAAIC,MACR,MAAMnC,iBAAiB6C,gBAAgB;gBAE3C;gBAEA,MAAMG,WAAY,MAAMH,eAAezC,IAAI;gBAC3C,MAAM6C,mBACJ,OAAOD,SAASlB,IAAI,KAAK,YAAYkB,SAASlB,IAAI,CAACvB,MAAM,GAAG,IAAIyC,SAASlB,IAAI,GAAGO;gBAElFf,eAAe2B;gBAEf,OAAO;oBACLnB,MAAMmB;oBACNC,QAAQF,SAASE,MAAM;oBACvBC,UAAUH,SAASG,QAAQ;oBAC3BC,cAAcJ,SAASI,YAAY;oBACnCC,KAAKL,SAASK,GAAG;gBACnB;YACF;QACF;IACF,GAAG;QAAC5C;QAAUC;QAAgBG,OAAOI,MAAM,CAACC,GAAG;QAAEP;QAAQC;QAAWE;KAAiB;IAErF,OAAO;AACT,EAAC"}
@@ -0,0 +1,8 @@
1
+ import type ImageKit from '@imagekit/nodejs';
2
+ import type { PayloadHandler, UploadCollectionSlug } from 'payload';
3
+ type CreateImageKitUploadAuthHandlerArgs = {
4
+ client: ImageKit;
5
+ collections: Partial<Record<UploadCollectionSlug, true>>;
6
+ };
7
+ export declare const createImageKitUploadAuthHandler: ({ client, collections, }: CreateImageKitUploadAuthHandlerArgs) => PayloadHandler;
8
+ export {};
@@ -0,0 +1,47 @@
1
+ import { getSafeFileName } from 'payload/internal';
2
+ export const createImageKitUploadAuthHandler = ({ client, collections })=>{
3
+ return async (req)=>{
4
+ const collectionSlug = req.routeParams?.collection;
5
+ if (typeof collectionSlug !== 'string' || !(collectionSlug in collections) || collections[collectionSlug] !== true) {
6
+ return Response.json({
7
+ message: 'Collection not found.'
8
+ }, {
9
+ status: 404
10
+ });
11
+ }
12
+ if (!req.user) {
13
+ return Response.json({
14
+ message: 'Unauthorized.'
15
+ }, {
16
+ status: 401
17
+ });
18
+ }
19
+ const authenticationParameters = client.helper.getAuthenticationParameters();
20
+ const requestURL = new URL(req.url || 'http://localhost');
21
+ const requestedFilename = requestURL.searchParams.get('filename')?.trim();
22
+ const collection = req.payload.collections[collectionSlug];
23
+ if (!requestedFilename || typeof collection?.config.upload !== 'object' || typeof collection.config.upload.staticDir !== 'string') {
24
+ return Response.json(authenticationParameters, {
25
+ headers: {
26
+ 'Cache-Control': 'no-store'
27
+ }
28
+ });
29
+ }
30
+ const safeFilename = await getSafeFileName({
31
+ collectionSlug,
32
+ desiredFilename: requestedFilename,
33
+ req,
34
+ staticPath: collection.config.upload.staticDir
35
+ });
36
+ return Response.json({
37
+ ...authenticationParameters,
38
+ fileName: safeFilename
39
+ }, {
40
+ headers: {
41
+ 'Cache-Control': 'no-store'
42
+ }
43
+ });
44
+ };
45
+ };
46
+
47
+ //# sourceMappingURL=createImageKitUploadAuthHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/endpoints/createImageKitUploadAuthHandler.ts"],"sourcesContent":["import type ImageKit from '@imagekit/nodejs'\nimport type { PayloadHandler, UploadCollectionSlug } from 'payload'\n\nimport { getSafeFileName } from 'payload/internal'\n\ntype CreateImageKitUploadAuthHandlerArgs = {\n client: ImageKit\n collections: Partial<Record<UploadCollectionSlug, true>>\n}\n\nexport const createImageKitUploadAuthHandler = ({\n client,\n collections,\n}: CreateImageKitUploadAuthHandlerArgs): PayloadHandler => {\n return async (req) => {\n const collectionSlug = req.routeParams?.collection\n\n if (typeof collectionSlug !== 'string' || !(collectionSlug in collections) || collections[collectionSlug] !== true) {\n return Response.json({ message: 'Collection not found.' }, { status: 404 })\n }\n\n if (!req.user) {\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n const authenticationParameters = client.helper.getAuthenticationParameters()\n const requestURL = new URL(req.url || 'http://localhost')\n const requestedFilename = requestURL.searchParams.get('filename')?.trim()\n const collection = req.payload.collections[collectionSlug]\n\n if (\n !requestedFilename ||\n typeof collection?.config.upload !== 'object' ||\n typeof collection.config.upload.staticDir !== 'string'\n ) {\n return Response.json(authenticationParameters, {\n headers: {\n 'Cache-Control': 'no-store',\n },\n })\n }\n\n const safeFilename = await getSafeFileName({\n collectionSlug,\n desiredFilename: requestedFilename,\n req,\n staticPath: collection.config.upload.staticDir,\n })\n\n return Response.json({ ...authenticationParameters, fileName: safeFilename }, {\n headers: {\n 'Cache-Control': 'no-store',\n },\n })\n }\n}\n"],"names":["getSafeFileName","createImageKitUploadAuthHandler","client","collections","req","collectionSlug","routeParams","collection","Response","json","message","status","user","authenticationParameters","helper","getAuthenticationParameters","requestURL","URL","url","requestedFilename","searchParams","get","trim","payload","config","upload","staticDir","headers","safeFilename","desiredFilename","staticPath","fileName"],"mappings":"AAGA,SAASA,eAAe,QAAQ,mBAAkB;AAOlD,OAAO,MAAMC,kCAAkC,CAAC,EAC9CC,MAAM,EACNC,WAAW,EACyB;IACpC,OAAO,OAAOC;QACZ,MAAMC,iBAAiBD,IAAIE,WAAW,EAAEC;QAExC,IAAI,OAAOF,mBAAmB,YAAY,CAAEA,CAAAA,kBAAkBF,WAAU,KAAMA,WAAW,CAACE,eAAe,KAAK,MAAM;YAClH,OAAOG,SAASC,IAAI,CAAC;gBAAEC,SAAS;YAAwB,GAAG;gBAAEC,QAAQ;YAAI;QAC3E;QAEA,IAAI,CAACP,IAAIQ,IAAI,EAAE;YACb,OAAOJ,SAASC,IAAI,CAAC;gBAAEC,SAAS;YAAgB,GAAG;gBAAEC,QAAQ;YAAI;QACnE;QAEA,MAAME,2BAA2BX,OAAOY,MAAM,CAACC,2BAA2B;QAC1E,MAAMC,aAAa,IAAIC,IAAIb,IAAIc,GAAG,IAAI;QACtC,MAAMC,oBAAoBH,WAAWI,YAAY,CAACC,GAAG,CAAC,aAAaC;QACnE,MAAMf,aAAaH,IAAImB,OAAO,CAACpB,WAAW,CAACE,eAAe;QAE1D,IACE,CAACc,qBACD,OAAOZ,YAAYiB,OAAOC,WAAW,YACrC,OAAOlB,WAAWiB,MAAM,CAACC,MAAM,CAACC,SAAS,KAAK,UAC9C;YACA,OAAOlB,SAASC,IAAI,CAACI,0BAA0B;gBAC7Cc,SAAS;oBACP,iBAAiB;gBACnB;YACF;QACF;QAEA,MAAMC,eAAe,MAAM5B,gBAAgB;YACzCK;YACAwB,iBAAiBV;YACjBf;YACA0B,YAAYvB,WAAWiB,MAAM,CAACC,MAAM,CAACC,SAAS;QAChD;QAEA,OAAOlB,SAASC,IAAI,CAAC;YAAE,GAAGI,wBAAwB;YAAEkB,UAAUH;QAAa,GAAG;YAC5ED,SAAS;gBACP,iBAAiB;YACnB;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,8 @@
1
+ import type ImageKit from '@imagekit/nodejs';
2
+ import type { PayloadHandler, UploadCollectionSlug } from 'payload';
3
+ type CreateImageKitUploadAuthHandlerArgs = {
4
+ client: ImageKit;
5
+ collections: Partial<Record<UploadCollectionSlug, true>>;
6
+ };
7
+ export declare const createImageKitUploadAuthHandler: ({ client, collections, }: CreateImageKitUploadAuthHandlerArgs) => PayloadHandler;
8
+ export {};
@@ -0,0 +1,26 @@
1
+ export const createImageKitUploadAuthHandler = ({ client, collections })=>{
2
+ return async (req)=>{
3
+ const collectionSlug = req.routeParams?.collection;
4
+ if (typeof collectionSlug !== 'string' || !(collectionSlug in collections) || collections[collectionSlug] !== true) {
5
+ return Response.json({
6
+ message: 'Collection not found.'
7
+ }, {
8
+ status: 404
9
+ });
10
+ }
11
+ if (!req.user) {
12
+ return Response.json({
13
+ message: 'Unauthorized.'
14
+ }, {
15
+ status: 401
16
+ });
17
+ }
18
+ return Response.json(client.helper.getAuthenticationParameters(), {
19
+ headers: {
20
+ 'Cache-Control': 'no-store'
21
+ }
22
+ });
23
+ };
24
+ };
25
+
26
+ //# sourceMappingURL=customEndpointHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/endpoints/customEndpointHandler.ts"],"sourcesContent":["import type { UploadCollectionSlug, PayloadHandler } from 'payload'\n\nimport type ImageKit from '@imagekit/nodejs'\n\ntype CreateImageKitUploadAuthHandlerArgs = {\n client: ImageKit\n collections: Partial<Record<UploadCollectionSlug, true>>\n}\n\nexport const createImageKitUploadAuthHandler = ({\n client,\n collections,\n}: CreateImageKitUploadAuthHandlerArgs): PayloadHandler => {\n return async (req) => {\n const collectionSlug = req.routeParams?.collection\n\n if (\n typeof collectionSlug !== 'string' ||\n !(collectionSlug in collections) ||\n collections[collectionSlug as UploadCollectionSlug] !== true\n ) {\n return Response.json({ message: 'Collection not found.' }, { status: 404 })\n }\n\n if (!req.user) {\n return Response.json({ message: 'Unauthorized.' }, { status: 401 })\n }\n\n return Response.json(client.helper.getAuthenticationParameters(), {\n headers: {\n 'Cache-Control': 'no-store',\n },\n })\n }\n}\n"],"names":["createImageKitUploadAuthHandler","client","collections","req","collectionSlug","routeParams","collection","Response","json","message","status","user","helper","getAuthenticationParameters","headers"],"mappings":"AASA,OAAO,MAAMA,kCAAkC,CAAC,EAC9CC,MAAM,EACNC,WAAW,EACyB;IACpC,OAAO,OAAOC;QACZ,MAAMC,iBAAiBD,IAAIE,WAAW,EAAEC;QAExC,IACE,OAAOF,mBAAmB,YAC1B,CAAEA,CAAAA,kBAAkBF,WAAU,KAC9BA,WAAW,CAACE,eAAuC,KAAK,MACxD;YACA,OAAOG,SAASC,IAAI,CAAC;gBAAEC,SAAS;YAAwB,GAAG;gBAAEC,QAAQ;YAAI;QAC3E;QAEA,IAAI,CAACP,IAAIQ,IAAI,EAAE;YACb,OAAOJ,SAASC,IAAI,CAAC;gBAAEC,SAAS;YAAgB,GAAG;gBAAEC,QAAQ;YAAI;QACnE;QAEA,OAAOH,SAASC,IAAI,CAACP,OAAOW,MAAM,CAACC,2BAA2B,IAAI;YAChEC,SAAS;gBACP,iBAAiB;YACnB;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,3 @@
1
+ export type { ImageKitClientUploadContext, ImageKitUploadHandlerProps, } from '../clientUploads.js';
2
+ export { BeforeDashboardClient } from '../components/BeforeDashboardClient.js';
3
+ export { ImageKitUploadHandler } from '../components/ImageKitUploadHandler.js';
@@ -0,0 +1,4 @@
1
+ export { BeforeDashboardClient } from '../components/BeforeDashboardClient.js';
2
+ export { ImageKitUploadHandler } from '../components/ImageKitUploadHandler.js';
3
+
4
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export type {\n ImageKitClientUploadContext,\n ImageKitUploadHandlerProps,\n} from '../clientUploads.js'\nexport { BeforeDashboardClient } from '../components/BeforeDashboardClient.js'\nexport { ImageKitUploadHandler } from '../components/ImageKitUploadHandler.js'\n"],"names":["BeforeDashboardClient","ImageKitUploadHandler"],"mappings":"AAIA,SAASA,qBAAqB,QAAQ,yCAAwC;AAC9E,SAASC,qBAAqB,QAAQ,yCAAwC"}
@@ -0,0 +1 @@
1
+ export { BeforeDashboardServer } from '../components/BeforeDashboardServer.js';
@@ -0,0 +1,3 @@
1
+ export { BeforeDashboardServer } from '../components/BeforeDashboardServer.js';
2
+
3
+ //# sourceMappingURL=rsc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export { BeforeDashboardServer } from '../components/BeforeDashboardServer.js'\n"],"names":["BeforeDashboardServer"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,yCAAwC"}
@@ -0,0 +1 @@
1
+ export declare const getAdminThumbnailURL: (doc: unknown) => string;
@@ -0,0 +1,22 @@
1
+ export const getAdminThumbnailURL = (doc)=>{
2
+ const file = doc;
3
+ const baseURL = file.imagekit?.url;
4
+ if (!baseURL) {
5
+ return '';
6
+ }
7
+ const isVideo = file.mimeType?.startsWith('video');
8
+ const isPDF = file.mimeType === 'application/pdf' || file.mimeType?.endsWith('/pdf');
9
+ let thumbnailBaseURL = baseURL;
10
+ if (isVideo || isPDF) {
11
+ try {
12
+ const parsedURL = new URL(baseURL);
13
+ thumbnailBaseURL = `${parsedURL.origin}${parsedURL.pathname}/ik-thumbnail.jpg`;
14
+ } catch {
15
+ const normalizedBaseURL = baseURL.split('?')[0].split('#')[0];
16
+ thumbnailBaseURL = `${normalizedBaseURL}/ik-thumbnail.jpg`;
17
+ }
18
+ }
19
+ return `${thumbnailBaseURL}${thumbnailBaseURL.includes('?') ? '&' : '?'}tr=w-300,h-300`;
20
+ };
21
+
22
+ //# sourceMappingURL=getAdminThumbnailURL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/getAdminThumbnailURL.ts"],"sourcesContent":["type ImagekitReference = {\n imagekit?: {\n url?: string\n }\n}\n\nexport const getAdminThumbnailURL = (doc: unknown): string => {\n const file = doc as { mimeType?: string } & ImagekitReference\n const baseURL = file.imagekit?.url\n\n if (!baseURL) {\n return ''\n }\n\n const isVideo = file.mimeType?.startsWith('video')\n const isPDF = file.mimeType === 'application/pdf' || file.mimeType?.endsWith('/pdf')\n\n let thumbnailBaseURL = baseURL\n\n if (isVideo || isPDF) {\n try {\n const parsedURL = new URL(baseURL)\n thumbnailBaseURL = `${parsedURL.origin}${parsedURL.pathname}/ik-thumbnail.jpg`\n } catch {\n const normalizedBaseURL = baseURL.split('?')[0].split('#')[0]\n thumbnailBaseURL = `${normalizedBaseURL}/ik-thumbnail.jpg`\n }\n }\n\n return `${thumbnailBaseURL}${thumbnailBaseURL.includes('?') ? '&' : '?'}tr=w-300,h-300`\n}\n"],"names":["getAdminThumbnailURL","doc","file","baseURL","imagekit","url","isVideo","mimeType","startsWith","isPDF","endsWith","thumbnailBaseURL","parsedURL","URL","origin","pathname","normalizedBaseURL","split","includes"],"mappings":"AAMA,OAAO,MAAMA,uBAAuB,CAACC;IACnC,MAAMC,OAAOD;IACb,MAAME,UAAUD,KAAKE,QAAQ,EAAEC;IAE/B,IAAI,CAACF,SAAS;QACZ,OAAO;IACT;IAEA,MAAMG,UAAUJ,KAAKK,QAAQ,EAAEC,WAAW;IAC1C,MAAMC,QAAQP,KAAKK,QAAQ,KAAK,qBAAqBL,KAAKK,QAAQ,EAAEG,SAAS;IAE7E,IAAIC,mBAAmBR;IAEvB,IAAIG,WAAWG,OAAO;QACpB,IAAI;YACF,MAAMG,YAAY,IAAIC,IAAIV;YAC1BQ,mBAAmB,GAAGC,UAAUE,MAAM,GAAGF,UAAUG,QAAQ,CAAC,iBAAiB,CAAC;QAChF,EAAE,OAAM;YACN,MAAMC,oBAAoBb,QAAQc,KAAK,CAAC,IAAI,CAAC,EAAE,CAACA,KAAK,CAAC,IAAI,CAAC,EAAE;YAC7DN,mBAAmB,GAAGK,kBAAkB,iBAAiB,CAAC;QAC5D;IACF;IAEA,OAAO,GAAGL,mBAAmBA,iBAAiBO,QAAQ,CAAC,OAAO,MAAM,IAAI,cAAc,CAAC;AACzF,EAAC"}
@@ -0,0 +1,15 @@
1
+ type ImageKitCropMode = 'at_least' | 'at_max' | 'extract' | 'force' | 'maintain_ratio' | 'pad_extract' | 'pad_resize';
2
+ type ImageKitFocalStrategy = 'coordinates' | 'custom';
3
+ export type BuildImageKitTransformOptions = {
4
+ additionalTransforms?: string[];
5
+ cropMode?: ImageKitCropMode;
6
+ extractZoomOut?: number;
7
+ focalStrategy?: ImageKitFocalStrategy;
8
+ height?: number;
9
+ width?: number;
10
+ };
11
+ export declare const getImageKitCustomCoordinates: (doc: unknown) => string | undefined;
12
+ export declare const getImageKitThumbnailTransform: (doc: unknown) => string;
13
+ export declare const buildImageKitTransform: (doc: unknown, options: BuildImageKitTransformOptions) => string;
14
+ export declare const buildImageKitURL: (doc: unknown, options: BuildImageKitTransformOptions) => string;
15
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { Config, UploadCollectionSlug } from 'payload';
2
+ type ImageKitCollectionMap = Partial<Record<UploadCollectionSlug, true>>;
3
+ export type PayloadStorageImagekitConfig = {
4
+ alwaysInsertFields?: boolean;
5
+ clientUploads?: boolean;
6
+ collections: ImageKitCollectionMap;
7
+ disablePayloadAccessControl?: true;
8
+ enabled?: boolean;
9
+ folder: string;
10
+ privateKey: string;
11
+ publicKey: string;
12
+ urlEndpoint: string;
13
+ };
14
+ export declare const imagekitStorage: (pluginOptions: PayloadStorageImagekitConfig) => (config: Config) => Config;
15
+ export { migrateFolder } from './migrate.js';
16
+ export type { MigrateFolderOptions, MigrationJobResult } from './migrate.js';
17
+ export declare const payloadStorageImagekit: (pluginOptions: PayloadStorageImagekitConfig) => (config: Config) => Config;