@revealui/core 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +57 -5
  2. package/dist/client/admin/components/AdminDashboard.d.ts +7 -1
  3. package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
  4. package/dist/client/admin/components/AdminDashboard.js +11 -11
  5. package/dist/client/admin/components/CollectionList.d.ts +2 -1
  6. package/dist/client/admin/components/CollectionList.d.ts.map +1 -1
  7. package/dist/client/admin/components/CollectionList.js +5 -5
  8. package/dist/client/admin/components/DocumentForm.d.ts +2 -1
  9. package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
  10. package/dist/client/admin/components/DocumentForm.js +16 -16
  11. package/dist/client/admin/components/GlobalForm.d.ts +2 -1
  12. package/dist/client/admin/components/GlobalForm.d.ts.map +1 -1
  13. package/dist/client/admin/components/GlobalForm.js +3 -3
  14. package/dist/client/admin/context/ServerFunctionContext.d.ts +1 -1
  15. package/dist/client/admin/context/ServerFunctionContext.d.ts.map +1 -1
  16. package/dist/client/admin/layout.d.ts +1 -1
  17. package/dist/client/admin/layout.d.ts.map +1 -1
  18. package/dist/client/admin/layout.js +5 -1
  19. package/dist/client/admin/page.d.ts +2 -2
  20. package/dist/client/admin/page.d.ts.map +1 -1
  21. package/dist/client/admin/page.js +10 -3
  22. package/dist/client/richtext/RichTextEditor.d.ts +1 -1
  23. package/dist/client/richtext/RichTextEditor.d.ts.map +1 -1
  24. package/dist/client/richtext/plugins/CollaborationPlugin.d.ts +1 -1
  25. package/dist/client/richtext/plugins/CollaborationPlugin.d.ts.map +1 -1
  26. package/dist/client/richtext/plugins/ToolbarPlugin.d.ts +1 -1
  27. package/dist/client/richtext/plugins/ToolbarPlugin.d.ts.map +1 -1
  28. package/dist/collections/operations/sqlAdapter.d.ts.map +1 -1
  29. package/dist/collections/operations/sqlAdapter.js +7 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +1 -1
  33. package/dist/license.d.ts +20 -0
  34. package/dist/license.d.ts.map +1 -1
  35. package/dist/license.js +30 -0
  36. package/dist/nextjs/withRevealUI.d.ts +7 -2
  37. package/dist/nextjs/withRevealUI.d.ts.map +1 -1
  38. package/dist/nextjs/withRevealUI.js +9 -99
  39. package/dist/observability/health-check.d.ts.map +1 -1
  40. package/dist/observability/health-check.js +8 -1
  41. package/dist/revforge-license.d.ts +4 -2
  42. package/dist/revforge-license.d.ts.map +1 -1
  43. package/dist/revforge-license.js +21 -3
  44. package/dist/richtext/exports/server/rsc.d.ts +3 -3
  45. package/dist/richtext/exports/server/rsc.d.ts.map +1 -1
  46. package/dist/server/index.d.ts +1 -1
  47. package/dist/server/index.d.ts.map +1 -1
  48. package/dist/server/index.js +1 -1
  49. package/dist/storage/_sigv4.d.ts +76 -0
  50. package/dist/storage/_sigv4.d.ts.map +1 -0
  51. package/dist/storage/_sigv4.js +134 -0
  52. package/dist/storage/_xml.d.ts +26 -0
  53. package/dist/storage/_xml.d.ts.map +1 -0
  54. package/dist/storage/_xml.js +75 -0
  55. package/dist/storage/index.d.ts +7 -6
  56. package/dist/storage/index.d.ts.map +1 -1
  57. package/dist/storage/index.js +17 -15
  58. package/dist/storage/object-storage.d.ts +41 -0
  59. package/dist/storage/object-storage.d.ts.map +1 -0
  60. package/dist/storage/{vercel-blob.js → object-storage.js} +38 -18
  61. package/dist/storage/r2.d.ts +14 -2
  62. package/dist/storage/r2.d.ts.map +1 -1
  63. package/dist/storage/r2.js +107 -44
  64. package/dist/storage/vercel-blob-provider.d.ts +28 -0
  65. package/dist/storage/vercel-blob-provider.d.ts.map +1 -0
  66. package/dist/storage/vercel-blob-provider.js +88 -0
  67. package/package.json +22 -23
  68. package/dist/storage/vercel-blob.d.ts +0 -17
  69. package/dist/storage/vercel-blob.d.ts.map +0 -1
