@btst/stack 2.9.0 → 2.9.2
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/dist/packages/stack/src/plugins/media/api/plugin.cjs +1 -1
- package/dist/packages/stack/src/plugins/media/api/plugin.mjs +1 -1
- 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/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.d.cts +1 -1
- package/dist/plugins/media/api/adapters/s3.d.mts +1 -1
- package/dist/plugins/media/api/adapters/s3.d.ts +1 -1
- package/dist/plugins/media/api/adapters/vercel-blob.cjs +5 -7
- package/dist/plugins/media/api/adapters/vercel-blob.d.cts +3 -3
- package/dist/plugins/media/api/adapters/vercel-blob.d.mts +3 -3
- package/dist/plugins/media/api/adapters/vercel-blob.d.ts +3 -3
- package/dist/plugins/media/api/adapters/vercel-blob.mjs +5 -7
- package/dist/plugins/media/api/index.d.cts +3 -3
- package/dist/plugins/media/api/index.d.mts +3 -3
- package/dist/plugins/media/api/index.d.ts +3 -3
- package/dist/plugins/media/query-keys.d.cts +2 -2
- package/dist/plugins/media/query-keys.d.mts +2 -2
- package/dist/plugins/media/query-keys.d.ts +2 -2
- package/dist/shared/{stack.vxskCkim.d.cts → stack.BinHXe1r.d.cts} +1 -1
- package/dist/shared/{stack.BUTXWiG-.d.ts → stack.BjN_-cxo.d.ts} +1 -1
- package/dist/shared/{stack.CoBj86jf.d.ts → stack.DO6vOGQG.d.cts} +27 -2
- package/dist/shared/{stack.CoBj86jf.d.cts → stack.DO6vOGQG.d.mts} +27 -2
- package/dist/shared/{stack.CoBj86jf.d.mts → stack.DO6vOGQG.d.ts} +27 -2
- package/dist/shared/{stack.C7Y9sBDg.d.mts → stack.DYrJsJ7x.d.mts} +1 -1
- package/package.json +1 -1
- package/src/plugins/media/__tests__/__stubs__/vercel-blob-server.ts +1 -1
- package/src/plugins/media/__tests__/storage-adapters.test.ts +51 -7
- package/src/plugins/media/api/adapters/vercel-blob.ts +10 -11
- package/src/plugins/media/api/plugin.ts +1 -1
- package/src/plugins/media/api/storage-adapter.ts +33 -1
- package/dist/shared/{stack.D4Cea8II.d.ts → stack.CMbX8Q5C.d.ts} +13 -13
- package/dist/shared/{stack.HE_IvqV5.d.mts → stack.Dj04W2c3.d.mts} +13 -13
- package/dist/shared/{stack.Rtcvl8sS.d.cts → stack.eq5eg1yt.d.cts} +13 -13
|
@@ -472,7 +472,7 @@ const mediaBackendPlugin = (config) => api.defineBackendPlugin({
|
|
|
472
472
|
message: "Request object is not available"
|
|
473
473
|
});
|
|
474
474
|
}
|
|
475
|
-
return storageAdapter$1.handleRequest(ctx.request, {
|
|
475
|
+
return storageAdapter$1.handleRequest(ctx.request, ctx.body, {
|
|
476
476
|
onBeforeGenerateToken: async (pathname, clientPayload) => {
|
|
477
477
|
const filename = pathname.split("/").pop() ?? pathname;
|
|
478
478
|
let parsed = {};
|
|
@@ -470,7 +470,7 @@ const mediaBackendPlugin = (config) => defineBackendPlugin({
|
|
|
470
470
|
message: "Request object is not available"
|
|
471
471
|
});
|
|
472
472
|
}
|
|
473
|
-
return storageAdapter.handleRequest(ctx.request, {
|
|
473
|
+
return storageAdapter.handleRequest(ctx.request, ctx.body, {
|
|
474
474
|
onBeforeGenerateToken: async (pathname, clientPayload) => {
|
|
475
475
|
const filename = pathname.split("/").pop() ?? pathname;
|
|
476
476
|
let parsed = {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.
|
|
1
|
+
export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.eq5eg1yt.cjs';
|
|
2
2
|
import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.cjs';
|
|
3
3
|
import '@btst/stack/plugins/api';
|
|
4
4
|
import '@btst/db';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.
|
|
1
|
+
export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.Dj04W2c3.mjs';
|
|
2
2
|
import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.mjs';
|
|
3
3
|
import '@btst/stack/plugins/api';
|
|
4
4
|
import '@btst/db';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.
|
|
1
|
+
export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.CMbX8Q5C.js';
|
|
2
2
|
import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.js';
|
|
3
3
|
import '@btst/stack/plugins/api';
|
|
4
4
|
import '@btst/db';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.
|
|
2
|
+
import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.eq5eg1yt.cjs';
|
|
3
3
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
4
4
|
import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.cjs';
|
|
5
5
|
import '@btst/stack/plugins/api';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.
|
|
2
|
+
import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.Dj04W2c3.mjs';
|
|
3
3
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
4
4
|
import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.mjs';
|
|
5
5
|
import '@btst/stack/plugins/api';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.
|
|
2
|
+
import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.CMbX8Q5C.js';
|
|
3
3
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
4
4
|
import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.js';
|
|
5
5
|
import '@btst/stack/plugins/api';
|
|
@@ -4,21 +4,19 @@ function vercelBlobAdapter(options = {}) {
|
|
|
4
4
|
return {
|
|
5
5
|
type: "vercel-blob",
|
|
6
6
|
urlHostnameSuffix: ".public.blob.vercel-storage.com",
|
|
7
|
-
async handleRequest(request, callbacks) {
|
|
7
|
+
async handleRequest(request, body, callbacks) {
|
|
8
8
|
let handleUpload;
|
|
9
9
|
try {
|
|
10
|
-
const
|
|
10
|
+
const vercelBlobClient = (
|
|
11
11
|
/* @vite-ignore */
|
|
12
|
-
|
|
13
|
-
await import('@vercel/blob/server')
|
|
12
|
+
await import('@vercel/blob/client')
|
|
14
13
|
);
|
|
15
|
-
({ handleUpload } =
|
|
14
|
+
({ handleUpload } = vercelBlobClient);
|
|
16
15
|
} catch {
|
|
17
16
|
throw new Error(
|
|
18
|
-
"[@btst/stack] Vercel Blob adapter requires '@vercel/blob' with 'handleUpload' exported from '@vercel/blob/
|
|
17
|
+
"[@btst/stack] Vercel Blob adapter requires '@vercel/blob' with 'handleUpload' exported from '@vercel/blob/client'. Run: npm install @vercel/blob"
|
|
19
18
|
);
|
|
20
19
|
}
|
|
21
|
-
const body = await request.json();
|
|
22
20
|
return handleUpload({
|
|
23
21
|
body,
|
|
24
22
|
request,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { V as VercelBlobStorageAdapter } from '../../../../shared/stack.
|
|
1
|
+
import { V as VercelBlobStorageAdapter } from '../../../../shared/stack.DO6vOGQG.cjs';
|
|
2
2
|
|
|
3
3
|
interface VercelBlobStorageAdapterOptions {
|
|
4
4
|
/**
|
|
@@ -11,11 +11,11 @@ interface VercelBlobStorageAdapterOptions {
|
|
|
11
11
|
/**
|
|
12
12
|
* Create a Vercel Blob storage adapter using the signed direct-upload protocol.
|
|
13
13
|
* The server never receives file bytes — it only issues short-lived client tokens
|
|
14
|
-
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/
|
|
14
|
+
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/client`
|
|
15
15
|
* in compatible versions).
|
|
16
16
|
*
|
|
17
17
|
* @remarks Requires `@vercel/blob` as an optional peer dependency (version
|
|
18
|
-
* with `handleUpload` exported from `@vercel/blob/
|
|
18
|
+
* with `handleUpload` exported from `@vercel/blob/client`).
|
|
19
19
|
*
|
|
20
20
|
* Upload flow:
|
|
21
21
|
* 1. Client calls `POST /media/upload/vercel-blob` to obtain a client token.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { V as VercelBlobStorageAdapter } from '../../../../shared/stack.
|
|
1
|
+
import { V as VercelBlobStorageAdapter } from '../../../../shared/stack.DO6vOGQG.mjs';
|
|
2
2
|
|
|
3
3
|
interface VercelBlobStorageAdapterOptions {
|
|
4
4
|
/**
|
|
@@ -11,11 +11,11 @@ interface VercelBlobStorageAdapterOptions {
|
|
|
11
11
|
/**
|
|
12
12
|
* Create a Vercel Blob storage adapter using the signed direct-upload protocol.
|
|
13
13
|
* The server never receives file bytes — it only issues short-lived client tokens
|
|
14
|
-
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/
|
|
14
|
+
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/client`
|
|
15
15
|
* in compatible versions).
|
|
16
16
|
*
|
|
17
17
|
* @remarks Requires `@vercel/blob` as an optional peer dependency (version
|
|
18
|
-
* with `handleUpload` exported from `@vercel/blob/
|
|
18
|
+
* with `handleUpload` exported from `@vercel/blob/client`).
|
|
19
19
|
*
|
|
20
20
|
* Upload flow:
|
|
21
21
|
* 1. Client calls `POST /media/upload/vercel-blob` to obtain a client token.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { V as VercelBlobStorageAdapter } from '../../../../shared/stack.
|
|
1
|
+
import { V as VercelBlobStorageAdapter } from '../../../../shared/stack.DO6vOGQG.js';
|
|
2
2
|
|
|
3
3
|
interface VercelBlobStorageAdapterOptions {
|
|
4
4
|
/**
|
|
@@ -11,11 +11,11 @@ interface VercelBlobStorageAdapterOptions {
|
|
|
11
11
|
/**
|
|
12
12
|
* Create a Vercel Blob storage adapter using the signed direct-upload protocol.
|
|
13
13
|
* The server never receives file bytes — it only issues short-lived client tokens
|
|
14
|
-
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/
|
|
14
|
+
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/client`
|
|
15
15
|
* in compatible versions).
|
|
16
16
|
*
|
|
17
17
|
* @remarks Requires `@vercel/blob` as an optional peer dependency (version
|
|
18
|
-
* with `handleUpload` exported from `@vercel/blob/
|
|
18
|
+
* with `handleUpload` exported from `@vercel/blob/client`).
|
|
19
19
|
*
|
|
20
20
|
* Upload flow:
|
|
21
21
|
* 1. Client calls `POST /media/upload/vercel-blob` to obtain a client token.
|
|
@@ -2,21 +2,19 @@ function vercelBlobAdapter(options = {}) {
|
|
|
2
2
|
return {
|
|
3
3
|
type: "vercel-blob",
|
|
4
4
|
urlHostnameSuffix: ".public.blob.vercel-storage.com",
|
|
5
|
-
async handleRequest(request, callbacks) {
|
|
5
|
+
async handleRequest(request, body, callbacks) {
|
|
6
6
|
let handleUpload;
|
|
7
7
|
try {
|
|
8
|
-
const
|
|
8
|
+
const vercelBlobClient = (
|
|
9
9
|
/* @vite-ignore */
|
|
10
|
-
|
|
11
|
-
await import('@vercel/blob/server')
|
|
10
|
+
await import('@vercel/blob/client')
|
|
12
11
|
);
|
|
13
|
-
({ handleUpload } =
|
|
12
|
+
({ handleUpload } = vercelBlobClient);
|
|
14
13
|
} catch {
|
|
15
14
|
throw new Error(
|
|
16
|
-
"[@btst/stack] Vercel Blob adapter requires '@vercel/blob' with 'handleUpload' exported from '@vercel/blob/
|
|
15
|
+
"[@btst/stack] Vercel Blob adapter requires '@vercel/blob' with 'handleUpload' exported from '@vercel/blob/client'. Run: npm install @vercel/blob"
|
|
17
16
|
);
|
|
18
17
|
}
|
|
19
|
-
const body = await request.json();
|
|
20
18
|
return handleUpload({
|
|
21
19
|
body,
|
|
22
20
|
request,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { a as MEDIA_QUERY_KEYS, c as MediaApiContext, M as MediaApiRouter, e as MediaBackendConfig, d as MediaBackendHooks, b as assetListDiscriminator, m as mediaBackendPlugin } from '../../../shared/stack.
|
|
1
|
+
export { a as MEDIA_QUERY_KEYS, c as MediaApiContext, M as MediaApiRouter, e as MediaBackendConfig, d as MediaBackendHooks, b as assetListDiscriminator, m as mediaBackendPlugin } from '../../../shared/stack.BinHXe1r.cjs';
|
|
2
2
|
export { A as AssetListParams, c as AssetListResult, F as FolderListParams, g as getAssetById, b as getFolderById, l as listAssets, a as listFolders } from '../../../shared/stack.CAni8dnD.cjs';
|
|
3
3
|
import { DBAdapter } from '@btst/db';
|
|
4
4
|
import { A as Asset, F as Folder, S as SerializedAsset, a as SerializedFolder } from '../../../shared/stack.CLcnSF_b.cjs';
|
|
5
|
-
import { D as DirectStorageAdapter } from '../../../shared/stack.
|
|
6
|
-
export { S as S3StorageAdapter, b as S3UploadToken, a as StorageAdapter, U as UploadOptions, c as VercelBlobHandlerCallbacks, V as VercelBlobStorageAdapter } from '../../../shared/stack.
|
|
5
|
+
import { D as DirectStorageAdapter } from '../../../shared/stack.DO6vOGQG.cjs';
|
|
6
|
+
export { S as S3StorageAdapter, b as S3UploadToken, a as StorageAdapter, U as UploadOptions, c as VercelBlobHandlerCallbacks, V as VercelBlobStorageAdapter } from '../../../shared/stack.DO6vOGQG.cjs';
|
|
7
7
|
import '@btst/stack/plugins/api';
|
|
8
8
|
import 'better-call';
|
|
9
9
|
import 'zod';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { a as MEDIA_QUERY_KEYS, c as MediaApiContext, M as MediaApiRouter, e as MediaBackendConfig, d as MediaBackendHooks, b as assetListDiscriminator, m as mediaBackendPlugin } from '../../../shared/stack.
|
|
1
|
+
export { a as MEDIA_QUERY_KEYS, c as MediaApiContext, M as MediaApiRouter, e as MediaBackendConfig, d as MediaBackendHooks, b as assetListDiscriminator, m as mediaBackendPlugin } from '../../../shared/stack.DYrJsJ7x.mjs';
|
|
2
2
|
export { A as AssetListParams, c as AssetListResult, F as FolderListParams, g as getAssetById, b as getFolderById, l as listAssets, a as listFolders } from '../../../shared/stack.C7vfOBmO.mjs';
|
|
3
3
|
import { DBAdapter } from '@btst/db';
|
|
4
4
|
import { A as Asset, F as Folder, S as SerializedAsset, a as SerializedFolder } from '../../../shared/stack.CLcnSF_b.mjs';
|
|
5
|
-
import { D as DirectStorageAdapter } from '../../../shared/stack.
|
|
6
|
-
export { S as S3StorageAdapter, b as S3UploadToken, a as StorageAdapter, U as UploadOptions, c as VercelBlobHandlerCallbacks, V as VercelBlobStorageAdapter } from '../../../shared/stack.
|
|
5
|
+
import { D as DirectStorageAdapter } from '../../../shared/stack.DO6vOGQG.mjs';
|
|
6
|
+
export { S as S3StorageAdapter, b as S3UploadToken, a as StorageAdapter, U as UploadOptions, c as VercelBlobHandlerCallbacks, V as VercelBlobStorageAdapter } from '../../../shared/stack.DO6vOGQG.mjs';
|
|
7
7
|
import '@btst/stack/plugins/api';
|
|
8
8
|
import 'better-call';
|
|
9
9
|
import 'zod';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { a as MEDIA_QUERY_KEYS, c as MediaApiContext, M as MediaApiRouter, e as MediaBackendConfig, d as MediaBackendHooks, b as assetListDiscriminator, m as mediaBackendPlugin } from '../../../shared/stack.
|
|
1
|
+
export { a as MEDIA_QUERY_KEYS, c as MediaApiContext, M as MediaApiRouter, e as MediaBackendConfig, d as MediaBackendHooks, b as assetListDiscriminator, m as mediaBackendPlugin } from '../../../shared/stack.BjN_-cxo.js';
|
|
2
2
|
export { A as AssetListParams, c as AssetListResult, F as FolderListParams, g as getAssetById, b as getFolderById, l as listAssets, a as listFolders } from '../../../shared/stack.CYSwntXC.js';
|
|
3
3
|
import { DBAdapter } from '@btst/db';
|
|
4
4
|
import { A as Asset, F as Folder, S as SerializedAsset, a as SerializedFolder } from '../../../shared/stack.CLcnSF_b.js';
|
|
5
|
-
import { D as DirectStorageAdapter } from '../../../shared/stack.
|
|
6
|
-
export { S as S3StorageAdapter, b as S3UploadToken, a as StorageAdapter, U as UploadOptions, c as VercelBlobHandlerCallbacks, V as VercelBlobStorageAdapter } from '../../../shared/stack.
|
|
5
|
+
import { D as DirectStorageAdapter } from '../../../shared/stack.DO6vOGQG.js';
|
|
6
|
+
export { S as S3StorageAdapter, b as S3UploadToken, a as StorageAdapter, U as UploadOptions, c as VercelBlobHandlerCallbacks, V as VercelBlobStorageAdapter } from '../../../shared/stack.DO6vOGQG.js';
|
|
7
7
|
import '@btst/stack/plugins/api';
|
|
8
8
|
import 'better-call';
|
|
9
9
|
import 'zod';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { M as MediaApiRouter, A as AssetListDiscriminator } from '../../shared/stack.
|
|
2
|
+
import { M as MediaApiRouter, A as AssetListDiscriminator } from '../../shared/stack.BinHXe1r.cjs';
|
|
3
3
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
4
4
|
import { S as SerializedAsset, a as SerializedFolder } from '../../shared/stack.CLcnSF_b.cjs';
|
|
5
5
|
import { A as AssetListParams } from '../../shared/stack.CAni8dnD.cjs';
|
|
6
6
|
import '@btst/stack/plugins/api';
|
|
7
|
-
import '../../shared/stack.
|
|
7
|
+
import '../../shared/stack.DO6vOGQG.cjs';
|
|
8
8
|
import 'better-call';
|
|
9
9
|
import 'zod';
|
|
10
10
|
import '@btst/db';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { M as MediaApiRouter, A as AssetListDiscriminator } from '../../shared/stack.
|
|
2
|
+
import { M as MediaApiRouter, A as AssetListDiscriminator } from '../../shared/stack.DYrJsJ7x.mjs';
|
|
3
3
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
4
4
|
import { S as SerializedAsset, a as SerializedFolder } from '../../shared/stack.CLcnSF_b.mjs';
|
|
5
5
|
import { A as AssetListParams } from '../../shared/stack.C7vfOBmO.mjs';
|
|
6
6
|
import '@btst/stack/plugins/api';
|
|
7
|
-
import '../../shared/stack.
|
|
7
|
+
import '../../shared/stack.DO6vOGQG.mjs';
|
|
8
8
|
import 'better-call';
|
|
9
9
|
import 'zod';
|
|
10
10
|
import '@btst/db';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
2
|
-
import { M as MediaApiRouter, A as AssetListDiscriminator } from '../../shared/stack.
|
|
2
|
+
import { M as MediaApiRouter, A as AssetListDiscriminator } from '../../shared/stack.BjN_-cxo.js';
|
|
3
3
|
import { createApiClient } from '@btst/stack/plugins/client';
|
|
4
4
|
import { S as SerializedAsset, a as SerializedFolder } from '../../shared/stack.CLcnSF_b.js';
|
|
5
5
|
import { A as AssetListParams } from '../../shared/stack.CYSwntXC.js';
|
|
6
6
|
import '@btst/stack/plugins/api';
|
|
7
|
-
import '../../shared/stack.
|
|
7
|
+
import '../../shared/stack.DO6vOGQG.js';
|
|
8
8
|
import 'better-call';
|
|
9
9
|
import 'zod';
|
|
10
10
|
import '@btst/db';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
|
-
import { a as StorageAdapter, b as S3UploadToken } from './stack.
|
|
2
|
+
import { a as StorageAdapter, b as S3UploadToken } from './stack.DO6vOGQG.cjs';
|
|
3
3
|
import { c as AssetListResult, l as listAssets, a as listFolders, A as AssetListParams } from './stack.CAni8dnD.cjs';
|
|
4
4
|
import * as better_call from 'better-call';
|
|
5
5
|
import { z } from 'zod';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
|
-
import { a as StorageAdapter, b as S3UploadToken } from './stack.
|
|
2
|
+
import { a as StorageAdapter, b as S3UploadToken } from './stack.DO6vOGQG.js';
|
|
3
3
|
import { c as AssetListResult, l as listAssets, a as listFolders, A as AssetListParams } from './stack.CYSwntXC.js';
|
|
4
4
|
import * as better_call from 'better-call';
|
|
5
5
|
import { z } from 'zod';
|
|
@@ -69,6 +69,31 @@ interface VercelBlobTokenOptions {
|
|
|
69
69
|
allowedContentTypes?: string[];
|
|
70
70
|
maximumSizeInBytes?: number;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Minimal blob metadata sent back by Vercel Blob's upload completion callback.
|
|
74
|
+
* Keep this intentionally small so BTST does not hard-depend on a specific SDK type.
|
|
75
|
+
*/
|
|
76
|
+
interface VercelBlobCallbackBlob {
|
|
77
|
+
url: string;
|
|
78
|
+
pathname: string;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
81
|
+
interface VercelBlobGenerateClientTokenBody {
|
|
82
|
+
type: "blob.generate-client-token";
|
|
83
|
+
payload: {
|
|
84
|
+
pathname: string;
|
|
85
|
+
multipart: boolean;
|
|
86
|
+
clientPayload: string | null;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
interface VercelBlobUploadCompletedBody {
|
|
90
|
+
type: "blob.upload-completed";
|
|
91
|
+
payload: {
|
|
92
|
+
blob: VercelBlobCallbackBlob;
|
|
93
|
+
tokenPayload?: string | null;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
type VercelBlobHandleUploadBody = VercelBlobGenerateClientTokenBody | VercelBlobUploadCompletedBody;
|
|
72
97
|
/**
|
|
73
98
|
* Callbacks provided to the Vercel Blob adapter when handling a request.
|
|
74
99
|
*/
|
|
@@ -81,7 +106,7 @@ interface VercelBlobHandlerCallbacks {
|
|
|
81
106
|
onBeforeGenerateToken?: (pathname: string, clientPayload: string | null) => Promise<VercelBlobTokenOptions | void> | VercelBlobTokenOptions | void;
|
|
82
107
|
}
|
|
83
108
|
/**
|
|
84
|
-
* Vercel Blob storage adapter — uses the `@vercel/blob/
|
|
109
|
+
* Vercel Blob storage adapter — uses the `@vercel/blob/client` `handleUpload`
|
|
85
110
|
* protocol. The same endpoint handles both token generation and upload
|
|
86
111
|
* completion notifications from Vercel's servers.
|
|
87
112
|
*/
|
|
@@ -98,7 +123,7 @@ interface VercelBlobStorageAdapter {
|
|
|
98
123
|
* Vercel Blob's upload-completion webhook. Returns a JSON-serialisable object
|
|
99
124
|
* that should be sent back as the response body.
|
|
100
125
|
*/
|
|
101
|
-
handleRequest(request: Request, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
126
|
+
handleRequest(request: Request, body: VercelBlobHandleUploadBody, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
102
127
|
/**
|
|
103
128
|
* Remove the stored blob given its public URL.
|
|
104
129
|
*/
|
|
@@ -69,6 +69,31 @@ interface VercelBlobTokenOptions {
|
|
|
69
69
|
allowedContentTypes?: string[];
|
|
70
70
|
maximumSizeInBytes?: number;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Minimal blob metadata sent back by Vercel Blob's upload completion callback.
|
|
74
|
+
* Keep this intentionally small so BTST does not hard-depend on a specific SDK type.
|
|
75
|
+
*/
|
|
76
|
+
interface VercelBlobCallbackBlob {
|
|
77
|
+
url: string;
|
|
78
|
+
pathname: string;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
81
|
+
interface VercelBlobGenerateClientTokenBody {
|
|
82
|
+
type: "blob.generate-client-token";
|
|
83
|
+
payload: {
|
|
84
|
+
pathname: string;
|
|
85
|
+
multipart: boolean;
|
|
86
|
+
clientPayload: string | null;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
interface VercelBlobUploadCompletedBody {
|
|
90
|
+
type: "blob.upload-completed";
|
|
91
|
+
payload: {
|
|
92
|
+
blob: VercelBlobCallbackBlob;
|
|
93
|
+
tokenPayload?: string | null;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
type VercelBlobHandleUploadBody = VercelBlobGenerateClientTokenBody | VercelBlobUploadCompletedBody;
|
|
72
97
|
/**
|
|
73
98
|
* Callbacks provided to the Vercel Blob adapter when handling a request.
|
|
74
99
|
*/
|
|
@@ -81,7 +106,7 @@ interface VercelBlobHandlerCallbacks {
|
|
|
81
106
|
onBeforeGenerateToken?: (pathname: string, clientPayload: string | null) => Promise<VercelBlobTokenOptions | void> | VercelBlobTokenOptions | void;
|
|
82
107
|
}
|
|
83
108
|
/**
|
|
84
|
-
* Vercel Blob storage adapter — uses the `@vercel/blob/
|
|
109
|
+
* Vercel Blob storage adapter — uses the `@vercel/blob/client` `handleUpload`
|
|
85
110
|
* protocol. The same endpoint handles both token generation and upload
|
|
86
111
|
* completion notifications from Vercel's servers.
|
|
87
112
|
*/
|
|
@@ -98,7 +123,7 @@ interface VercelBlobStorageAdapter {
|
|
|
98
123
|
* Vercel Blob's upload-completion webhook. Returns a JSON-serialisable object
|
|
99
124
|
* that should be sent back as the response body.
|
|
100
125
|
*/
|
|
101
|
-
handleRequest(request: Request, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
126
|
+
handleRequest(request: Request, body: VercelBlobHandleUploadBody, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
102
127
|
/**
|
|
103
128
|
* Remove the stored blob given its public URL.
|
|
104
129
|
*/
|
|
@@ -69,6 +69,31 @@ interface VercelBlobTokenOptions {
|
|
|
69
69
|
allowedContentTypes?: string[];
|
|
70
70
|
maximumSizeInBytes?: number;
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Minimal blob metadata sent back by Vercel Blob's upload completion callback.
|
|
74
|
+
* Keep this intentionally small so BTST does not hard-depend on a specific SDK type.
|
|
75
|
+
*/
|
|
76
|
+
interface VercelBlobCallbackBlob {
|
|
77
|
+
url: string;
|
|
78
|
+
pathname: string;
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
}
|
|
81
|
+
interface VercelBlobGenerateClientTokenBody {
|
|
82
|
+
type: "blob.generate-client-token";
|
|
83
|
+
payload: {
|
|
84
|
+
pathname: string;
|
|
85
|
+
multipart: boolean;
|
|
86
|
+
clientPayload: string | null;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
interface VercelBlobUploadCompletedBody {
|
|
90
|
+
type: "blob.upload-completed";
|
|
91
|
+
payload: {
|
|
92
|
+
blob: VercelBlobCallbackBlob;
|
|
93
|
+
tokenPayload?: string | null;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
type VercelBlobHandleUploadBody = VercelBlobGenerateClientTokenBody | VercelBlobUploadCompletedBody;
|
|
72
97
|
/**
|
|
73
98
|
* Callbacks provided to the Vercel Blob adapter when handling a request.
|
|
74
99
|
*/
|
|
@@ -81,7 +106,7 @@ interface VercelBlobHandlerCallbacks {
|
|
|
81
106
|
onBeforeGenerateToken?: (pathname: string, clientPayload: string | null) => Promise<VercelBlobTokenOptions | void> | VercelBlobTokenOptions | void;
|
|
82
107
|
}
|
|
83
108
|
/**
|
|
84
|
-
* Vercel Blob storage adapter — uses the `@vercel/blob/
|
|
109
|
+
* Vercel Blob storage adapter — uses the `@vercel/blob/client` `handleUpload`
|
|
85
110
|
* protocol. The same endpoint handles both token generation and upload
|
|
86
111
|
* completion notifications from Vercel's servers.
|
|
87
112
|
*/
|
|
@@ -98,7 +123,7 @@ interface VercelBlobStorageAdapter {
|
|
|
98
123
|
* Vercel Blob's upload-completion webhook. Returns a JSON-serialisable object
|
|
99
124
|
* that should be sent back as the response body.
|
|
100
125
|
*/
|
|
101
|
-
handleRequest(request: Request, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
126
|
+
handleRequest(request: Request, body: VercelBlobHandleUploadBody, callbacks: VercelBlobHandlerCallbacks): Promise<unknown>;
|
|
102
127
|
/**
|
|
103
128
|
* Remove the stored blob given its public URL.
|
|
104
129
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
|
-
import { a as StorageAdapter, b as S3UploadToken } from './stack.
|
|
2
|
+
import { a as StorageAdapter, b as S3UploadToken } from './stack.DO6vOGQG.mjs';
|
|
3
3
|
import { c as AssetListResult, l as listAssets, a as listFolders, A as AssetListParams } from './stack.C7vfOBmO.mjs';
|
|
4
4
|
import * as better_call from 'better-call';
|
|
5
5
|
import { z } from 'zod';
|
package/package.json
CHANGED
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export async function handleUpload(_options: unknown): Promise<unknown> {
|
|
6
6
|
throw new Error(
|
|
7
|
-
"handleUpload is not available in the installed @vercel/blob version.
|
|
7
|
+
"handleUpload is not available in the installed @vercel/blob version. BTST requires a version that exports @vercel/blob/server.",
|
|
8
8
|
);
|
|
9
9
|
}
|
|
@@ -2,6 +2,7 @@ import { describe, it, expect, vi, afterEach } from "vitest";
|
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import * as os from "node:os";
|
|
5
|
+
import type { VercelBlobHandleUploadBody } from "../api/storage-adapter";
|
|
5
6
|
|
|
6
7
|
// Top-level vi.mock calls are hoisted by Vitest before any imports.
|
|
7
8
|
// Factories are used so the packages do not need to be installed as devDependencies.
|
|
@@ -36,7 +37,7 @@ vi.mock("@aws-sdk/s3-request-presigner", () => ({
|
|
|
36
37
|
getSignedUrl: mockGetSignedUrl,
|
|
37
38
|
}));
|
|
38
39
|
|
|
39
|
-
vi.mock("@vercel/blob/
|
|
40
|
+
vi.mock("@vercel/blob/client", () => ({
|
|
40
41
|
handleUpload: mockHandleUpload,
|
|
41
42
|
}));
|
|
42
43
|
|
|
@@ -271,9 +272,13 @@ describe("vercelBlobAdapter", () => {
|
|
|
271
272
|
const { vercelBlobAdapter } = await import("../api/adapters/vercel-blob");
|
|
272
273
|
const adapter = vercelBlobAdapter();
|
|
273
274
|
|
|
274
|
-
const body = {
|
|
275
|
+
const body: VercelBlobHandleUploadBody = {
|
|
275
276
|
type: "blob.generate-client-token",
|
|
276
|
-
payload: {
|
|
277
|
+
payload: {
|
|
278
|
+
pathname: "photo.jpg",
|
|
279
|
+
multipart: false,
|
|
280
|
+
clientPayload: null,
|
|
281
|
+
},
|
|
277
282
|
};
|
|
278
283
|
const request = new Request("https://example.com/api/upload", {
|
|
279
284
|
method: "POST",
|
|
@@ -281,7 +286,7 @@ describe("vercelBlobAdapter", () => {
|
|
|
281
286
|
headers: { "Content-Type": "application/json" },
|
|
282
287
|
});
|
|
283
288
|
|
|
284
|
-
const result = await adapter.handleRequest(request, {});
|
|
289
|
+
const result = await adapter.handleRequest(request, body, {});
|
|
285
290
|
|
|
286
291
|
expect(mockHandleUpload).toHaveBeenCalledWith(
|
|
287
292
|
expect.objectContaining({
|
|
@@ -300,9 +305,13 @@ describe("vercelBlobAdapter", () => {
|
|
|
300
305
|
const adapter = vercelBlobAdapter();
|
|
301
306
|
|
|
302
307
|
const onBeforeGenerateToken = vi.fn().mockResolvedValue(undefined);
|
|
303
|
-
const body = {
|
|
308
|
+
const body: VercelBlobHandleUploadBody = {
|
|
304
309
|
type: "blob.generate-client-token",
|
|
305
|
-
payload: {
|
|
310
|
+
payload: {
|
|
311
|
+
pathname: "test.jpg",
|
|
312
|
+
multipart: false,
|
|
313
|
+
clientPayload: null,
|
|
314
|
+
},
|
|
306
315
|
};
|
|
307
316
|
const request = new Request("https://example.com/api/upload", {
|
|
308
317
|
method: "POST",
|
|
@@ -310,7 +319,7 @@ describe("vercelBlobAdapter", () => {
|
|
|
310
319
|
headers: { "Content-Type": "application/json" },
|
|
311
320
|
});
|
|
312
321
|
|
|
313
|
-
await adapter.handleRequest(request, { onBeforeGenerateToken });
|
|
322
|
+
await adapter.handleRequest(request, body, { onBeforeGenerateToken });
|
|
314
323
|
|
|
315
324
|
// Verify that handleUpload received an onBeforeGenerateToken callback
|
|
316
325
|
const callArgs = mockHandleUpload.mock.calls[0]![0] as Record<
|
|
@@ -325,6 +334,41 @@ describe("vercelBlobAdapter", () => {
|
|
|
325
334
|
expect(onBeforeGenerateToken).toHaveBeenCalledWith("test.jpg", null);
|
|
326
335
|
});
|
|
327
336
|
|
|
337
|
+
it("reuses the already-parsed request body without reading the request again", async () => {
|
|
338
|
+
const { vercelBlobAdapter } = await import("../api/adapters/vercel-blob");
|
|
339
|
+
const adapter = vercelBlobAdapter();
|
|
340
|
+
|
|
341
|
+
const body: VercelBlobHandleUploadBody = {
|
|
342
|
+
type: "blob.generate-client-token",
|
|
343
|
+
payload: {
|
|
344
|
+
pathname: "consumed.jpg",
|
|
345
|
+
multipart: false,
|
|
346
|
+
clientPayload: null,
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
const request = new Request("https://example.com/api/upload", {
|
|
350
|
+
method: "POST",
|
|
351
|
+
body: JSON.stringify(body),
|
|
352
|
+
headers: { "Content-Type": "application/json" },
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Simulate the BTST route layer parsing the request before the adapter runs.
|
|
356
|
+
const parsedBody = await request.json();
|
|
357
|
+
|
|
358
|
+
const result = await adapter.handleRequest(request, parsedBody, {});
|
|
359
|
+
|
|
360
|
+
expect(mockHandleUpload).toHaveBeenCalledWith(
|
|
361
|
+
expect.objectContaining({
|
|
362
|
+
body: parsedBody,
|
|
363
|
+
request,
|
|
364
|
+
}),
|
|
365
|
+
);
|
|
366
|
+
expect(result).toEqual({
|
|
367
|
+
type: "blob.generate-client-token",
|
|
368
|
+
clientToken: "tok123",
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
|
|
328
372
|
it("calls del when deleting a blob by URL", async () => {
|
|
329
373
|
const { vercelBlobAdapter } = await import("../api/adapters/vercel-blob");
|
|
330
374
|
const adapter = vercelBlobAdapter();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
VercelBlobStorageAdapter,
|
|
3
3
|
VercelBlobHandlerCallbacks,
|
|
4
|
+
VercelBlobHandleUploadBody,
|
|
4
5
|
} from "../storage-adapter";
|
|
5
6
|
|
|
6
7
|
export interface VercelBlobStorageAdapterOptions {
|
|
@@ -13,11 +14,11 @@ export interface VercelBlobStorageAdapterOptions {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
|
-
* Minimal subset of the `@vercel/blob/
|
|
17
|
+
* Minimal subset of the `@vercel/blob/client` `handleUpload` options.
|
|
17
18
|
* Defined inline so we do not hard-depend on a specific `@vercel/blob` release.
|
|
18
19
|
*/
|
|
19
20
|
interface HandleUploadOptions {
|
|
20
|
-
body:
|
|
21
|
+
body: VercelBlobHandleUploadBody;
|
|
21
22
|
request: Request;
|
|
22
23
|
token?: string;
|
|
23
24
|
onBeforeGenerateToken: (
|
|
@@ -40,11 +41,11 @@ type DelFn = (url: string, options?: { token?: string }) => Promise<void>;
|
|
|
40
41
|
/**
|
|
41
42
|
* Create a Vercel Blob storage adapter using the signed direct-upload protocol.
|
|
42
43
|
* The server never receives file bytes — it only issues short-lived client tokens
|
|
43
|
-
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/
|
|
44
|
+
* via `@vercel/blob`'s `handleUpload` helper (available via `@vercel/blob/client`
|
|
44
45
|
* in compatible versions).
|
|
45
46
|
*
|
|
46
47
|
* @remarks Requires `@vercel/blob` as an optional peer dependency (version
|
|
47
|
-
* with `handleUpload` exported from `@vercel/blob/
|
|
48
|
+
* with `handleUpload` exported from `@vercel/blob/client`).
|
|
48
49
|
*
|
|
49
50
|
* Upload flow:
|
|
50
51
|
* 1. Client calls `POST /media/upload/vercel-blob` to obtain a client token.
|
|
@@ -73,27 +74,25 @@ export function vercelBlobAdapter(
|
|
|
73
74
|
|
|
74
75
|
async handleRequest(
|
|
75
76
|
request: Request,
|
|
77
|
+
body: VercelBlobHandleUploadBody,
|
|
76
78
|
callbacks: VercelBlobHandlerCallbacks,
|
|
77
79
|
): Promise<unknown> {
|
|
78
80
|
let handleUpload: HandleUploadFn;
|
|
79
81
|
try {
|
|
80
|
-
const
|
|
82
|
+
const vercelBlobClient =
|
|
81
83
|
/* @vite-ignore */
|
|
82
|
-
|
|
83
|
-
(await import("@vercel/blob/server")) as {
|
|
84
|
+
(await import("@vercel/blob/client")) as unknown as {
|
|
84
85
|
handleUpload: HandleUploadFn;
|
|
85
86
|
};
|
|
86
|
-
({ handleUpload } =
|
|
87
|
+
({ handleUpload } = vercelBlobClient);
|
|
87
88
|
} catch {
|
|
88
89
|
throw new Error(
|
|
89
90
|
"[@btst/stack] Vercel Blob adapter requires '@vercel/blob' with " +
|
|
90
|
-
"'handleUpload' exported from '@vercel/blob/
|
|
91
|
+
"'handleUpload' exported from '@vercel/blob/client'. " +
|
|
91
92
|
"Run: npm install @vercel/blob",
|
|
92
93
|
);
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
const body = await request.json();
|
|
96
|
-
|
|
97
96
|
return handleUpload({
|
|
98
97
|
body,
|
|
99
98
|
request,
|
|
@@ -788,7 +788,7 @@ export const mediaBackendPlugin = (config: MediaBackendConfig) =>
|
|
|
788
788
|
});
|
|
789
789
|
}
|
|
790
790
|
|
|
791
|
-
return storageAdapter.handleRequest(ctx.request, {
|
|
791
|
+
return storageAdapter.handleRequest(ctx.request, ctx.body, {
|
|
792
792
|
onBeforeGenerateToken: async (pathname, clientPayload) => {
|
|
793
793
|
const filename = pathname.split("/").pop() ?? pathname;
|
|
794
794
|
let parsed: Record<string, unknown> = {};
|
|
@@ -72,6 +72,37 @@ export interface VercelBlobTokenOptions {
|
|
|
72
72
|
maximumSizeInBytes?: number;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Minimal blob metadata sent back by Vercel Blob's upload completion callback.
|
|
77
|
+
* Keep this intentionally small so BTST does not hard-depend on a specific SDK type.
|
|
78
|
+
*/
|
|
79
|
+
export interface VercelBlobCallbackBlob {
|
|
80
|
+
url: string;
|
|
81
|
+
pathname: string;
|
|
82
|
+
[key: string]: unknown;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface VercelBlobGenerateClientTokenBody {
|
|
86
|
+
type: "blob.generate-client-token";
|
|
87
|
+
payload: {
|
|
88
|
+
pathname: string;
|
|
89
|
+
multipart: boolean;
|
|
90
|
+
clientPayload: string | null;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface VercelBlobUploadCompletedBody {
|
|
95
|
+
type: "blob.upload-completed";
|
|
96
|
+
payload: {
|
|
97
|
+
blob: VercelBlobCallbackBlob;
|
|
98
|
+
tokenPayload?: string | null;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type VercelBlobHandleUploadBody =
|
|
103
|
+
| VercelBlobGenerateClientTokenBody
|
|
104
|
+
| VercelBlobUploadCompletedBody;
|
|
105
|
+
|
|
75
106
|
/**
|
|
76
107
|
* Callbacks provided to the Vercel Blob adapter when handling a request.
|
|
77
108
|
*/
|
|
@@ -88,7 +119,7 @@ export interface VercelBlobHandlerCallbacks {
|
|
|
88
119
|
}
|
|
89
120
|
|
|
90
121
|
/**
|
|
91
|
-
* Vercel Blob storage adapter — uses the `@vercel/blob/
|
|
122
|
+
* Vercel Blob storage adapter — uses the `@vercel/blob/client` `handleUpload`
|
|
92
123
|
* protocol. The same endpoint handles both token generation and upload
|
|
93
124
|
* completion notifications from Vercel's servers.
|
|
94
125
|
*/
|
|
@@ -107,6 +138,7 @@ export interface VercelBlobStorageAdapter {
|
|
|
107
138
|
*/
|
|
108
139
|
handleRequest(
|
|
109
140
|
request: Request,
|
|
141
|
+
body: VercelBlobHandleUploadBody,
|
|
110
142
|
callbacks: VercelBlobHandlerCallbacks,
|
|
111
143
|
): Promise<unknown>;
|
|
112
144
|
/**
|
|
@@ -8,11 +8,11 @@ import { QueryClient } from '@tanstack/react-query';
|
|
|
8
8
|
declare const createBoardSchema: z.ZodObject<{
|
|
9
9
|
description: z.ZodOptional<z.ZodString>;
|
|
10
10
|
name: z.ZodString;
|
|
11
|
-
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
12
|
-
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
13
11
|
slug: z.ZodOptional<z.ZodString>;
|
|
14
12
|
ownerId: z.ZodOptional<z.ZodString>;
|
|
15
13
|
organizationId: z.ZodOptional<z.ZodString>;
|
|
14
|
+
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
15
|
+
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
16
16
|
}, z.core.$strip>;
|
|
17
17
|
declare const updateBoardSchema: z.ZodObject<{
|
|
18
18
|
createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
|
|
@@ -26,10 +26,10 @@ declare const updateBoardSchema: z.ZodObject<{
|
|
|
26
26
|
}, z.core.$strip>;
|
|
27
27
|
declare const createColumnSchema: z.ZodObject<{
|
|
28
28
|
title: z.ZodString;
|
|
29
|
+
boardId: z.ZodString;
|
|
29
30
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
30
31
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
31
32
|
order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
32
|
-
boardId: z.ZodString;
|
|
33
33
|
}, z.core.$strip>;
|
|
34
34
|
declare const updateColumnSchema: z.ZodObject<{
|
|
35
35
|
createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
|
|
@@ -331,19 +331,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
331
331
|
body: better_call.StandardSchemaV1<{
|
|
332
332
|
name: string;
|
|
333
333
|
description?: string | undefined;
|
|
334
|
-
createdAt?: unknown;
|
|
335
|
-
updatedAt?: unknown;
|
|
336
334
|
slug?: string | undefined;
|
|
337
335
|
ownerId?: string | undefined;
|
|
338
336
|
organizationId?: string | undefined;
|
|
337
|
+
createdAt?: unknown;
|
|
338
|
+
updatedAt?: unknown;
|
|
339
339
|
}, {
|
|
340
340
|
name: string;
|
|
341
341
|
description?: string | undefined;
|
|
342
|
-
createdAt?: unknown;
|
|
343
|
-
updatedAt?: unknown;
|
|
344
342
|
slug?: string | undefined;
|
|
345
343
|
ownerId?: string | undefined;
|
|
346
344
|
organizationId?: string | undefined;
|
|
345
|
+
createdAt?: unknown;
|
|
346
|
+
updatedAt?: unknown;
|
|
347
347
|
}>;
|
|
348
348
|
}, {
|
|
349
349
|
columns: ColumnWithTasks[];
|
|
@@ -361,19 +361,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
361
361
|
body: better_call.StandardSchemaV1<{
|
|
362
362
|
description?: string | undefined;
|
|
363
363
|
name?: string | undefined;
|
|
364
|
-
createdAt?: unknown;
|
|
365
|
-
updatedAt?: unknown;
|
|
366
364
|
slug?: string | undefined;
|
|
367
365
|
ownerId?: string | undefined;
|
|
368
366
|
organizationId?: string | undefined;
|
|
367
|
+
createdAt?: unknown;
|
|
368
|
+
updatedAt?: unknown;
|
|
369
369
|
}, {
|
|
370
370
|
description?: string | undefined;
|
|
371
371
|
name?: string | undefined;
|
|
372
|
-
createdAt?: unknown;
|
|
373
|
-
updatedAt?: unknown;
|
|
374
372
|
slug?: string | undefined;
|
|
375
373
|
ownerId?: string | undefined;
|
|
376
374
|
organizationId?: string | undefined;
|
|
375
|
+
createdAt?: unknown;
|
|
376
|
+
updatedAt?: unknown;
|
|
377
377
|
}>;
|
|
378
378
|
}, Board>;
|
|
379
379
|
readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
|
|
@@ -402,16 +402,16 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
402
402
|
method: "PUT";
|
|
403
403
|
body: better_call.StandardSchemaV1<{
|
|
404
404
|
title?: string | undefined;
|
|
405
|
+
boardId?: string | undefined;
|
|
405
406
|
createdAt?: unknown;
|
|
406
407
|
updatedAt?: unknown;
|
|
407
408
|
order?: number | undefined;
|
|
408
|
-
boardId?: string | undefined;
|
|
409
409
|
}, {
|
|
410
410
|
title?: string | undefined;
|
|
411
|
+
boardId?: string | undefined;
|
|
411
412
|
createdAt?: unknown;
|
|
412
413
|
updatedAt?: unknown;
|
|
413
414
|
order?: number | undefined;
|
|
414
|
-
boardId?: string | undefined;
|
|
415
415
|
}>;
|
|
416
416
|
}, Column>;
|
|
417
417
|
readonly deleteColumn: better_call.StrictEndpoint<"/columns/:id", {} & {
|
|
@@ -8,11 +8,11 @@ import { QueryClient } from '@tanstack/react-query';
|
|
|
8
8
|
declare const createBoardSchema: z.ZodObject<{
|
|
9
9
|
description: z.ZodOptional<z.ZodString>;
|
|
10
10
|
name: z.ZodString;
|
|
11
|
-
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
12
|
-
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
13
11
|
slug: z.ZodOptional<z.ZodString>;
|
|
14
12
|
ownerId: z.ZodOptional<z.ZodString>;
|
|
15
13
|
organizationId: z.ZodOptional<z.ZodString>;
|
|
14
|
+
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
15
|
+
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
16
16
|
}, z.core.$strip>;
|
|
17
17
|
declare const updateBoardSchema: z.ZodObject<{
|
|
18
18
|
createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
|
|
@@ -26,10 +26,10 @@ declare const updateBoardSchema: z.ZodObject<{
|
|
|
26
26
|
}, z.core.$strip>;
|
|
27
27
|
declare const createColumnSchema: z.ZodObject<{
|
|
28
28
|
title: z.ZodString;
|
|
29
|
+
boardId: z.ZodString;
|
|
29
30
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
30
31
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
31
32
|
order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
32
|
-
boardId: z.ZodString;
|
|
33
33
|
}, z.core.$strip>;
|
|
34
34
|
declare const updateColumnSchema: z.ZodObject<{
|
|
35
35
|
createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
|
|
@@ -331,19 +331,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
331
331
|
body: better_call.StandardSchemaV1<{
|
|
332
332
|
name: string;
|
|
333
333
|
description?: string | undefined;
|
|
334
|
-
createdAt?: unknown;
|
|
335
|
-
updatedAt?: unknown;
|
|
336
334
|
slug?: string | undefined;
|
|
337
335
|
ownerId?: string | undefined;
|
|
338
336
|
organizationId?: string | undefined;
|
|
337
|
+
createdAt?: unknown;
|
|
338
|
+
updatedAt?: unknown;
|
|
339
339
|
}, {
|
|
340
340
|
name: string;
|
|
341
341
|
description?: string | undefined;
|
|
342
|
-
createdAt?: unknown;
|
|
343
|
-
updatedAt?: unknown;
|
|
344
342
|
slug?: string | undefined;
|
|
345
343
|
ownerId?: string | undefined;
|
|
346
344
|
organizationId?: string | undefined;
|
|
345
|
+
createdAt?: unknown;
|
|
346
|
+
updatedAt?: unknown;
|
|
347
347
|
}>;
|
|
348
348
|
}, {
|
|
349
349
|
columns: ColumnWithTasks[];
|
|
@@ -361,19 +361,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
361
361
|
body: better_call.StandardSchemaV1<{
|
|
362
362
|
description?: string | undefined;
|
|
363
363
|
name?: string | undefined;
|
|
364
|
-
createdAt?: unknown;
|
|
365
|
-
updatedAt?: unknown;
|
|
366
364
|
slug?: string | undefined;
|
|
367
365
|
ownerId?: string | undefined;
|
|
368
366
|
organizationId?: string | undefined;
|
|
367
|
+
createdAt?: unknown;
|
|
368
|
+
updatedAt?: unknown;
|
|
369
369
|
}, {
|
|
370
370
|
description?: string | undefined;
|
|
371
371
|
name?: string | undefined;
|
|
372
|
-
createdAt?: unknown;
|
|
373
|
-
updatedAt?: unknown;
|
|
374
372
|
slug?: string | undefined;
|
|
375
373
|
ownerId?: string | undefined;
|
|
376
374
|
organizationId?: string | undefined;
|
|
375
|
+
createdAt?: unknown;
|
|
376
|
+
updatedAt?: unknown;
|
|
377
377
|
}>;
|
|
378
378
|
}, Board>;
|
|
379
379
|
readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
|
|
@@ -402,16 +402,16 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
402
402
|
method: "PUT";
|
|
403
403
|
body: better_call.StandardSchemaV1<{
|
|
404
404
|
title?: string | undefined;
|
|
405
|
+
boardId?: string | undefined;
|
|
405
406
|
createdAt?: unknown;
|
|
406
407
|
updatedAt?: unknown;
|
|
407
408
|
order?: number | undefined;
|
|
408
|
-
boardId?: string | undefined;
|
|
409
409
|
}, {
|
|
410
410
|
title?: string | undefined;
|
|
411
|
+
boardId?: string | undefined;
|
|
411
412
|
createdAt?: unknown;
|
|
412
413
|
updatedAt?: unknown;
|
|
413
414
|
order?: number | undefined;
|
|
414
|
-
boardId?: string | undefined;
|
|
415
415
|
}>;
|
|
416
416
|
}, Column>;
|
|
417
417
|
readonly deleteColumn: better_call.StrictEndpoint<"/columns/:id", {} & {
|
|
@@ -8,11 +8,11 @@ import { QueryClient } from '@tanstack/react-query';
|
|
|
8
8
|
declare const createBoardSchema: z.ZodObject<{
|
|
9
9
|
description: z.ZodOptional<z.ZodString>;
|
|
10
10
|
name: z.ZodString;
|
|
11
|
-
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
12
|
-
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
13
11
|
slug: z.ZodOptional<z.ZodString>;
|
|
14
12
|
ownerId: z.ZodOptional<z.ZodString>;
|
|
15
13
|
organizationId: z.ZodOptional<z.ZodString>;
|
|
14
|
+
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
15
|
+
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
16
16
|
}, z.core.$strip>;
|
|
17
17
|
declare const updateBoardSchema: z.ZodObject<{
|
|
18
18
|
createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
|
|
@@ -26,10 +26,10 @@ declare const updateBoardSchema: z.ZodObject<{
|
|
|
26
26
|
}, z.core.$strip>;
|
|
27
27
|
declare const createColumnSchema: z.ZodObject<{
|
|
28
28
|
title: z.ZodString;
|
|
29
|
+
boardId: z.ZodString;
|
|
29
30
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
30
31
|
updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
31
32
|
order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
32
|
-
boardId: z.ZodString;
|
|
33
33
|
}, z.core.$strip>;
|
|
34
34
|
declare const updateColumnSchema: z.ZodObject<{
|
|
35
35
|
createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
|
|
@@ -331,19 +331,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
331
331
|
body: better_call.StandardSchemaV1<{
|
|
332
332
|
name: string;
|
|
333
333
|
description?: string | undefined;
|
|
334
|
-
createdAt?: unknown;
|
|
335
|
-
updatedAt?: unknown;
|
|
336
334
|
slug?: string | undefined;
|
|
337
335
|
ownerId?: string | undefined;
|
|
338
336
|
organizationId?: string | undefined;
|
|
337
|
+
createdAt?: unknown;
|
|
338
|
+
updatedAt?: unknown;
|
|
339
339
|
}, {
|
|
340
340
|
name: string;
|
|
341
341
|
description?: string | undefined;
|
|
342
|
-
createdAt?: unknown;
|
|
343
|
-
updatedAt?: unknown;
|
|
344
342
|
slug?: string | undefined;
|
|
345
343
|
ownerId?: string | undefined;
|
|
346
344
|
organizationId?: string | undefined;
|
|
345
|
+
createdAt?: unknown;
|
|
346
|
+
updatedAt?: unknown;
|
|
347
347
|
}>;
|
|
348
348
|
}, {
|
|
349
349
|
columns: ColumnWithTasks[];
|
|
@@ -361,19 +361,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
361
361
|
body: better_call.StandardSchemaV1<{
|
|
362
362
|
description?: string | undefined;
|
|
363
363
|
name?: string | undefined;
|
|
364
|
-
createdAt?: unknown;
|
|
365
|
-
updatedAt?: unknown;
|
|
366
364
|
slug?: string | undefined;
|
|
367
365
|
ownerId?: string | undefined;
|
|
368
366
|
organizationId?: string | undefined;
|
|
367
|
+
createdAt?: unknown;
|
|
368
|
+
updatedAt?: unknown;
|
|
369
369
|
}, {
|
|
370
370
|
description?: string | undefined;
|
|
371
371
|
name?: string | undefined;
|
|
372
|
-
createdAt?: unknown;
|
|
373
|
-
updatedAt?: unknown;
|
|
374
372
|
slug?: string | undefined;
|
|
375
373
|
ownerId?: string | undefined;
|
|
376
374
|
organizationId?: string | undefined;
|
|
375
|
+
createdAt?: unknown;
|
|
376
|
+
updatedAt?: unknown;
|
|
377
377
|
}>;
|
|
378
378
|
}, Board>;
|
|
379
379
|
readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
|
|
@@ -402,16 +402,16 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
|
|
|
402
402
|
method: "PUT";
|
|
403
403
|
body: better_call.StandardSchemaV1<{
|
|
404
404
|
title?: string | undefined;
|
|
405
|
+
boardId?: string | undefined;
|
|
405
406
|
createdAt?: unknown;
|
|
406
407
|
updatedAt?: unknown;
|
|
407
408
|
order?: number | undefined;
|
|
408
|
-
boardId?: string | undefined;
|
|
409
409
|
}, {
|
|
410
410
|
title?: string | undefined;
|
|
411
|
+
boardId?: string | undefined;
|
|
411
412
|
createdAt?: unknown;
|
|
412
413
|
updatedAt?: unknown;
|
|
413
414
|
order?: number | undefined;
|
|
414
|
-
boardId?: string | undefined;
|
|
415
415
|
}>;
|
|
416
416
|
}, Column>;
|
|
417
417
|
readonly deleteColumn: better_call.StrictEndpoint<"/columns/:id", {} & {
|