@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.
- package/README.md +142 -0
- package/dist/clientUploads.d.ts +16 -0
- package/dist/clientUploads.js +10 -0
- package/dist/clientUploads.js.map +1 -0
- package/dist/components/BeforeDashboardClient.d.ts +1 -0
- package/dist/components/BeforeDashboardClient.js +40 -0
- package/dist/components/BeforeDashboardClient.js.map +1 -0
- package/dist/components/BeforeDashboardServer.d.ts +2 -0
- package/dist/components/BeforeDashboardServer.js +22 -0
- package/dist/components/BeforeDashboardServer.js.map +1 -0
- package/dist/components/BeforeDashboardServer.module.css +5 -0
- package/dist/components/ImageKitUploadHandler.d.ts +2 -0
- package/dist/components/ImageKitUploadHandler.js +77 -0
- package/dist/components/ImageKitUploadHandler.js.map +1 -0
- package/dist/endpoints/createImageKitUploadAuthHandler.d.ts +8 -0
- package/dist/endpoints/createImageKitUploadAuthHandler.js +47 -0
- package/dist/endpoints/createImageKitUploadAuthHandler.js.map +1 -0
- package/dist/endpoints/customEndpointHandler.d.ts +8 -0
- package/dist/endpoints/customEndpointHandler.js +26 -0
- package/dist/endpoints/customEndpointHandler.js.map +1 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.js +4 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/rsc.d.ts +1 -0
- package/dist/exports/rsc.js +3 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/getAdminThumbnailURL.d.ts +1 -0
- package/dist/getAdminThumbnailURL.js +22 -0
- package/dist/getAdminThumbnailURL.js.map +1 -0
- package/dist/imagekitTransforms.d.ts +15 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +275 -0
- package/dist/index.js.map +1 -0
- package/dist/migrate.d.ts +44 -0
- package/dist/migrate.js +258 -0
- package/dist/migrate.js.map +1 -0
- 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,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,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 @@
|
|
|
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 @@
|
|
|
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 {};
|
package/dist/index.d.ts
ADDED
|
@@ -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;
|