@@ -1,21 +1,37 @@
1
1
  /**
2
2
  * Cloudflare R2 implementation of StorageProvider.
3
3
  *
4
- * R2 is S3-compatible uses @aws-sdk/client-s3 with a custom endpoint and
5
- * region='auto'. See https://developers.cloudflare.com/r2/api/s3/api/.
4
+ * R2 is S3-compatible. This is a native client: AWS SigV4 request signing
5
+ * (./_sigv4.ts, verified against AWS's official test vector) over global
6
+ * `fetch`, plus a small XML reader for ListObjectsV2 (./_xml.ts). No SDK
7
+ * dependency — only node:crypto + fetch.
8
+ *
9
+ * Path-style addressing is used for the S3 API calls
10
+ * (https://<account>.r2.cloudflarestorage.com/<bucket>/<key>); this has no
11
+ * effect on the public object URLs, which are built from `publicBaseUrl`.
6
12
  *
7
13
  * GAP-208 Phase 2a (2026-05-18). Phase 1 (interface + types) shipped in #959.
14
+ * Native client (dropping @aws-sdk/client-s3) landed 2026-06-09.
8
15
  *
9
16
  * Server-only. Do NOT import from client-side code or edge runtime.
17
+ *
18
+ * Known limitation (unchanged from the SDK version): request bodies are
19
+ * buffered fully in memory (see toUint8Array) so the payload can be hashed for
20
+ * SigV4. Streaming uploads (STREAMING-AWS4-HMAC-SHA256-PAYLOAD) are a future
21
+ * enhancement; presigned/private URLs remain Phase 2b.
10
22
  */
11
- import { DeleteObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client, } from '@aws-sdk/client-s3';
12
23
  import { toUint8Array } from './_helpers.js';
24
+ import { EMPTY_SHA256, sha256Hex, signS3Request } from './_sigv4.js';
25
+ import { parseListObjectsV2, s3ErrorFields } from './_xml.js';
13
26
  const PROVIDER_TAG = 'r2';
14
27
  const DEFAULT_CONTENT_TYPE = 'application/octet-stream';
15
28
  const DEFAULT_LIST_LIMIT = 1000;
29
+ const REGION = 'auto';
16
30
  class R2Provider {
17
31
  provider = PROVIDER_TAG;
18
- client;
32
+ accountId;
33
+ accessKeyId;
34
+ secretAccessKey;
19
35
  bucket;
20
36
  publicBaseUrl;
21
37
  constructor(config) {
@@ -25,16 +41,11 @@ class R2Provider {
25
41
  "custom domain (e.g. 'https://media.revealui.com') or the R2 dev URL " +
26
42
  "('https://<account-id>.r2.cloudflarestorage.com/<bucket>').");
27
43
  }
44
+ this.accountId = config.accountId;
45
+ this.accessKeyId = config.accessKeyId;
46
+ this.secretAccessKey = config.secretAccessKey;
28
47
  this.bucket = config.bucket;
29
48
  this.publicBaseUrl = stripTrailingSlash(config.publicBaseUrl);
30
- this.client = new S3Client({
31
- region: 'auto',
32
- endpoint: `https://${config.accountId}.r2.cloudflarestorage.com`,
33
- credentials: {
34
- accessKeyId: config.accessKeyId,
35
- secretAccessKey: config.secretAccessKey,
36
- },
37
- });
38
49
  }
