clefbase 1.3.4 → 1.3.6

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.
@@ -42,6 +42,7 @@ exports.ClefbaseHosting = exports.SiteReference = void 0;
42
42
  * const site = hosting.site("my-site-id");
43
43
  * const result = await site.deployFiles({ "index.html": htmlBuffer, "app.js": jsBuffer });
44
44
  * console.log(`Live at ${result.url}`);
45
+ * console.log(`Preview at ${result.previewUrl}`);
45
46
  */
46
47
  class SiteReference {
47
48
  constructor(hosting, siteId) {
@@ -74,13 +75,29 @@ class SiteReference {
74
75
  * message: "v1.2.0",
75
76
  * onProgress: (done, total) => console.log(`${done}/${total}`),
76
77
  * });
78
+ * console.log(`Live at ${result.url}`);
77
79
  */
78
80
  async deployFiles(files, opts) {
79
81
  return this.hosting._deployFiles(this.siteId, files, opts);
80
82
  }
81
- /** The public URL for this site. */
83
+ /** Check the DNS status of this site's preview + custom domains. */
84
+ async getDnsStatus() {
85
+ return this.hosting._getDnsStatus(this.siteId);
86
+ }
87
+ /** Re-provision the preview DNS record (e.g. if it was accidentally deleted). */
88
+ async reprovisionDns() {
89
+ return this.hosting._reprovisionDns(this.siteId);
90
+ }
91
+ /** The preview URL for this site ({slug}.preview.cleforyx.com). */
92
+ get previewUrl() {
93
+ return this.hosting._previewUrl(this.siteId);
94
+ }
95
+ /**
96
+ * The public URL — custom domain if configured, else preview subdomain.
97
+ * Requires the site metadata; use `(await site.get())?.customDomain` to check.
98
+ */
82
99
  get url() {
83
- return this.hosting._siteUrl(this.siteId);
100
+ return this.previewUrl; // SDK doesn't cache site; use DeployResult.url for canonical
84
101
  }
85
102
  }
86
103
  exports.SiteReference = SiteReference;
@@ -90,7 +107,12 @@ exports.SiteReference = SiteReference;
90
107
  *
91
108
  * @example
92
109
  * const hosting = getHosting(app);
110
+ *
111
+ * // Create a site — automatically provisions {name}.preview.cleforyx.com
93
112
  * const site = await hosting.createSite("my-app");
113
+ * console.log(site.previewUrl); // https://my-app.preview.cleforyx.com
114
+ *
115
+ * // Deploy files
94
116
  * const result = await hosting.site(site.id).deployFiles(files);
95
117
  * console.log(result.url);
96
118
  */
