@btst/stack 2.8.1 → 2.9.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 +3 -2
- package/dist/components/markdown/index.d.cts +15 -2
- package/dist/components/markdown/index.d.mts +15 -2
- package/dist/components/markdown/index.d.ts +15 -2
- package/dist/packages/stack/src/plugins/blog/client/components/forms/image-field.cjs +30 -1
- package/dist/packages/stack/src/plugins/blog/client/components/forms/image-field.mjs +30 -1
- package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.cjs +49 -9
- package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.mjs +50 -10
- package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor.cjs +77 -9
- package/dist/packages/stack/src/plugins/blog/client/components/forms/markdown-editor.mjs +77 -9
- package/dist/packages/stack/src/plugins/cms/client/components/forms/content-form.cjs +24 -5
- package/dist/packages/stack/src/plugins/cms/client/components/forms/content-form.mjs +24 -5
- package/dist/packages/stack/src/plugins/cms/client/components/forms/file-upload.cjs +47 -13
- package/dist/packages/stack/src/plugins/cms/client/components/forms/file-upload.mjs +47 -13
- package/dist/packages/stack/src/plugins/kanban/client/components/forms/board-form.cjs +1 -1
- package/dist/packages/stack/src/plugins/kanban/client/components/forms/board-form.mjs +1 -1
- package/dist/packages/stack/src/plugins/kanban/client/components/forms/task-form.cjs +6 -2
- package/dist/packages/stack/src/plugins/kanban/client/components/forms/task-form.mjs +6 -2
- package/dist/packages/stack/src/plugins/media/api/adapters/local.cjs +55 -0
- package/dist/packages/stack/src/plugins/media/api/adapters/local.mjs +37 -0
- package/dist/packages/stack/src/plugins/media/api/getters.cjs +83 -0
- package/dist/packages/stack/src/plugins/media/api/getters.mjs +78 -0
- package/dist/packages/stack/src/plugins/media/api/mutations.cjs +88 -0
- package/dist/packages/stack/src/plugins/media/api/mutations.mjs +82 -0
- package/dist/packages/stack/src/plugins/media/api/plugin.cjs +525 -0
- package/dist/packages/stack/src/plugins/media/api/plugin.mjs +523 -0
- package/dist/packages/stack/src/plugins/media/api/query-key-defs.cjs +19 -0
- package/dist/packages/stack/src/plugins/media/api/query-key-defs.mjs +16 -0
- package/dist/packages/stack/src/plugins/media/api/serializers.cjs +17 -0
- package/dist/packages/stack/src/plugins/media/api/serializers.mjs +14 -0
- package/dist/packages/stack/src/plugins/media/api/storage-adapter.cjs +15 -0
- package/dist/packages/stack/src/plugins/media/api/storage-adapter.mjs +11 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/asset-card.cjs +129 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/asset-card.mjs +127 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/asset-preview-button.cjs +58 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/asset-preview-button.mjs +56 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/browse-tab.cjs +94 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/browse-tab.mjs +92 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/folder-tree.cjs +171 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/folder-tree.mjs +168 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/index.cjs +308 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/index.mjs +305 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/upload-tab.cjs +104 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/upload-tab.mjs +102 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/url-tab.cjs +70 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/url-tab.mjs +68 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/utils.cjs +21 -0
- package/dist/packages/stack/src/plugins/media/client/components/media-picker/utils.mjs +17 -0
- package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.cjs +35 -0
- package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.internal.cjs +125 -0
- package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.internal.mjs +123 -0
- package/dist/packages/stack/src/plugins/media/client/components/pages/library-page.mjs +33 -0
- package/dist/packages/stack/src/plugins/media/client/hooks/use-media.cjs +222 -0
- package/dist/packages/stack/src/plugins/media/client/hooks/use-media.mjs +214 -0
- package/dist/packages/stack/src/plugins/media/client/plugin.cjs +94 -0
- package/dist/packages/stack/src/plugins/media/client/plugin.mjs +92 -0
- package/dist/packages/stack/src/plugins/media/client/upload.cjs +121 -0
- package/dist/packages/stack/src/plugins/media/client/upload.mjs +119 -0
- package/dist/packages/stack/src/plugins/media/client/utils/image-compression.cjs +67 -0
- package/dist/packages/stack/src/plugins/media/client/utils/image-compression.mjs +65 -0
- package/dist/packages/stack/src/plugins/media/db.cjs +62 -0
- package/dist/packages/stack/src/plugins/media/db.mjs +60 -0
- package/dist/packages/stack/src/plugins/media/schemas.cjs +41 -0
- package/dist/packages/stack/src/plugins/media/schemas.mjs +35 -0
- package/dist/packages/ui/src/components/minimal-tiptap/components/image/image-edit-block.cjs +18 -1
- package/dist/packages/ui/src/components/minimal-tiptap/components/image/image-edit-block.mjs +19 -2
- package/dist/packages/ui/src/components/minimal-tiptap/components/image/image-edit-dialog.cjs +2 -2
- package/dist/packages/ui/src/components/minimal-tiptap/components/image/image-edit-dialog.mjs +2 -2
- package/dist/packages/ui/src/components/minimal-tiptap/components/section/five.cjs +3 -2
- package/dist/packages/ui/src/components/minimal-tiptap/components/section/five.mjs +3 -2
- package/dist/packages/ui/src/components/minimal-tiptap/minimal-tiptap.cjs +12 -5
- package/dist/packages/ui/src/components/minimal-tiptap/minimal-tiptap.mjs +12 -5
- package/dist/plugins/blog/client/index.d.cts +58 -1
- package/dist/plugins/blog/client/index.d.mts +58 -1
- package/dist/plugins/blog/client/index.d.ts +58 -1
- package/dist/plugins/cms/client/index.d.cts +73 -3
- package/dist/plugins/cms/client/index.d.mts +73 -3
- package/dist/plugins/cms/client/index.d.ts +73 -3
- package/dist/plugins/kanban/api/index.d.cts +1 -1
- package/dist/plugins/kanban/api/index.d.mts +1 -1
- package/dist/plugins/kanban/api/index.d.ts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
- package/dist/plugins/kanban/client/index.d.cts +1 -1
- package/dist/plugins/kanban/client/index.d.mts +1 -1
- package/dist/plugins/kanban/client/index.d.ts +1 -1
- package/dist/plugins/kanban/query-keys.d.cts +1 -1
- package/dist/plugins/kanban/query-keys.d.mts +1 -1
- package/dist/plugins/kanban/query-keys.d.ts +1 -1
- package/dist/plugins/media/api/adapters/s3.cjs +106 -0
- package/dist/plugins/media/api/adapters/s3.d.cts +60 -0
- package/dist/plugins/media/api/adapters/s3.d.mts +60 -0
- package/dist/plugins/media/api/adapters/s3.d.ts +60 -0
- package/dist/plugins/media/api/adapters/s3.mjs +104 -0
- package/dist/plugins/media/api/adapters/vercel-blob.cjs +53 -0
- package/dist/plugins/media/api/adapters/vercel-blob.d.cts +41 -0
- package/dist/plugins/media/api/adapters/vercel-blob.d.mts +41 -0
- package/dist/plugins/media/api/adapters/vercel-blob.d.ts +41 -0
- package/dist/plugins/media/api/adapters/vercel-blob.mjs +51 -0
- package/dist/plugins/media/api/index.cjs +26 -0
- package/dist/plugins/media/api/index.d.cts +116 -0
- package/dist/plugins/media/api/index.d.mts +116 -0
- package/dist/plugins/media/api/index.d.ts +116 -0
- package/dist/plugins/media/api/index.mjs +6 -0
- package/dist/plugins/media/client/components/index.cjs +10 -0
- package/dist/plugins/media/client/components/index.d.cts +55 -0
- package/dist/plugins/media/client/components/index.d.mts +55 -0
- package/dist/plugins/media/client/components/index.d.ts +55 -0
- package/dist/plugins/media/client/components/index.mjs +2 -0
- package/dist/plugins/media/client/hooks/index.cjs +13 -0
- package/dist/plugins/media/client/hooks/index.d.cts +53 -0
- package/dist/plugins/media/client/hooks/index.d.mts +53 -0
- package/dist/plugins/media/client/hooks/index.d.ts +53 -0
- package/dist/plugins/media/client/hooks/index.mjs +1 -0
- package/dist/plugins/media/client/index.cjs +9 -0
- package/dist/plugins/media/client/index.d.cts +242 -0
- package/dist/plugins/media/client/index.d.mts +242 -0
- package/dist/plugins/media/client/index.d.ts +242 -0
- package/dist/plugins/media/client/index.mjs +2 -0
- package/dist/plugins/media/client.css +1 -0
- package/dist/plugins/media/query-keys.cjs +72 -0
- package/dist/plugins/media/query-keys.d.cts +49 -0
- package/dist/plugins/media/query-keys.d.mts +49 -0
- package/dist/plugins/media/query-keys.d.ts +49 -0
- package/dist/plugins/media/query-keys.mjs +70 -0
- package/dist/plugins/media/style.css +1 -0
- package/dist/shared/{stack.DRpeDS6X.d.ts → stack.BMx2QYOK.d.ts} +25 -0
- package/dist/shared/stack.BttDsJJn.d.cts +109 -0
- package/dist/shared/stack.BttDsJJn.d.mts +109 -0
- package/dist/shared/stack.BttDsJJn.d.ts +109 -0
- package/dist/shared/stack.C7vfOBmO.d.mts +63 -0
- package/dist/shared/stack.CAni8dnD.d.cts +63 -0
- package/dist/shared/stack.CI8iRKKi.d.cts +286 -0
- package/dist/shared/stack.CLcnSF_b.d.cts +25 -0
- package/dist/shared/stack.CLcnSF_b.d.mts +25 -0
- package/dist/shared/stack.CLcnSF_b.d.ts +25 -0
- package/dist/shared/stack.CYSwntXC.d.ts +63 -0
- package/dist/shared/{stack.Jb0kQDJC.d.mts → stack.Cd6McBu1.d.mts} +25 -0
- package/dist/shared/stack.DJDjdG64.d.ts +286 -0
- package/dist/shared/{stack.BxFl46lB.d.cts → stack.DxQl8Wa1.d.cts} +25 -0
- package/dist/shared/stack.FgBVDSPi.d.mts +286 -0
- package/package.json +113 -4
- package/src/plugins/blog/client/components/forms/image-field.tsx +35 -4
- package/src/plugins/blog/client/components/forms/markdown-editor-with-overrides.tsx +67 -12
- package/src/plugins/blog/client/components/forms/markdown-editor.tsx +106 -10
- package/src/plugins/blog/client/overrides.ts +58 -1
- package/src/plugins/cms/client/components/forms/content-form.tsx +26 -7
- package/src/plugins/cms/client/components/forms/file-upload.tsx +73 -15
- package/src/plugins/cms/client/overrides.ts +57 -2
- package/src/plugins/kanban/client/components/forms/board-form.tsx +1 -1
- package/src/plugins/kanban/client/components/forms/task-form.tsx +7 -1
- package/src/plugins/kanban/client/overrides.ts +25 -0
- package/src/plugins/media/__tests__/__stubs__/vercel-blob-server.ts +9 -0
- package/src/plugins/media/__tests__/getters.test.ts +274 -0
- package/src/plugins/media/__tests__/mutations.test.ts +299 -0
- package/src/plugins/media/__tests__/plugin.test.ts +752 -0
- package/src/plugins/media/__tests__/query-key-defs.test.ts +54 -0
- package/src/plugins/media/__tests__/storage-adapters.test.ts +351 -0
- package/src/plugins/media/api/adapters/local.ts +79 -0
- package/src/plugins/media/api/adapters/s3.ts +198 -0
- package/src/plugins/media/api/adapters/vercel-blob.ts +131 -0
- package/src/plugins/media/api/getters.ts +174 -0
- package/src/plugins/media/api/index.ts +41 -0
- package/src/plugins/media/api/mutations.ts +179 -0
- package/src/plugins/media/api/plugin.ts +855 -0
- package/src/plugins/media/api/query-key-defs.ts +41 -0
- package/src/plugins/media/api/serializers.ts +28 -0
- package/src/plugins/media/api/storage-adapter.ts +139 -0
- package/src/plugins/media/client/components/index.tsx +6 -0
- package/src/plugins/media/client/components/media-picker/asset-card.tsx +150 -0
- package/src/plugins/media/client/components/media-picker/asset-preview-button.tsx +67 -0
- package/src/plugins/media/client/components/media-picker/browse-tab.tsx +116 -0
- package/src/plugins/media/client/components/media-picker/folder-tree.tsx +188 -0
- package/src/plugins/media/client/components/media-picker/index.tsx +347 -0
- package/src/plugins/media/client/components/media-picker/upload-tab.tsx +108 -0
- package/src/plugins/media/client/components/media-picker/url-tab.tsx +72 -0
- package/src/plugins/media/client/components/media-picker/utils.ts +17 -0
- package/src/plugins/media/client/components/pages/library-page.internal.tsx +134 -0
- package/src/plugins/media/client/components/pages/library-page.tsx +42 -0
- package/src/plugins/media/client/hooks/index.tsx +9 -0
- package/src/plugins/media/client/hooks/use-media.tsx +289 -0
- package/src/plugins/media/client/index.ts +4 -0
- package/src/plugins/media/client/overrides.ts +127 -0
- package/src/plugins/media/client/plugin.tsx +184 -0
- package/src/plugins/media/client/upload.ts +171 -0
- package/src/plugins/media/client/utils/image-compression.ts +131 -0
- package/src/plugins/media/client.css +1 -0
- package/src/plugins/media/db.ts +62 -0
- package/src/plugins/media/query-keys.ts +96 -0
- package/src/plugins/media/schemas.ts +37 -0
- package/src/plugins/media/style.css +1 -0
- package/src/plugins/media/types.ts +26 -0
- package/dist/shared/{stack.BOokfhZD.d.cts → stack.B6S3cgwN.d.cts} +16 -16
- package/dist/shared/{stack.CWxAl9K3.d.mts → stack.Bzfx-_lq.d.mts} +16 -16
- package/dist/shared/{stack.BvCR4-9H.d.ts → stack.j5SFLC1d.d.ts} +16 -16
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options provided to storage adapters when initiating an upload.
|
|
3
|
+
*/
|
|
4
|
+
interface UploadOptions {
|
|
5
|
+
filename: string;
|
|
6
|
+
mimeType: string;
|
|
7
|
+
size: number;
|
|
8
|
+
folderId?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Local storage adapter — backend receives and stores file bytes directly.
|
|
12
|
+
* Suitable for development and self-hosted deployments.
|
|
13
|
+
*/
|
|
14
|
+
interface DirectStorageAdapter {
|
|
15
|
+
readonly type: "local";
|
|
16
|
+
/**
|
|
17
|
+
* Store the file buffer and return the public URL.
|
|
18
|
+
*/
|
|
19
|
+
upload(buffer: Buffer, options: UploadOptions): Promise<{
|
|
20
|
+
url: string;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Remove the stored file given its public URL.
|
|
24
|
+
*/
|
|
25
|
+
delete(url: string): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Token returned by the S3 adapter.
|
|
29
|
+
* The client performs a `PUT` to `payload.uploadUrl` with the file body,
|
|
30
|
+
* then saves `payload.publicUrl` as the asset URL.
|
|
31
|
+
*/
|
|
32
|
+
interface S3UploadToken {
|
|
33
|
+
type: "presigned-url";
|
|
34
|
+
payload: {
|
|
35
|
+
uploadUrl: string;
|
|
36
|
+
publicUrl: string;
|
|
37
|
+
key: string;
|
|
38
|
+
method: "PUT";
|
|
39
|
+
headers: Record<string, string>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* S3 storage adapter — server issues a short-lived presigned PUT URL;
|
|
44
|
+
* the browser uploads directly to S3 (or R2 / MinIO).
|
|
45
|
+
*/
|
|
46
|
+
interface S3StorageAdapter {
|
|
47
|
+
readonly type: "s3";
|
|
48
|
+
/**
|
|
49
|
+
* The public base URL prefix for all assets in this bucket
|
|
50
|
+
* (e.g. `"https://assets.example.com"`). Used by the plugin to
|
|
51
|
+
* automatically validate client-supplied URLs when no explicit
|
|
52
|
+
* `allowedUrlPrefixes` are configured.
|
|
53
|
+
*/
|
|
54
|
+
readonly urlPrefix: string;
|
|
55
|
+
/**
|
|
56
|
+
* Generate a presigned PUT URL for direct client upload.
|
|
57
|
+
*/
|
|
58
|
+
generateUploadToken(options: UploadOptions): Promise<S3UploadToken>;
|
|
59
|
+
/**
|
|
60
|
+
* Remove the stored object given its public URL.
|
|
61
|
+
*/
|
|
62
|
+
delete(url: string): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Options returned from onBeforeGenerateToken and passed to Vercel Blob's handleUpload.
|
|
66
|
+
*/
|
|
67
|
+
interface VercelBlobTokenOptions {
|
|
68
|
+
addRandomSuffix?: boolean;
|
|
69
|
+
allowedContentTypes?: string[];
|
|
70
|
+
maximumSizeInBytes?: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Callbacks provided to the Vercel Blob adapter when handling a request.
|
|
74
|
+
*/
|
|
75
|
+
interface VercelBlobHandlerCallbacks {
|
|
76
|
+
/**
|
|
77
|
+
* Called before a client token is generated.
|
|
78
|
+
* Throw to reject the upload (auth gate).
|
|
79
|
+
* Return options to enforce allowedContentTypes and maximumSizeInBytes at the edge.
|
|
80
|
+
*/
|
|
81
|
+
onBeforeGenerateToken?: (pathname: string, clientPayload: string | null) => Promise<VercelBlobTokenOptions | void> | VercelBlobTokenOptions | void;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Vercel Blob storage adapter — uses the `@vercel/blob/client` `handleUpload`
|
|
85
|
+
* protocol. The same endpoint handles both token generation and upload
|
|
86
|
+
* completion notifications from Vercel's servers.
|
|
87
|
+
*/
|
|
88
|
+
interface VercelBlobStorageAdapter {
|
|
89
|
+
readonly type: "vercel-blob";
|
|
90
|
+
/**
|
|
91
|
+
* Hostname suffix that all Vercel Blob public URLs end with.
|
|
92
|
+
* Used by the plugin to automatically validate client-supplied URLs.
|
|
93
|
+
* Always `".public.blob.vercel-storage.com"`.
|
|
94
|
+
*/
|
|
95
|
+
readonly urlHostnameSuffix: string;
|
|
96
|
+
/**
|
|
97
|
+
* Process a raw request from `@vercel/blob/client`'s `upload()` or from
|
|
98
|
+
* Vercel Blob's upload-completion webhook. Returns a JSON-serialisable object
|
|
99
|
+
* that should be sent back as the response body.
|
|
100
|
+
*/
|
|
101
|
+
handleRequest(request: Request, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
102
|
+
/**
|
|
103
|
+
* Remove the stored blob given its public URL.
|
|
104
|
+
*/
|
|
105
|
+
delete(url: string): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
type StorageAdapter = DirectStorageAdapter | S3StorageAdapter | VercelBlobStorageAdapter;
|
|
108
|
+
|
|
109
|
+
export type { DirectStorageAdapter as D, S3StorageAdapter as S, UploadOptions as U, VercelBlobStorageAdapter as V, StorageAdapter as a, S3UploadToken as b, VercelBlobHandlerCallbacks as c };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options provided to storage adapters when initiating an upload.
|
|
3
|
+
*/
|
|
4
|
+
interface UploadOptions {
|
|
5
|
+
filename: string;
|
|
6
|
+
mimeType: string;
|
|
7
|
+
size: number;
|
|
8
|
+
folderId?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Local storage adapter — backend receives and stores file bytes directly.
|
|
12
|
+
* Suitable for development and self-hosted deployments.
|
|
13
|
+
*/
|
|
14
|
+
interface DirectStorageAdapter {
|
|
15
|
+
readonly type: "local";
|
|
16
|
+
/**
|
|
17
|
+
* Store the file buffer and return the public URL.
|
|
18
|
+
*/
|
|
19
|
+
upload(buffer: Buffer, options: UploadOptions): Promise<{
|
|
20
|
+
url: string;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Remove the stored file given its public URL.
|
|
24
|
+
*/
|
|
25
|
+
delete(url: string): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Token returned by the S3 adapter.
|
|
29
|
+
* The client performs a `PUT` to `payload.uploadUrl` with the file body,
|
|
30
|
+
* then saves `payload.publicUrl` as the asset URL.
|
|
31
|
+
*/
|
|
32
|
+
interface S3UploadToken {
|
|
33
|
+
type: "presigned-url";
|
|
34
|
+
payload: {
|
|
35
|
+
uploadUrl: string;
|
|
36
|
+
publicUrl: string;
|
|
37
|
+
key: string;
|
|
38
|
+
method: "PUT";
|
|
39
|
+
headers: Record<string, string>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* S3 storage adapter — server issues a short-lived presigned PUT URL;
|
|
44
|
+
* the browser uploads directly to S3 (or R2 / MinIO).
|
|
45
|
+
*/
|
|
46
|
+
interface S3StorageAdapter {
|
|
47
|
+
readonly type: "s3";
|
|
48
|
+
/**
|
|
49
|
+
* The public base URL prefix for all assets in this bucket
|
|
50
|
+
* (e.g. `"https://assets.example.com"`). Used by the plugin to
|
|
51
|
+
* automatically validate client-supplied URLs when no explicit
|
|
52
|
+
* `allowedUrlPrefixes` are configured.
|
|
53
|
+
*/
|
|
54
|
+
readonly urlPrefix: string;
|
|
55
|
+
/**
|
|
56
|
+
* Generate a presigned PUT URL for direct client upload.
|
|
57
|
+
*/
|
|
58
|
+
generateUploadToken(options: UploadOptions): Promise<S3UploadToken>;
|
|
59
|
+
/**
|
|
60
|
+
* Remove the stored object given its public URL.
|
|
61
|
+
*/
|
|
62
|
+
delete(url: string): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Options returned from onBeforeGenerateToken and passed to Vercel Blob's handleUpload.
|
|
66
|
+
*/
|
|
67
|
+
interface VercelBlobTokenOptions {
|
|
68
|
+
addRandomSuffix?: boolean;
|
|
69
|
+
allowedContentTypes?: string[];
|
|
70
|
+
maximumSizeInBytes?: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Callbacks provided to the Vercel Blob adapter when handling a request.
|
|
74
|
+
*/
|
|
75
|
+
interface VercelBlobHandlerCallbacks {
|
|
76
|
+
/**
|
|
77
|
+
* Called before a client token is generated.
|
|
78
|
+
* Throw to reject the upload (auth gate).
|
|
79
|
+
* Return options to enforce allowedContentTypes and maximumSizeInBytes at the edge.
|
|
80
|
+
*/
|
|
81
|
+
onBeforeGenerateToken?: (pathname: string, clientPayload: string | null) => Promise<VercelBlobTokenOptions | void> | VercelBlobTokenOptions | void;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Vercel Blob storage adapter — uses the `@vercel/blob/client` `handleUpload`
|
|
85
|
+
* protocol. The same endpoint handles both token generation and upload
|
|
86
|
+
* completion notifications from Vercel's servers.
|
|
87
|
+
*/
|
|
88
|
+
interface VercelBlobStorageAdapter {
|
|
89
|
+
readonly type: "vercel-blob";
|
|
90
|
+
/**
|
|
91
|
+
* Hostname suffix that all Vercel Blob public URLs end with.
|
|
92
|
+
* Used by the plugin to automatically validate client-supplied URLs.
|
|
93
|
+
* Always `".public.blob.vercel-storage.com"`.
|
|
94
|
+
*/
|
|
95
|
+
readonly urlHostnameSuffix: string;
|
|
96
|
+
/**
|
|
97
|
+
* Process a raw request from `@vercel/blob/client`'s `upload()` or from
|
|
98
|
+
* Vercel Blob's upload-completion webhook. Returns a JSON-serialisable object
|
|
99
|
+
* that should be sent back as the response body.
|
|
100
|
+
*/
|
|
101
|
+
handleRequest(request: Request, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
102
|
+
/**
|
|
103
|
+
* Remove the stored blob given its public URL.
|
|
104
|
+
*/
|
|
105
|
+
delete(url: string): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
type StorageAdapter = DirectStorageAdapter | S3StorageAdapter | VercelBlobStorageAdapter;
|
|
108
|
+
|
|
109
|
+
export type { DirectStorageAdapter as D, S3StorageAdapter as S, UploadOptions as U, VercelBlobStorageAdapter as V, StorageAdapter as a, S3UploadToken as b, VercelBlobHandlerCallbacks as c };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options provided to storage adapters when initiating an upload.
|
|
3
|
+
*/
|
|
4
|
+
interface UploadOptions {
|
|
5
|
+
filename: string;
|
|
6
|
+
mimeType: string;
|
|
7
|
+
size: number;
|
|
8
|
+
folderId?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Local storage adapter — backend receives and stores file bytes directly.
|
|
12
|
+
* Suitable for development and self-hosted deployments.
|
|
13
|
+
*/
|
|
14
|
+
interface DirectStorageAdapter {
|
|
15
|
+
readonly type: "local";
|
|
16
|
+
/**
|
|
17
|
+
* Store the file buffer and return the public URL.
|
|
18
|
+
*/
|
|
19
|
+
upload(buffer: Buffer, options: UploadOptions): Promise<{
|
|
20
|
+
url: string;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Remove the stored file given its public URL.
|
|
24
|
+
*/
|
|
25
|
+
delete(url: string): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Token returned by the S3 adapter.
|
|
29
|
+
* The client performs a `PUT` to `payload.uploadUrl` with the file body,
|
|
30
|
+
* then saves `payload.publicUrl` as the asset URL.
|
|
31
|
+
*/
|
|
32
|
+
interface S3UploadToken {
|
|
33
|
+
type: "presigned-url";
|
|
34
|
+
payload: {
|
|
35
|
+
uploadUrl: string;
|
|
36
|
+
publicUrl: string;
|
|
37
|
+
key: string;
|
|
38
|
+
method: "PUT";
|
|
39
|
+
headers: Record<string, string>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* S3 storage adapter — server issues a short-lived presigned PUT URL;
|
|
44
|
+
* the browser uploads directly to S3 (or R2 / MinIO).
|
|
45
|
+
*/
|
|
46
|
+
interface S3StorageAdapter {
|
|
47
|
+
readonly type: "s3";
|
|
48
|
+
/**
|
|
49
|
+
* The public base URL prefix for all assets in this bucket
|
|
50
|
+
* (e.g. `"https://assets.example.com"`). Used by the plugin to
|
|
51
|
+
* automatically validate client-supplied URLs when no explicit
|
|
52
|
+
* `allowedUrlPrefixes` are configured.
|
|
53
|
+
*/
|
|
54
|
+
readonly urlPrefix: string;
|
|
55
|
+
/**
|
|
56
|
+
* Generate a presigned PUT URL for direct client upload.
|
|
57
|
+
*/
|
|
58
|
+
generateUploadToken(options: UploadOptions): Promise<S3UploadToken>;
|
|
59
|
+
/**
|
|
60
|
+
* Remove the stored object given its public URL.
|
|
61
|
+
*/
|
|
62
|
+
delete(url: string): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Options returned from onBeforeGenerateToken and passed to Vercel Blob's handleUpload.
|
|
66
|
+
*/
|
|
67
|
+
interface VercelBlobTokenOptions {
|
|
68
|
+
addRandomSuffix?: boolean;
|
|
69
|
+
allowedContentTypes?: string[];
|
|
70
|
+
maximumSizeInBytes?: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Callbacks provided to the Vercel Blob adapter when handling a request.
|
|
74
|
+
*/
|
|
75
|
+
interface VercelBlobHandlerCallbacks {
|
|
76
|
+
/**
|
|
77
|
+
* Called before a client token is generated.
|
|
78
|
+
* Throw to reject the upload (auth gate).
|
|
79
|
+
* Return options to enforce allowedContentTypes and maximumSizeInBytes at the edge.
|
|
80
|
+
*/
|
|
81
|
+
onBeforeGenerateToken?: (pathname: string, clientPayload: string | null) => Promise<VercelBlobTokenOptions | void> | VercelBlobTokenOptions | void;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Vercel Blob storage adapter — uses the `@vercel/blob/client` `handleUpload`
|
|
85
|
+
* protocol. The same endpoint handles both token generation and upload
|
|
86
|
+
* completion notifications from Vercel's servers.
|
|
87
|
+
*/
|
|
88
|
+
interface VercelBlobStorageAdapter {
|
|
89
|
+
readonly type: "vercel-blob";
|
|
90
|
+
/**
|
|
91
|
+
* Hostname suffix that all Vercel Blob public URLs end with.
|
|
92
|
+
* Used by the plugin to automatically validate client-supplied URLs.
|
|
93
|
+
* Always `".public.blob.vercel-storage.com"`.
|
|
94
|
+
*/
|
|
95
|
+
readonly urlHostnameSuffix: string;
|
|
96
|
+
/**
|
|
97
|
+
* Process a raw request from `@vercel/blob/client`'s `upload()` or from
|
|
98
|
+
* Vercel Blob's upload-completion webhook. Returns a JSON-serialisable object
|
|
99
|
+
* that should be sent back as the response body.
|
|
100
|
+
*/
|
|
101
|
+
handleRequest(request: Request, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
102
|
+
/**
|
|
103
|
+
* Remove the stored blob given its public URL.
|
|
104
|
+
*/
|
|
105
|
+
delete(url: string): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
type StorageAdapter = DirectStorageAdapter | S3StorageAdapter | VercelBlobStorageAdapter;
|
|
108
|
+
|
|
109
|
+
export type { DirectStorageAdapter as D, S3StorageAdapter as S, UploadOptions as U, VercelBlobStorageAdapter as V, StorageAdapter as a, S3UploadToken as b, VercelBlobHandlerCallbacks as c };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { DBAdapter } from '@btst/db';
|
|
2
|
+
import { A as Asset, F as Folder } from './stack.CLcnSF_b.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parameters for filtering and paginating the asset list.
|
|
6
|
+
*/
|
|
7
|
+
interface AssetListParams {
|
|
8
|
+
folderId?: string;
|
|
9
|
+
mimeType?: string;
|
|
10
|
+
query?: string;
|
|
11
|
+
offset?: number;
|
|
12
|
+
limit?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Paginated result returned by {@link listAssets}.
|
|
16
|
+
*/
|
|
17
|
+
interface AssetListResult {
|
|
18
|
+
items: Asset[];
|
|
19
|
+
total: number;
|
|
20
|
+
limit?: number;
|
|
21
|
+
offset?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parameters for filtering the folder list.
|
|
25
|
+
*/
|
|
26
|
+
interface FolderListParams {
|
|
27
|
+
parentId?: string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Retrieve all assets matching optional filter criteria.
|
|
31
|
+
* Pure DB function — no hooks, no HTTP context. Safe for server-side use.
|
|
32
|
+
*
|
|
33
|
+
* @remarks **Security:** Authorization hooks are NOT called. The caller is
|
|
34
|
+
* responsible for any access-control checks before invoking this function.
|
|
35
|
+
*/
|
|
36
|
+
declare function listAssets(adapter: DBAdapter, params?: AssetListParams): Promise<AssetListResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Retrieve a single asset by its ID.
|
|
39
|
+
* Returns `null` if no asset is found.
|
|
40
|
+
* Pure DB function — no hooks, no HTTP context.
|
|
41
|
+
*
|
|
42
|
+
* @remarks **Security:** Authorization hooks are NOT called.
|
|
43
|
+
*/
|
|
44
|
+
declare function getAssetById(adapter: DBAdapter, id: string): Promise<Asset | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Retrieve all folders, optionally filtered by `parentId`.
|
|
47
|
+
* Pass `null` to list root-level folders (those without a parent).
|
|
48
|
+
* Pure DB function — no hooks, no HTTP context.
|
|
49
|
+
*
|
|
50
|
+
* @remarks **Security:** Authorization hooks are NOT called.
|
|
51
|
+
*/
|
|
52
|
+
declare function listFolders(adapter: DBAdapter, params?: FolderListParams): Promise<Folder[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Retrieve a single folder by its ID.
|
|
55
|
+
* Returns `null` if no folder is found.
|
|
56
|
+
* Pure DB function — no hooks, no HTTP context.
|
|
57
|
+
*
|
|
58
|
+
* @remarks **Security:** Authorization hooks are NOT called.
|
|
59
|
+
*/
|
|
60
|
+
declare function getFolderById(adapter: DBAdapter, id: string): Promise<Folder | null>;
|
|
61
|
+
|
|
62
|
+
export { listFolders as a, getFolderById as b, getAssetById as g, listAssets as l };
|
|
63
|
+
export type { AssetListParams as A, FolderListParams as F, AssetListResult as c };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { DBAdapter } from '@btst/db';
|
|
2
|
+
import { A as Asset, F as Folder } from './stack.CLcnSF_b.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parameters for filtering and paginating the asset list.
|
|
6
|
+
*/
|
|
7
|
+
interface AssetListParams {
|
|
8
|
+
folderId?: string;
|
|
9
|
+
mimeType?: string;
|
|
10
|
+
query?: string;
|
|
11
|
+
offset?: number;
|
|
12
|
+
limit?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Paginated result returned by {@link listAssets}.
|
|
16
|
+
*/
|
|
17
|
+
interface AssetListResult {
|
|
18
|
+
items: Asset[];
|
|
19
|
+
total: number;
|
|
20
|
+
limit?: number;
|
|
21
|
+
offset?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parameters for filtering the folder list.
|
|
25
|
+
*/
|
|
26
|
+
interface FolderListParams {
|
|
27
|
+
parentId?: string | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Retrieve all assets matching optional filter criteria.
|
|
31
|
+
* Pure DB function — no hooks, no HTTP context. Safe for server-side use.
|
|
32
|
+
*
|
|
33
|
+
* @remarks **Security:** Authorization hooks are NOT called. The caller is
|
|
34
|
+
* responsible for any access-control checks before invoking this function.
|
|
35
|
+
*/
|
|
36
|
+
declare function listAssets(adapter: DBAdapter, params?: AssetListParams): Promise<AssetListResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Retrieve a single asset by its ID.
|
|
39
|
+
* Returns `null` if no asset is found.
|
|
40
|
+
* Pure DB function — no hooks, no HTTP context.
|
|
41
|
+
*
|
|
42
|
+
* @remarks **Security:** Authorization hooks are NOT called.
|
|
43
|
+
*/
|
|
44
|
+
declare function getAssetById(adapter: DBAdapter, id: string): Promise<Asset | null>;
|
|
45
|
+
/**
|
|
46
|
+
* Retrieve all folders, optionally filtered by `parentId`.
|
|
47
|
+
* Pass `null` to list root-level folders (those without a parent).
|
|
48
|
+
* Pure DB function — no hooks, no HTTP context.
|
|
49
|
+
*
|
|
50
|
+
* @remarks **Security:** Authorization hooks are NOT called.
|
|
51
|
+
*/
|
|
52
|
+
declare function listFolders(adapter: DBAdapter, params?: FolderListParams): Promise<Folder[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Retrieve a single folder by its ID.
|
|
55
|
+
* Returns `null` if no folder is found.
|
|
56
|
+
* Pure DB function — no hooks, no HTTP context.
|
|
57
|
+
*
|
|
58
|
+
* @remarks **Security:** Authorization hooks are NOT called.
|
|
59
|
+
*/
|
|
60
|
+
declare function getFolderById(adapter: DBAdapter, id: string): Promise<Folder | null>;
|
|
61
|
+
|
|
62
|
+
export { listFolders as a, getFolderById as b, getAssetById as g, listAssets as l };
|
|
63
|
+
export type { AssetListParams as A, FolderListParams as F, AssetListResult as c };
|