39
50
  async put(key, data, opts) {
40
51
  if (opts?.access === 'private') {
@@ -43,15 +54,40 @@ class R2Provider {
43
54
  'lands in Phase 2b.');
44
55
  }
45
56
  const body = await toUint8Array(data);
46
- await this.client.send(new PutObjectCommand({
47
- Bucket: this.bucket,
48
- Key: key,
49
- Body: body,
50
- ContentType: opts?.contentType ?? DEFAULT_CONTENT_TYPE,
51
- ContentLength: body.byteLength,
52
- CacheControl: opts?.cacheControl,
53
- Metadata: opts?.metadata,
54
- }));
57
+ const extraHeaders = {
58
+ 'content-type': opts?.contentType ?? DEFAULT_CONTENT_TYPE,
59
+ };
60
+ if (opts?.cacheControl) {
61
+ extraHeaders['cache-control'] = opts.cacheControl;
62
+ }
63
+ for (const [name, value] of Object.entries(opts?.metadata ?? {})) {
64
+ extraHeaders[`x-amz-meta-${name.toLowerCase()}`] = value;
65
+ }
66
+ const { url, headers } = signS3Request({
67
+ method: 'PUT',
68
+ accountId: this.accountId,
69
+ bucket: this.bucket,
70
+ key,
71
+ region: REGION,
72
+ accessKeyId: this.accessKeyId,
73
+ secretAccessKey: this.secretAccessKey,
74
+ payloadHash: sha256Hex(body),
75
+ extraHeaders,
76
+ now: new Date(),
77
+ });
78
+ // No manual content-length: it is a forbidden fetch header that undici
79
+ // computes from the body itself, and setting it throws UND_ERR_INVALID_ARG
80
+ // ("invalid content-length header") on the R2 PUT. `headers` already carries
81
+ // the signed set. `as BodyInit` bridges the TS lib's ArrayBufferLike vs
82
+ // ArrayBuffer typed-array variance for fetch bodies (cf. src/api/compression.ts).
83
+ const response = await fetch(url, {
84
+ method: 'PUT',
85
+ headers,
86
+ body: body,
87
+ });
88
+ if (!response.ok) {
89
+ throw await storageError('PUT', key, response);
90
+ }
55
91
  return {
56
92
  key,
57
93
  url: `${this.publicBaseUrl}/${key}`,
@@ -61,34 +97,56 @@ class R2Provider {
61
97
  }
62
98
  async del(keyOrUrl) {
63
99
  const key = this.extractKey(keyOrUrl);
64
- await this.client.send(new DeleteObjectCommand({
65
- Bucket: this.bucket,
66
- Key: key,
67
- }));
100
+ const { url, headers } = signS3Request({
101
+ method: 'DELETE',
102
+ accountId: this.accountId,
103
+ bucket: this.bucket,
104
+ key,
105
+ region: REGION,
106
+ accessKeyId: this.accessKeyId,
107
+ secretAccessKey: this.secretAccessKey,
108
+ payloadHash: EMPTY_SHA256,
109
+ now: new Date(),
110
+ });
111
+ // Best-effort: a missing key is not an error. S3/R2 returns 204 regardless;
112
+ // tolerate 404 defensively.
113
+ const response = await fetch(url, { method: 'DELETE', headers });
114
+ if (!response.ok && response.status !== 404) {
115
+ throw await storageError('DELETE', key, response);
116
+ }
68
117
  }
69
118
  async list(opts) {
70
- const response = await this.client.send(new ListObjectsV2Command({
71
- Bucket: this.bucket,
72
- Prefix: opts?.prefix,
73
- MaxKeys: opts?.limit ?? DEFAULT_LIST_LIMIT,
74
- ContinuationToken: opts?.cursor,
75
- }));
76
- const items = (response.Contents ?? []).flatMap((entry) => {
77
- if (!entry.Key)
78
- return [];
79
- return [
80
- {
81
- key: entry.Key,
82
- url: `${this.publicBaseUrl}/${entry.Key}`,
83
- size: entry.Size ?? 0,
84
- uploadedAt: entry.LastModified ?? new Date(0),
85
- },
86
- ];
119
+ const { url, headers } = signS3Request({
120
+ method: 'GET',
121
+ accountId: this.accountId,
122
+ bucket: this.bucket,
123
+ region: REGION,
124
+ accessKeyId: this.accessKeyId,
125
+ secretAccessKey: this.secretAccessKey,
126
+ payloadHash: EMPTY_SHA256,
127
+ query: {
128
+ 'list-type': '2',
129
+ prefix: opts?.prefix,
130
+ 'max-keys': String(opts?.limit ?? DEFAULT_LIST_LIMIT),
131
+ 'continuation-token': opts?.cursor,
132
+ },
133
+ now: new Date(),
87
134
  });
135
+ const response = await fetch(url, { method: 'GET', headers });
136
+ if (!response.ok) {
137
+ throw await storageError('LIST', this.bucket, response);
138
+ }
139
+ const parsed = parseListObjectsV2(await response.text());
140
+ const items = parsed.objects.map((entry) => ({
141
+ key: entry.key,
142
+ url: `${this.publicBaseUrl}/${entry.key}`,
143
+ size: entry.size,
144
+ uploadedAt: entry.lastModified,
145
+ }));
88
146
  return {
89
147
  items,
90
- cursor: response.NextContinuationToken,
91
- hasMore: response.IsTruncated === true,
148
+ cursor: parsed.nextContinuationToken,
149
+ hasMore: parsed.isTruncated,
92
150
  };
93
151
  }
94
152
  extractKey(keyOrUrl) {
@@ -104,6 +162,11 @@ export function createR2Provider(config) {
104
162
  return new R2Provider(config);
105
163
  }
106
164
  // ── helpers ────────────────────────────────────────────────────────────────
165
+ async function storageError(operation, key, response) {
166
+ const body = await response.text().catch(() => '');
167
+ const { code, message } = s3ErrorFields(body);
168
+ return new Error(`R2 ${operation} failed for "${key}": ${code ?? response.status} ${message ?? response.statusText}`);
169
+ }
107
170
  function tryParseUrl(value) {
108
171
  try {
109
172
  return new URL(value);
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Vercel Blob implementation of StorageProvider.
3
+ *
4
+ * Legacy backend retained during the GAP-208 Cloudflare R2 cutover so the
5
+ * media-upload path can fall back to Vercel Blob when R2 is not configured.
6
+ * Wraps @vercel/blob's put/del/list behind the provider-agnostic
7
+ * StorageProvider interface. Cloudflare R2 (r2.ts) is the canonical backend;
8
+ * this provider is removed once the Blob store is decommissioned.
9
+ *
10
+ * NOTE: distinct from vercel-blob.ts in this directory, which is the legacy
11
+ * Payload-style upload *plugin* still wired into apps/admin's
12
+ * revealui.config.ts. This file is the StorageProvider the createStorage
13
+ * factory returns for the 'vercel-blob' tag.
14
+ *
15
+ * Server-only. Do NOT import from client-side code or edge runtime.
16
+ */
17
+ import type { ListOptions, ListResult, PutOptions, PutResult, StorageProvider, VercelBlobConfig } from './types.js';
18
+ declare class VercelBlobProvider implements StorageProvider {
19
+ readonly provider = "vercel-blob";
20
+ private readonly token;
21
+ constructor(config: VercelBlobConfig);
22
+ put(key: string, data: Blob | ArrayBuffer | Uint8Array | ReadableStream<Uint8Array>, opts?: PutOptions): Promise<PutResult>;
23
+ del(keyOrUrl: string): Promise<void>;
24
+ list(opts?: ListOptions): Promise<ListResult>;
25
+ }
26
+ export declare function createVercelBlobProvider(config: VercelBlobConfig): StorageProvider;
27
+ export type { VercelBlobProvider };
28
+ //# sourceMappingURL=vercel-blob-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel-blob-provider.d.ts","sourceRoot":"","sources":["../../src/storage/vercel-blob-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAEV,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAKpB,cAAM,kBAAmB,YAAW,eAAe;IACjD,QAAQ,CAAC,QAAQ,iBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,MAAM,EAAE,gBAAgB;IAW9B,GAAG,CACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,IAAI,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,EAClE,IAAI,CAAC,EAAE,UAAU,GAChB,OAAO,CAAC,SAAS,CAAC;IAmCf,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpC,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAqBpD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,CAElF;AAED,YAAY,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Vercel Blob implementation of StorageProvider.
3
+ *
4
+ * Legacy backend retained during the GAP-208 Cloudflare R2 cutover so the
5
+ * media-upload path can fall back to Vercel Blob when R2 is not configured.
6
+ * Wraps @vercel/blob's put/del/list behind the provider-agnostic
7
+ * StorageProvider interface. Cloudflare R2 (r2.ts) is the canonical backend;
8
+ * this provider is removed once the Blob store is decommissioned.
9
+ *
10
+ * NOTE: distinct from vercel-blob.ts in this directory, which is the legacy
11
+ * Payload-style upload *plugin* still wired into apps/admin's
12
+ * revealui.config.ts. This file is the StorageProvider the createStorage
13
+ * factory returns for the 'vercel-blob' tag.
14
+ *
15
+ * Server-only. Do NOT import from client-side code or edge runtime.
16
+ */
17
+ import { del, list, put } from '@vercel/blob';
18
+ import { toUint8Array } from './_helpers.js';
19
+ const PROVIDER_TAG = 'vercel-blob';
20
+ const DEFAULT_LIST_LIMIT = 1000;
21
+ class VercelBlobProvider {
22
+ provider = PROVIDER_TAG;
23
+ token;
24
+ constructor(config) {
25
+ if (!config.token) {
26
+ throw new Error('Vercel Blob provider requires VercelBlobConfig.token (the ' +
27
+ 'BLOB_READ_WRITE_TOKEN value). For new deployments prefer Cloudflare ' +
28
+ 'R2 (provider: "r2").');
29
+ }
30
+ this.token = config.token;
31
+ }
32
+ async put(key, data, opts) {
33
+ if (opts?.access === 'private') {
34
+ throw new Error("Vercel Blob provider does not support access: 'private' — every blob " +
35
+ 'is publicly readable. Use Cloudflare R2 for private-access patterns.');
36
+ }
37
+ // Normalize to bytes so the result carries an accurate size regardless of
38
+ // input shape (ReadableStream has no length until consumed). Re-wrap in a
39
+ // fresh Uint8Array so the Blob part is backed by a non-shared ArrayBuffer,
40
+ // satisfying the DOM BlobPart type under TS strict typed-array generics.
41
+ const body = await toUint8Array(data);
42
+ const result = await put(key, new Blob([new Uint8Array(body)]), {
43
+ access: 'public',
44
+ token: this.token,
45
+ contentType: opts?.contentType,
46
+ // Keys are caller-controlled (callers pre-randomize, e.g. media/<uuid>.ext);
47
+ // never append a second random suffix or the returned URL won't match `key`.
48
+ addRandomSuffix: false,
49
+ });
50
+ // Vercel Blob has no per-object user-metadata or Cache-Control-header API
51
+ // (only cacheControlMaxAge); opts.metadata / opts.cacheControl are ignored
52
+ // by this legacy provider. R2 honors both.
53
+ return {
54
+ key,
55
+ url: result.url,
56
+ size: body.byteLength,
57
+ provider: PROVIDER_TAG,
58
+ };
59
+ }
60
+ async del(keyOrUrl) {
61
+ // Vercel's del is idempotent (deleting an absent blob is a no-op), so this
62
+ // satisfies the best-effort contract. It requires the full blob URL, which
63
+ // is what media records persist.
64
+ await del(keyOrUrl, { token: this.token });
65
+ }
66
+ async list(opts) {
67
+ const response = await list({
68
+ token: this.token,
69
+ prefix: opts?.prefix,
70
+ limit: opts?.limit ?? DEFAULT_LIST_LIMIT,
71
+ cursor: opts?.cursor,
72
+ });
73
+ const items = response.blobs.map((blob) => ({
74
+ key: blob.pathname,
75
+ url: blob.url,
76
+ size: blob.size,
77
+ uploadedAt: blob.uploadedAt,
78
+ }));
79
+ return {
80
+ items,
81
+ cursor: response.cursor,
82
+ hasMore: response.hasMore,
83
+ };
84
+ }
85
+ }
86
+ export function createVercelBlobProvider(config) {
87
+ return new VercelBlobProvider(config);
88
+ }
package/package.json CHANGED
@@ -1,45 +1,44 @@
1
1
  {
2
2
  "name": "@revealui/core",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "RevealUI's runtime engine — admin UI, REST API, auth, rich text, plugin system, and access control. The heart of the open-source platform.",
5
5
  "license": "MIT",
6
6
  "dependencies": {
7
- "@aws-sdk/client-s3": "^3.1049.0",
8
- "@electric-sql/pglite": "^0.4.5",
9
- "@lexical/clipboard": "^0.44.0",
10
- "@lexical/code": "^0.44.0",
11
- "@lexical/html": "^0.44.0",
12
- "@lexical/link": "^0.44.0",
13
- "@lexical/list": "^0.44.0",
14
- "@lexical/react": "^0.44.0",
15
- "@lexical/rich-text": "^0.44.0",
16
- "@lexical/selection": "^0.44.0",
17
- "@lexical/table": "^0.44.0",
18
- "@lexical/utils": "^0.44.0",
19
- "@lexical/yjs": "^0.44.0",
7
+ "@electric-sql/pglite": "^0.5.1",
8
+ "@lexical/clipboard": "^0.45.0",
9
+ "@lexical/code": "^0.45.0",
10
+ "@lexical/html": "^0.45.0",
11
+ "@lexical/link": "^0.45.0",
12
+ "@lexical/list": "^0.45.0",
13
+ "@lexical/react": "^0.45.0",
14
+ "@lexical/rich-text": "^0.45.0",
15
+ "@lexical/selection": "^0.45.0",
16
+ "@lexical/table": "^0.45.0",
17
+ "@lexical/utils": "^0.45.0",
18
+ "@lexical/yjs": "^0.45.0",
20
19
  "@vercel/blob": "^2.3.3",
21
20
  "bcryptjs": "^3.0.3",
22
21
  "dataloader": "^2.2.3",
23
- "jose": "^6.2.3",
24
- "lexical": "^0.44.0",
22
+ "jose": "^5.10.0",
23
+ "lexical": "^0.45.0",
25
24
  "pg": "^8.21.0",
26
- "yjs": "^13.6.30",
25
+ "yjs": "^13.6.31",
27
26
  "zod": "^4.4.3",
28
- "@revealui/cache": "0.2.1",
29
- "@revealui/contracts": "0.6.0",
27
+ "@revealui/cache": "0.2.2",
28
+ "@revealui/contracts": "0.6.1",
30
29
  "@revealui/resilience": "0.2.4",
31
- "@revealui/security": "0.4.0",
30
+ "@revealui/security": "0.4.1",
32
31
  "@revealui/utils": "0.3.5"
33
32
  },
34
33
  "devDependencies": {
35
34
  "@types/json-schema": "^7.0.15",
36
35
  "@types/pg": "^8.20.0",
37
- "@types/react": "^19.2.14",
36
+ "@types/react": "^19.2.17",
38
37
  "@types/react-dom": "^19.2.3",
39
- "@vitest/coverage-v8": "^4.1.5",
38
+ "@vitest/coverage-v8": "^4.1.8",
40
39
  "expect-type": "^1.3.0",
41
40
  "tsup": "^8.5.1",
42
- "vitest": "^4.1.5",
41
+ "vitest": "^4.1.8",
43
42
  "@revealui/dev": "0.1.0"
44
43
  },
45
44
  "engines": {
@@ -1,17 +0,0 @@
1
- /**
2
- * Vercel Blob Storage Plugin
3
- *
4
- * WARNING: This module is server-only.
5
- * Do NOT import in client-side code or edge runtime.
6
- */
7
- import type { Plugin } from '../types/index.js';
8
- export interface VercelBlobStorageConfig {
9
- enabled?: boolean;
10
- collections?: {
11
- [key: string]: boolean;
12
- };
13
- token?: string;
14
- prefix?: string;
15
- }
16
- export declare function vercelBlobStorage(config: VercelBlobStorageConfig): Plugin;
17
- //# sourceMappingURL=vercel-blob.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vercel-blob.d.ts","sourceRoot":"","sources":["../../src/storage/vercel-blob.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE;QACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,MAAM,CAyFzE"}