@@ -104,24 +126,45 @@ class ClefbaseHosting {
104
126
  async listSites() {
105
127
  return this.http.get(`/databases/${this.dbId}/sites`);
106
128
  }
107
- /** Create a new hosted site. */
129
+ /**
130
+ * Create a new hosted site.
131
+ *
132
+ * Site names must be globally unique across the platform.
133
+ * A CNAME record will be automatically provisioned on Cloudflare:
134
+ * {slug}.preview.cleforyx.com → cleforyx.com
135
+ *
136
+ * Throws a 409 ConflictError if the name is already taken.
137
+ */
108
138
  async createSite(name, description) {
109
139
  return this.http.post(`/databases/${this.dbId}/sites`, { name, description });
110
140
  }
111
- /** Update site metadata. */
141
+ /** Update site metadata. Handles DNS rename if name changes. */
112
142
  async updateSite(siteId, patch) {
113
143
  return this.http.patch(`/databases/${this.dbId}/sites/${siteId}`, patch);
114
144
  }
115
- /** Delete a site and all its deploys permanently. */
116
- async deleteSite(siteId) {
117
- await this.http.delete(`/databases/${this.dbId}/sites/${siteId}`);
145
+ /**
146
+ * Begin site deletion flow.
147
+ *
148
+ * Pass `confirm: false` (or omit) to get a confirmation prompt with DNS info.
149
+ * Pass `confirm: true` to actually delete. Include `deleteDns: true` to also
150
+ * remove the Cloudflare DNS record.
151
+ */
152
+ async deleteSite(siteId, opts) {
153
+ const params = new URLSearchParams();
154
+ if (opts?.confirm)
155
+ params.set("confirm", "true");
156
+ if (opts?.deleteDns)
157
+ params.set("deleteDns", "true");
158
+ const qs = params.toString() ? `?${params}` : "";
159
+ return this.http.delete(`/databases/${this.dbId}/sites/${siteId}${qs}`);
118
160
  }
119
161
  /** Return a SiteReference for a specific site ID. */
120
162
  site(siteId) {
121
163
  return new SiteReference(this, siteId);
122
164
  }
123
165
  // ─── Internals ─────────────────────────────────────────────────────────────
124
- _siteUrl(siteId) {
166
+ _previewUrl(siteId) {
167
+ // Falls back to server URL path if site metadata isn't cached
125
168
  return `${this.serverUrl.replace(/\/+$/, "")}/hosted/${this.dbId}/${siteId}`;
126
169
  }
127
170
  async _getSite(siteId) {
@@ -148,28 +191,35 @@ class ClefbaseHosting {
148
191
  async _listDeploys(siteId) {
149
192
  return this.http.get(`/databases/${this.dbId}/sites/${siteId}/deploys`);
150
193
  }
194
+ async _getDnsStatus(siteId) {
195
+ return this.http.get(`/databases/${this.dbId}/sites/${siteId}/dns`);
196
+ }
197
+ async _reprovisionDns(siteId) {
198
+ return this.http.post(`/databases/${this.dbId}/sites/${siteId}/dns/provision`, {});
199
+ }
151
200
  async _deployFiles(siteId, files, opts = {}) {
152
201
  const { entrypoint = "index.html", deployedBy, message, batchSize = 20, onProgress } = opts;
153
202
  // 1. Create pending deploy
154
203
  const pending = await this.http.post(`/databases/${this.dbId}/sites/${siteId}/deploys`, { deployedBy, entrypoint });
204
+ // 2. Get site for canonical URL
205
+ const siteData = await this._getSite(siteId).catch(() => null);
155
206
  const filePaths = Object.keys(files);
156
207
  const fileBuffers = Object.values(files);
157
208
  const errors = [];
158
209
  let uploaded = 0;
159
- // 2. Detect whether we have native FormData (Node 18+) or need form-data pkg
210
+ // 3. Detect whether we have native FormData (Node 18+) or need form-data pkg
160
211
  const hasNativeFormData = typeof FormData !== "undefined";
161
212
  let FormDataLegacy;
162
213
  if (!hasNativeFormData) {
163
214
  const mod = await Promise.resolve().then(() => __importStar(require("form-data")));
164
215
  FormDataLegacy = mod.default;
165
216
  }
166
- // 3. Upload in batches
217
+ // 4. Upload in batches
167
218
  for (let i = 0; i < filePaths.length; i += batchSize) {
168
219
  const batchPaths = filePaths.slice(i, i + batchSize);
169
220
  const batchBuffers = fileBuffers.slice(i, i + batchSize);
170
221
  try {
171
222
  if (hasNativeFormData) {
172
- // Node 18+ native FormData: Buffers must be wrapped in Blob/File
173
223
  const form = new FormData();
174
224
  for (let j = 0; j < batchPaths.length; j++) {
175
225
  const filename = batchPaths[j].split("/").pop() ?? batchPaths[j];
@@ -182,7 +232,6 @@ class ClefbaseHosting {
182
232
  await this.http.request(`/databases/${this.dbId}/deploys/${pending.id}/files/batch`, { method: "POST", body: form, isFormData: true });
183
233
  }
184
234
  else {
185
- // Older Node: form-data package accepts Buffers natively
186
235
  const form = new FormDataLegacy();
187
236
  for (let j = 0; j < batchPaths.length; j++) {
188
237
  form.append("files[]", batchBuffers[j], {
@@ -200,13 +249,17 @@ class ClefbaseHosting {
200
249
  }
201
250
  onProgress?.(Math.min(i + batchSize, filePaths.length), filePaths.length);
202
251
  }
203
- // 4. Finalize → go live
252
+ // 5. Finalize → go live
204
253
  const live = await this.http.post(`/databases/${this.dbId}/deploys/${pending.id}/finalize`, { message: message ?? "Deployed via clefbase SDK" });
254
+ const canonicalUrl = siteData?.customDomain
255
+ ? `https://${siteData.customDomain}`
256
+ : siteData?.previewUrl ?? this._previewUrl(siteId);
205
257
  return {
206
258
  deploy: live,
207
259
  filesUploaded: uploaded,
208
260
  errors,
209
- url: this._siteUrl(siteId),
261
+ url: canonicalUrl,
262
+ previewUrl: siteData?.previewUrl ?? this._previewUrl(siteId),
210
263
  };
211
264
  }
212
265
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hosting/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hosting/index.ts"],"names":[],"mappings":"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"}
@@ -2,75 +2,24 @@ import React, { type ImgHTMLAttributes } from "react";
2
2
  import type { ClefbaseStorage } from "../storage";
3
3
  export type StorageImageStatus = "loading" | "loaded" | "error";
4
4
  export interface StorageImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src"> {
5
- /**
6
- * The ClefbaseStorage instance returned by `getStorage(app)`.
7
- */
8
5
  storage: ClefbaseStorage;
9
- /**
10
- * Path inside the default bucket, e.g. `"avatars/user-123.jpg"`.
11
- * Mutually exclusive with `bucket` + `path`.
12
- */
6
+ /** Path inside the default bucket, e.g. "avatars/user-123.jpg". */
13
7
  src?: string;
14
- /**
15
- * Named bucket to read from. Pair with `path`.
16
- */
8
+ /** Named bucket to read from. Pair with `path`. */
17
9
  bucket?: string;
18
- /**
19
- * File path inside `bucket`.
20
- */
10
+ /** File path inside `bucket`. */
21
11
  path?: string;
22
- /**
23
- * Shown while the download URL is being resolved.
24
- * Accepts a URL string or any React node.
25
- */
12
+ /** Shown while the download URL is being resolved. */
26
13
  placeholder?: React.ReactNode | string;
27
- /**
28
- * Shown when the URL cannot be resolved or the image fails to load.
29
- * Accepts a URL string or any React node.
30
- */
14
+ /** Shown when the URL cannot be resolved or the image fails to load. */
31
15
  fallback?: React.ReactNode | string;
32
- /**
33
- * Called with the resolved download URL once ready.
34
- */
35
16
  onResolve?: (url: string) => void;
36
- /**
37
- * Called if URL resolution or image loading fails.
38
- */
39
17
  onError?: (err: unknown) => void;
40
- /**
41
- * Called whenever the loading status changes.
42
- */
43
18
  onStatusChange?: (status: StorageImageStatus) => void;
44
19
  }
45
20
  /**
46
- * A drop-in replacement for `<img>` that resolves Clefbase storage paths to
47
- * authenticated download URLs automatically.
48
- *
49
- * @example — default bucket
50
- * ```tsx
51
- * const storage = getStorage(app);
52
- *
53
- * <StorageImage
54
- * storage={storage}
55
- * src="avatars/user-123.jpg"
56
- * alt="User avatar"
57
- * width={64}
58
- * height={64}
59
- * style={{ borderRadius: "50%" }}
60
- * />
61
- * ```
62
- *
63
- * @example — named bucket
64
- * ```tsx
65
- * <StorageImage
66
- * storage={storage}
67
- * bucket="media"
68
- * path="products/shoe.webp"
69
- * alt="Product photo"
70
- * placeholder={<Spinner />}
71
- * fallback={<img src="/no-image.svg" alt="Not found" />}
72
- * />
73
- * ```
21
+ * Drop-in <img> replacement that resolves Clefbase storage paths to
22
+ * authenticated download URLs via /storage/resolve.
74
23
  */
75
24
  export declare const StorageImage: React.ForwardRefExoticComponent<StorageImageProps & React.RefAttributes<HTMLImageElement>>;
76
25
  export default StorageImage;
@@ -1 +1 @@
1
- {"version":3,"file":"StorageImage.d.ts","sourceRoot":"","sources":["../../src/react/StorageImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAKZ,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC;IACxD;;OAEG;IACH,OAAO,EAAE,eAAe,CAAC;IAEzB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC;IAEpC;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,YAAY,4FAuKxB,CAAC;AAIF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"StorageImage.d.ts","sourceRoot":"","sources":["../../src/react/StorageImage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAKZ,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEhE,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC;IACxD,OAAO,EAAE,eAAe,CAAC;IACzB,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC;IACvC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAID;;;GAGG;AACH,eAAO,MAAM,YAAY,4FAoIxB,CAAC;AAGF,eAAe,YAAY,CAAC"}
@@ -5,70 +5,20 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  // ─── StorageImage ─────────────────────────────────────────────────────────────
7
7
  /**
8
- * A drop-in replacement for `<img>` that resolves Clefbase storage paths to
9
- * authenticated download URLs automatically.
10
- *
11
- * @example — default bucket
12
- * ```tsx
13
- * const storage = getStorage(app);
14
- *
15
- * <StorageImage
16
- * storage={storage}
17
- * src="avatars/user-123.jpg"
18
- * alt="User avatar"
19
- * width={64}
20
- * height={64}
21
- * style={{ borderRadius: "50%" }}
22
- * />
23
- * ```
24
- *
25
- * @example — named bucket
26
- * ```tsx
27
- * <StorageImage
28
- * storage={storage}
29
- * bucket="media"
30
- * path="products/shoe.webp"
31
- * alt="Product photo"
32
- * placeholder={<Spinner />}
33
- * fallback={<img src="/no-image.svg" alt="Not found" />}
34
- * />
35
- * ```
8
+ * Drop-in <img> replacement that resolves Clefbase storage paths to
9
+ * authenticated download URLs via /storage/resolve.
36
10
  */
37
11
  exports.StorageImage = (0, react_1.forwardRef)(function StorageImage({ storage, src, bucket, path, placeholder, fallback, onResolve, onError, onStatusChange, alt = "", ...imgProps }, ref) {
38
- // Resolve the URL synchronously where possible (_directUrl is pure/sync)
39
- // to avoid an async waterfall that exhausts the browser's per-host
40
- // connection pool (typically 6 connections) when many cards mount at once.
41
- const getDirectUrl = () => {
42
- try {
43
- if (bucket && path)
44
- return storage._directUrl(bucket, path);
45
- if (src)
46
- return storage._directUrl(storage["_defaultBucket"] ?? "default", src);
47
- return null;
48
- }
49
- catch {
50
- return null;
51
- }
52
- };
53
- const initialUrl = getDirectUrl();
54
- const [resolvedUrl, setResolvedUrl] = (0, react_1.useState)(initialUrl);
55
- const [status, setStatus] = (0, react_1.useState)(initialUrl ? "loaded" : "loading");
56
- // Keep a ref to the latest callbacks so the effect closure stays stable.
12
+ const [resolvedUrl, setResolvedUrl] = (0, react_1.useState)(null);
13
+ const [status, setStatus] = (0, react_1.useState)("loading");
57
14
  const onResolveRef = (0, react_1.useRef)(onResolve);
58
15
  const onErrorRef = (0, react_1.useRef)(onError);
59
16
  const onStatusRef = (0, react_1.useRef)(onStatusChange);
60
17
  onResolveRef.current = onResolve;
61
18
  onErrorRef.current = onError;
62
19
  onStatusRef.current = onStatusChange;
63
- // Determine the key that uniquely identifies the requested file.
64
20
  const fileKey = bucket && path ? `${bucket}::${path}` : src ?? null;
65
21
  (0, react_1.useEffect)(() => {
66
- // If we already resolved synchronously, notify callers and skip the
67
- // async effect entirely — no extra network round-trip needed.
68
- if (initialUrl) {
69
- onResolveRef.current?.(initialUrl);
70
- return;
71
- }
72
22
  if (!fileKey)
73
23
  return;
74
24
  let cancelled = false;
@@ -78,9 +28,7 @@ exports.StorageImage = (0, react_1.forwardRef)(function StorageImage({ storage,
78
28
  try {
79
29
  let url;
80
30
  if (bucket && path) {
81
- url = storage.bucket(bucket).ref(path).getDownloadURL
82
- ? await storage.bucket(bucket).ref(path).getDownloadURL()
83
- : storage._directUrl(bucket, path);
31
+ url = await storage.bucket(bucket).ref(path).getDownloadURL();
84
32
  }
85
33
  else if (src) {
86
34
  url = await storage.ref(src).getDownloadURL();
@@ -90,9 +38,11 @@ exports.StorageImage = (0, react_1.forwardRef)(function StorageImage({ storage,
90
38
  }
91
39
  if (cancelled)
92
40
  return;
41
+ if (!url)
42
+ throw new Error("StorageImage: empty download URL returned.");
93
43
  setResolvedUrl(url);
94
44
  onResolveRef.current?.(url);
95
- // status moves to "loaded" in the <img> onLoad handler below
45
+ // status "loaded" fires in the <img> onLoad handler
96
46
  }
97
47
  catch (err) {
98
48
  if (cancelled)
@@ -103,9 +53,7 @@ exports.StorageImage = (0, react_1.forwardRef)(function StorageImage({ storage,
103
53
  }
104
54
  };
105
55
  resolve();
106
- return () => {
107
- cancelled = true;
108
- };
56
+ return () => { cancelled = true; };
109
57
  // eslint-disable-next-line react-hooks/exhaustive-deps
110
58
  }, [fileKey]);
111
59
  // ── Render helpers ────────────────────────────────────────────────────────
@@ -118,18 +66,17 @@ exports.StorageImage = (0, react_1.forwardRef)(function StorageImage({ storage,
118
66
  onStatusRef.current?.("error");
119
67
  onErrorRef.current?.(e);
120
68
  };
121
- // Show placeholder while resolving URL
69
+ // Placeholder while resolving
122
70
  if (status === "loading" && !resolvedUrl) {
123
71
  if (placeholder === undefined) {
124
- // Invisible img keeps layout stable
125
72
  return ((0, jsx_runtime_1.jsx)("img", { ...imgProps, ref: ref, src: "", alt: alt, style: { ...imgProps.style, visibility: "hidden" } }));
126
73
  }
127
74
  if (typeof placeholder === "string") {
128
- return ((0, jsx_runtime_1.jsx)("img", { ...imgProps, ref: ref, src: placeholder, alt: alt }));
75
+ return (0, jsx_runtime_1.jsx)("img", { ...imgProps, ref: ref, src: placeholder, alt: alt });
129
76
  }
130
77
  return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: placeholder });
131
78
  }
132
- // Show fallback on error
79
+ // Fallback on error
133
80
  if (status === "error" || !resolvedUrl) {
134
81
  if (fallback === undefined) {
135
82
  return ((0, jsx_runtime_1.jsx)("img", { ...imgProps, ref: ref, src: "", alt: alt, style: { ...imgProps.style, visibility: "hidden" } }));
@@ -139,10 +86,6 @@ exports.StorageImage = (0, react_1.forwardRef)(function StorageImage({ storage,
139
86
  }
140
87
  return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: fallback });
141
88
  }
142
- // Resolved — render the real image.
143
- // `loading="lazy"` defers off-screen fetches so the browser never
144
- // saturates its per-host connection pool (typically 6) when many
145
- // cards render simultaneously. Callers may override with loading="eager".
146
89
  return ((0, jsx_runtime_1.jsx)("img", { loading: "lazy", ...imgProps, ref: ref, src: resolvedUrl, alt: alt, onLoad: handleLoad, onError: handleImgError }));
147
90
  });
148
91
  exports.StorageImage.displayName = "StorageImage";
@@ -1 +1 @@
1
- {"version":3,"file":"StorageImage.js","sourceRoot":"","sources":["../../src/react/StorageImage.tsx"],"names":[],"mappings":";;;;AAAA,iCAMe;AA0Df,iFAAiF;AAEjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACU,QAAA,YAAY,GAAG,IAAA,kBAAU,EACpC,SAAS,YAAY,CACnB,EACE,OAAO,EACP,GAAG,EACH,MAAM,EACN,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,SAAS,EACT,OAAO,EACP,cAAc,EACd,GAAG,GAAG,EAAE,EACR,GAAG,QAAQ,EACZ,EACD,GAAG;IAEH,yEAAyE;IACzE,mEAAmE;IACnE,2EAA2E;IAC3E,MAAM,YAAY,GAAG,GAAkB,EAAE;QACvC,IAAI,CAAC;YACH,IAAI,MAAM,IAAI,IAAI;gBAAE,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC5D,IAAI,GAAG;gBAAa,OAAO,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,SAAS,EAAE,GAAG,CAAC,CAAC;YAC3F,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC;IAElC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAgB,UAAU,CAAC,CAAC;IAC1E,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAClC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAClC,CAAC;IAEF,yEAAyE;IACzE,MAAM,YAAY,GAAG,IAAA,cAAM,EAAC,SAAS,CAAC,CAAC;IACvC,MAAM,UAAU,GAAK,IAAA,cAAM,EAAC,OAAO,CAAC,CAAC;IACrC,MAAM,WAAW,GAAI,IAAA,cAAM,EAAC,cAAc,CAAC,CAAC;IAC5C,YAAY,CAAC,OAAO,GAAI,SAAS,CAAC;IAClC,UAAU,CAAC,OAAO,GAAM,OAAO,CAAC;IAChC,WAAW,CAAC,OAAO,GAAK,cAAc,CAAC;IAEvC,iEAAiE;IACjE,MAAM,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;IAEpE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,oEAAoE;QACpE,8DAA8D;QAC9D,IAAI,UAAU,EAAE,CAAC;YACf,YAAY,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,SAAS,CAAC,SAAS,CAAC,CAAC;QACrB,WAAW,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;QAEjC,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;YACzB,IAAI,CAAC;gBACH,IAAI,GAAW,CAAC;gBAEhB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;oBACnB,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,cAAc;wBACnD,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE;wBACzD,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACvC,CAAC;qBAAM,IAAI,GAAG,EAAE,CAAC;oBACf,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,CAAC;gBAChD,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;gBACnF,CAAC;gBAED,IAAI,SAAS;oBAAE,OAAO;gBACtB,cAAc,CAAC,GAAG,CAAC,CAAC;gBACpB,YAAY,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;gBAC5B,6DAA6D;YAC/D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,SAAS;oBAAE,OAAO;gBACtB,SAAS,CAAC,OAAO,CAAC,CAAC;gBACnB,WAAW,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;gBAC/B,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC,CAAC;QAEF,OAAO,EAAE,CAAC;QAEV,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;QACF,uDAAuD;IACzD,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,6EAA6E;IAE7E,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,WAAW,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,CAAyC,EAAE,EAAE;QACnE,SAAS,CAAC,OAAO,CAAC,CAAC;QACnB,WAAW,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;QAC/B,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC;IAEF,uCAAuC;IACvC,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,WAAW,EAAE,CAAC;QACzC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,oCAAoC;YACpC,OAAO,CACL,mCACM,QAAQ,EACZ,GAAG,EAAE,GAAG,EACR,GAAG,EAAC,EAAE,EACN,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,GAClD,CACH,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpC,OAAO,CACL,mCAAS,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,GAAI,CAC5D,CAAC;QACJ,CAAC;QACD,OAAO,2DAAG,WAAW,GAAI,CAAC;IAC5B,CAAC;IAED,yBAAyB;IACzB,IAAI,MAAM,KAAK,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CACL,mCACM,QAAQ,EACZ,GAAG,EAAE,GAAG,EACR,GAAG,EAAC,EAAE,EACN,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,GAClD,CACH,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,mCAAS,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,GAAI,CAAC;QAClE,CAAC;QACD,OAAO,2DAAG,QAAQ,GAAI,CAAC;IACzB,CAAC;IAED,oCAAoC;IACpC,kEAAkE;IAClE,iEAAiE;IACjE,0EAA0E;IAC1E,OAAO,CACL,gCACE,OAAO,EAAC,MAAM,KACV,QAAQ,EACZ,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,cAAc,GACvB,CACH,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,oBAAY,CAAC,WAAW,GAAG,cAAc,CAAC;AAE1C,kBAAe,oBAAY,CAAC"}
1
+ {"version":3,"file":"StorageImage.js","sourceRoot":"","sources":["../../src/react/StorageImage.tsx"],"names":[],"mappings":"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"}
@@ -22,6 +22,10 @@ export declare class StorageReference {
22
22
  contentType?: string;
23
23
  metadata?: Record<string, unknown>;
24
24
  }): Promise<StorageFile>;
25
+ /**
26
+ * Returns the authenticated download URL for this file.
27
+ * Always resolves via /storage/resolve to get the real bucketId + fileId.
28
+ */
25
29
  getDownloadURL(): Promise<string>;
26
30
  getMetadata(): Promise<StorageFile>;
27
31
  delete(): Promise<void>;
@@ -40,18 +44,32 @@ export declare class ClefbaseStorage {
40
44
  private readonly http;
41
45
  private readonly projectId;
42
46
  private readonly auth;
43
- /** @internal exposed so StorageImage can build URLs synchronously */
47
+ /** @internal used by StorageImage kept for compat but now returns empty string (no /path route exists) */
44
48
  _defaultBucket: string;
45
49
  /** In-memory cache: bucket name → UUID */
46
50
  private _bucketIdCache;
51
+ /** In-memory cache: "bucket::filePath" → download URL */
52
+ private _urlCache;
47
53
  constructor(http: HttpClient, projectId: string, auth?: Auth | null);
48
54
  private authHeaders;
49
55
  setDefaultBucket(name: string): this;
50
56
  bucket(name: string): BucketReference;
51
57
  ref(filePath: string): StorageReference;
52
58
  _resolveBucketId(bucketName: string): Promise<string>;
53
- /** Synchronous direct URL — used by StorageImage to avoid a waterfall. */
54
- _directUrl(bucket: string, filePath: string): string;
59
+ /**
60
+ * Resolves a storage path to an authenticated download URL via
61
+ * GET /storage/resolve?projectId=xxx&path=bucketName/folder/file.jpg
62
+ *
63
+ * The server returns { downloadUrl, id, bucketId, ... } — we use downloadUrl directly.
64
+ * Results are cached so repeated calls (e.g. many cards) only hit the server once per path.
65
+ */
66
+ _getDownloadURL(bucket: string, filePath: string): Promise<string>;
67
+ /**
68
+ * @deprecated No /path route exists on the server.
69
+ * Kept so StorageImage's synchronous fast-path gracefully returns ""
70
+ * (which makes StorageImage fall through to the async resolve path).
71
+ */
72
+ _directUrl(_bucket: string, _filePath: string): string;
55
73
  _resolve(bucket: string, filePath: string): Promise<StorageFile>;
56
74
  _upload(bucket: string, filePath: string, data: Buffer | Blob | File, opts?: {
57
75
  contentType?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"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"}
@@ -44,8 +44,12 @@ class StorageReference {
44
44
  async upload(data, opts) {
45
45
  return this.storage._upload(this.bucket, this.filePath, data, opts);
46
46
  }
47
+ /**
48
+ * Returns the authenticated download URL for this file.
49
+ * Always resolves via /storage/resolve to get the real bucketId + fileId.
50
+ */
47
51
  async getDownloadURL() {
48
- return this.storage._directUrl(this.bucket, this.filePath);
52
+ return this.storage._getDownloadURL(this.bucket, this.filePath);
49
53
  }
50
54
  async getMetadata() {
51
55
  return this.storage._resolve(this.bucket, this.filePath);
@@ -75,10 +79,12 @@ class ClefbaseStorage {
75
79
  this.http = http;
76
80
  this.projectId = projectId;
77
81
  this.auth = auth;
78
- /** @internal exposed so StorageImage can build URLs synchronously */
82
+ /** @internal used by StorageImage kept for compat but now returns empty string (no /path route exists) */
79
83
  this._defaultBucket = "default";
80
84
  /** In-memory cache: bucket name → UUID */
81
85
  this._bucketIdCache = new Map();
86
+ /** In-memory cache: "bucket::filePath" → download URL */
87
+ this._urlCache = new Map();
82
88
  }
83
89
  authHeaders() {
84
90
  return this.auth?.getAuthHeaders() ?? {};
@@ -94,10 +100,6 @@ class ClefbaseStorage {
94
100
  return new StorageReference(this, this._defaultBucket, filePath.replace(/^\/+/, ""));
95
101
  }
96
102
  // ─── Bucket UUID resolution ───────────────────────────────────────────────
97
- //
98
- // The external storage router identifies buckets by UUID, not by name.
99
- // dbId comes from the API key (set by dbApiKeyMiddleware), so we just call
100
- // GET /buckets (no projectId needed — the key carries that context).
101
103
  async _resolveBucketId(bucketName) {
102
104
  const cached = this._bucketIdCache.get(bucketName);
103
105
  if (cached)
@@ -111,19 +113,43 @@ class ClefbaseStorage {
111
113
  throw new Error(`Storage bucket "${bucketName}" not found`);
112
114
  return id;
113
115
  }
114
- // ─── Internal methods called by StorageReference ──────────────────────────
115
- /** Synchronous direct URL — used by StorageImage to avoid a waterfall. */
116
- _directUrl(bucket, filePath) {
116
+ // ─── Download URL ─────────────────────────────────────────────────────────
117
+ /**
118
+ * Resolves a storage path to an authenticated download URL via
119
+ * GET /storage/resolve?projectId=xxx&path=bucketName/folder/file.jpg
120
+ *
121
+ * The server returns { downloadUrl, id, bucketId, ... } — we use downloadUrl directly.
122
+ * Results are cached so repeated calls (e.g. many cards) only hit the server once per path.
123
+ */
124
+ async _getDownloadURL(bucket, filePath) {
117
125
  const cleanFile = filePath.replace(/^\/+/, "");
118
- const base = this.http.getBaseUrl();
119
- return `${base}/path/${cleanFile}?projectId=${encodeURIComponent(this.projectId)}&inline=true`;
126
+ // The resolve endpoint expects the full path including bucket name
127
+ const fullPath = `${bucket}/${cleanFile}`;
128
+ const cacheKey = fullPath;
129
+ const cached = this._urlCache.get(cacheKey);
130
+ if (cached)
131
+ return cached;
132
+ const meta = await this._resolve(bucket, cleanFile);
133
+ const url = meta.downloadUrl ?? "";
134
+ if (url)
135
+ this._urlCache.set(cacheKey, url);
136
+ return url;
137
+ }
138
+ /**
139
+ * @deprecated No /path route exists on the server.
140
+ * Kept so StorageImage's synchronous fast-path gracefully returns ""
141
+ * (which makes StorageImage fall through to the async resolve path).
142
+ */
143
+ _directUrl(_bucket, _filePath) {
144
+ return "";
120
145
  }
121
146
  async _resolve(bucket, filePath) {
122
147
  const cleanFile = filePath.replace(/^\/+/, "");
123
- return this.http.get(`/resolve?projectId=${encodeURIComponent(this.projectId)}&path=${cleanFile}`);
148
+ // The resolve endpoint matches by fullPath = "bucketName/folder/file.jpg"
149
+ const fullPath = `${bucket}/${cleanFile}`;
150
+ return this.http.get(`/resolve?projectId=${encodeURIComponent(this.projectId)}&path=${encodeURIComponent(fullPath)}`);
124
151
  }
125
152
  async _upload(bucket, filePath, data, opts) {
126
- // Resolve bucket name → UUID before building the URL
127
153
  const bucketId = await this._resolveBucketId(bucket);
128
154
  let FormDataImpl;
129
155
  if (typeof FormData !== "undefined") {
@@ -148,6 +174,9 @@ class ClefbaseStorage {
148
174
  form.append("folder", folder);
149
175
  if (opts?.metadata)
150
176
  form.append("metadata", JSON.stringify(opts.metadata));
177
+ // Bust the URL cache for this path so a fresh URL is fetched after upload
178
+ const cacheKey = `${bucket}/${cleanPath}`;
179
+ this._urlCache.delete(cacheKey);
151
180
  return this.http.request(`/buckets/${bucketId}/files`, {
152
181
  method: "POST",
153
182
  body: form,
@@ -158,6 +187,7 @@ class ClefbaseStorage {
158
187
  async _delete(bucket, filePath) {
159
188
  const bucketId = await this._resolveBucketId(bucket);
160
189
  const meta = await this._resolve(bucket, filePath);
190
+ this._urlCache.delete(`${bucket}/${filePath.replace(/^\/+/, "")}`);
161
191
  await this.http.delete(`/buckets/${bucketId}/files/${meta.id}`, this.authHeaders());
162
192
  }
163
193
  async _list(bucket, prefix, opts) {