@motherbase/client 2.2.1 → 2.2.4

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 (222) hide show
  1. package/COMPATIBILITY.md +157 -0
  2. package/LICENSE +21 -21
  3. package/README.md +52 -4
  4. package/dist/admin/auth-admin-client.d.ts +43 -0
  5. package/dist/admin/auth-admin-client.d.ts.map +1 -0
  6. package/dist/admin/auth-admin-client.js +62 -0
  7. package/dist/admin/auth-admin-client.js.map +1 -0
  8. package/dist/admin/auth-admin-mfa-client.d.ts +22 -0
  9. package/dist/admin/auth-admin-mfa-client.d.ts.map +1 -0
  10. package/dist/admin/auth-admin-mfa-client.js +17 -0
  11. package/dist/admin/auth-admin-mfa-client.js.map +1 -0
  12. package/dist/admin/types.d.ts +85 -0
  13. package/dist/admin/types.d.ts.map +1 -0
  14. package/dist/admin/types.js +3 -0
  15. package/dist/admin/types.js.map +1 -0
  16. package/dist/auth/constants.d.ts +21 -0
  17. package/dist/auth/constants.d.ts.map +1 -0
  18. package/dist/auth/constants.js +34 -0
  19. package/dist/auth/constants.js.map +1 -0
  20. package/dist/auth/index.d.ts +5 -0
  21. package/dist/auth/index.d.ts.map +1 -0
  22. package/dist/auth/index.js +34 -0
  23. package/dist/auth/index.js.map +1 -0
  24. package/dist/auth/motherbase-plugin.d.ts +6 -0
  25. package/dist/auth/motherbase-plugin.d.ts.map +1 -0
  26. package/dist/auth/motherbase-plugin.js +80 -0
  27. package/dist/auth/motherbase-plugin.js.map +1 -0
  28. package/dist/auth/pkce.d.ts +19 -0
  29. package/dist/auth/pkce.d.ts.map +1 -0
  30. package/dist/auth/pkce.js +89 -0
  31. package/dist/auth/pkce.js.map +1 -0
  32. package/dist/auth/session-utils.d.ts +29 -0
  33. package/dist/auth/session-utils.d.ts.map +1 -0
  34. package/dist/auth/session-utils.js +123 -0
  35. package/dist/auth/session-utils.js.map +1 -0
  36. package/dist/auth/session.d.ts +51 -0
  37. package/dist/auth/session.d.ts.map +1 -0
  38. package/dist/auth/session.js +161 -0
  39. package/dist/auth/session.js.map +1 -0
  40. package/dist/auth/types.d.ts +341 -0
  41. package/dist/auth/types.d.ts.map +1 -0
  42. package/dist/auth/types.js +2 -0
  43. package/dist/auth/types.js.map +1 -0
  44. package/dist/auth/utils.d.ts +28 -0
  45. package/dist/auth/utils.d.ts.map +1 -0
  46. package/dist/auth/utils.js +70 -0
  47. package/dist/auth/utils.js.map +1 -0
  48. package/dist/auth.d.ts +3 -2
  49. package/dist/auth.d.ts.map +1 -1
  50. package/dist/auth.js +27 -11
  51. package/dist/auth.js.map +1 -1
  52. package/dist/channel.d.ts +11 -0
  53. package/dist/channel.d.ts.map +1 -1
  54. package/dist/channel.js +26 -2
  55. package/dist/channel.js.map +1 -1
  56. package/dist/cookies/cookie-storage.d.ts +12 -0
  57. package/dist/cookies/cookie-storage.d.ts.map +1 -0
  58. package/dist/cookies/cookie-storage.js +35 -0
  59. package/dist/cookies/cookie-storage.js.map +1 -0
  60. package/dist/cookies/index.d.ts +5 -0
  61. package/dist/cookies/index.d.ts.map +1 -0
  62. package/dist/cookies/index.js +5 -0
  63. package/dist/cookies/index.js.map +1 -0
  64. package/dist/cookies/server-cookie-storage.d.ts +20 -0
  65. package/dist/cookies/server-cookie-storage.d.ts.map +1 -0
  66. package/dist/cookies/server-cookie-storage.js +60 -0
  67. package/dist/cookies/server-cookie-storage.js.map +1 -0
  68. package/dist/cookies/types.d.ts +33 -0
  69. package/dist/cookies/types.d.ts.map +1 -0
  70. package/dist/cookies/types.js +8 -0
  71. package/dist/cookies/types.js.map +1 -0
  72. package/dist/cookies/utils.d.ts +23 -0
  73. package/dist/cookies/utils.d.ts.map +1 -0
  74. package/dist/cookies/utils.js +67 -0
  75. package/dist/cookies/utils.js.map +1 -0
  76. package/dist/database/database.d.ts +197 -0
  77. package/dist/database/database.d.ts.map +1 -0
  78. package/dist/database/database.js +2 -0
  79. package/dist/database/database.js.map +1 -0
  80. package/dist/database/facade.d.ts +218 -0
  81. package/dist/database/facade.d.ts.map +1 -0
  82. package/dist/database/facade.js +198 -0
  83. package/dist/database/facade.js.map +1 -0
  84. package/dist/database/query.d.ts +97 -0
  85. package/dist/database/query.d.ts.map +1 -0
  86. package/dist/database/query.js +94 -0
  87. package/dist/database/query.js.map +1 -0
  88. package/dist/database/types.d.ts +314 -0
  89. package/dist/database/types.d.ts.map +1 -0
  90. package/dist/database/types.js +2 -0
  91. package/dist/database/types.js.map +1 -0
  92. package/dist/functions/errors.d.ts +28 -0
  93. package/dist/functions/errors.d.ts.map +1 -0
  94. package/dist/functions/errors.js +37 -0
  95. package/dist/functions/errors.js.map +1 -0
  96. package/dist/functions/index.d.ts +9 -0
  97. package/dist/functions/index.d.ts.map +1 -0
  98. package/dist/functions/index.js +40 -0
  99. package/dist/functions/index.js.map +1 -0
  100. package/dist/functions/types.d.ts +25 -0
  101. package/dist/functions/types.d.ts.map +1 -0
  102. package/dist/functions/types.js +2 -0
  103. package/dist/functions/types.js.map +1 -0
  104. package/dist/http/backend-error.d.ts +17 -0
  105. package/dist/http/backend-error.d.ts.map +1 -0
  106. package/dist/http/backend-error.js +11 -0
  107. package/dist/http/backend-error.js.map +1 -0
  108. package/dist/http/index.d.ts +59 -0
  109. package/dist/http/index.d.ts.map +1 -0
  110. package/dist/http/index.js +175 -0
  111. package/dist/http/index.js.map +1 -0
  112. package/dist/http/types.d.ts +45 -0
  113. package/dist/http/types.d.ts.map +1 -0
  114. package/dist/http/types.js +2 -0
  115. package/dist/http/types.js.map +1 -0
  116. package/dist/http/utils.d.ts +14 -0
  117. package/dist/http/utils.d.ts.map +1 -0
  118. package/dist/http/utils.js +37 -0
  119. package/dist/http/utils.js.map +1 -0
  120. package/dist/http.d.ts.map +1 -1
  121. package/dist/http.js +2 -1
  122. package/dist/http.js.map +1 -1
  123. package/dist/index.d.ts +47 -77
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +58 -73
  126. package/dist/index.js.map +1 -1
  127. package/dist/pkce.js +4 -4
  128. package/dist/postgrest/index.d.ts +4 -0
  129. package/dist/postgrest/index.d.ts.map +1 -0
  130. package/dist/postgrest/index.js +4 -0
  131. package/dist/postgrest/index.js.map +1 -0
  132. package/dist/postgrest/query-builder.d.ts +224 -0
  133. package/dist/postgrest/query-builder.d.ts.map +1 -0
  134. package/dist/postgrest/query-builder.js +544 -0
  135. package/dist/postgrest/query-builder.js.map +1 -0
  136. package/dist/postgrest/rpc.d.ts +12 -0
  137. package/dist/postgrest/rpc.d.ts.map +1 -0
  138. package/dist/postgrest/rpc.js +42 -0
  139. package/dist/postgrest/rpc.js.map +1 -0
  140. package/dist/postgrest/types.d.ts +88 -0
  141. package/dist/postgrest/types.d.ts.map +1 -0
  142. package/dist/postgrest/types.js +2 -0
  143. package/dist/postgrest/types.js.map +1 -0
  144. package/dist/postgrest/utils.d.ts +23 -0
  145. package/dist/postgrest/utils.d.ts.map +1 -0
  146. package/dist/postgrest/utils.js +87 -0
  147. package/dist/postgrest/utils.js.map +1 -0
  148. package/dist/postgrest.d.ts +5 -1
  149. package/dist/postgrest.d.ts.map +1 -1
  150. package/dist/postgrest.js +17 -10
  151. package/dist/postgrest.js.map +1 -1
  152. package/dist/realtime/channel.d.ts +83 -0
  153. package/dist/realtime/channel.d.ts.map +1 -0
  154. package/dist/realtime/channel.js +240 -0
  155. package/dist/realtime/channel.js.map +1 -0
  156. package/dist/realtime/index.d.ts +94 -0
  157. package/dist/realtime/index.d.ts.map +1 -0
  158. package/dist/realtime/index.js +455 -0
  159. package/dist/realtime/index.js.map +1 -0
  160. package/dist/realtime/types.d.ts +120 -0
  161. package/dist/realtime/types.d.ts.map +1 -0
  162. package/dist/realtime/types.js +2 -0
  163. package/dist/realtime/types.js.map +1 -0
  164. package/dist/realtime.d.ts +1 -0
  165. package/dist/realtime.d.ts.map +1 -1
  166. package/dist/realtime.js +26 -1
  167. package/dist/realtime.js.map +1 -1
  168. package/dist/runtime.d.ts +13 -0
  169. package/dist/runtime.d.ts.map +1 -0
  170. package/dist/runtime.js +15 -0
  171. package/dist/runtime.js.map +1 -0
  172. package/dist/session.d.ts +2 -0
  173. package/dist/session.d.ts.map +1 -1
  174. package/dist/session.js +11 -2
  175. package/dist/session.js.map +1 -1
  176. package/dist/storage/bucket.d.ts +166 -0
  177. package/dist/storage/bucket.d.ts.map +1 -0
  178. package/dist/storage/bucket.js +294 -0
  179. package/dist/storage/bucket.js.map +1 -0
  180. package/dist/storage/index.d.ts +45 -0
  181. package/dist/storage/index.d.ts.map +1 -0
  182. package/dist/storage/index.js +55 -0
  183. package/dist/storage/index.js.map +1 -0
  184. package/dist/storage/types.d.ts +131 -0
  185. package/dist/storage/types.d.ts.map +1 -0
  186. package/dist/storage/types.js +2 -0
  187. package/dist/storage/types.js.map +1 -0
  188. package/dist/storage/utils.d.ts +27 -0
  189. package/dist/storage/utils.d.ts.map +1 -0
  190. package/dist/storage/utils.js +43 -0
  191. package/dist/storage/utils.js.map +1 -0
  192. package/dist/test.d.ts +2 -0
  193. package/dist/test.d.ts.map +1 -0
  194. package/dist/test.js +3 -0
  195. package/dist/test.js.map +1 -0
  196. package/dist/types.d.ts +14 -249
  197. package/dist/types.d.ts.map +1 -1
  198. package/dist/utils/compat.d.ts +40 -0
  199. package/dist/utils/compat.d.ts.map +1 -0
  200. package/dist/utils/compat.js +100 -0
  201. package/dist/utils/compat.js.map +1 -0
  202. package/dist/utils/runtime.d.ts +13 -0
  203. package/dist/utils/runtime.d.ts.map +1 -0
  204. package/dist/utils/runtime.js +15 -0
  205. package/dist/utils/runtime.js.map +1 -0
  206. package/dist/utils/testing.d.ts +38 -0
  207. package/dist/utils/testing.d.ts.map +1 -0
  208. package/dist/utils/testing.js +50 -0
  209. package/dist/utils/testing.js.map +1 -0
  210. package/dist/utils/warn.d.ts +2 -0
  211. package/dist/utils/warn.d.ts.map +1 -0
  212. package/dist/utils/warn.js +23 -0
  213. package/dist/utils/warn.js.map +1 -0
  214. package/package.json +13 -11
  215. package/dist/devices.d.ts +0 -13
  216. package/dist/devices.d.ts.map +0 -1
  217. package/dist/devices.js +0 -13
  218. package/dist/devices.js.map +0 -1
  219. package/dist/profile.d.ts +0 -16
  220. package/dist/profile.d.ts.map +0 -1
  221. package/dist/profile.js +0 -26
  222. package/dist/profile.js.map +0 -1
@@ -0,0 +1,294 @@
1
+ import { contractPath, HTTP_ROUTES } from "@motherbase/contracts";
2
+ import { settle, toError, withoutTrailingSlash } from "../http/utils.js";
3
+ import { UUID, uploadBlob, RENDER_ROUTE, encodeKey, transformQuery } from "./utils.js";
4
+ export class StorageBucket {
5
+ constructor(http, baseUrl, bucket,
6
+ /** Used only by `uploadToSignedUrl`, which PUTs straight to object storage. */
7
+ fetchImpl) {
8
+ this.http = http;
9
+ this.baseUrl = baseUrl;
10
+ this.bucket = bucket;
11
+ this.fetchImpl = fetchImpl;
12
+ }
13
+ /**
14
+ * Route for one object. A bare uuid is treated as a file id (the pre-path
15
+ * addressing form, which existing callers have stored); anything else is a
16
+ * key inside this bucket.
17
+ */
18
+ objectPath(pathOrId, kind) {
19
+ if (UUID.test(pathOrId)) {
20
+ if (kind === 'object-info') {
21
+ throw new Error('info() addresses objects by path. Pass the key you uploaded under, not a file id.');
22
+ }
23
+ return contractPath.file(pathOrId, kind === 'object-url' ? 'url' : 'raw');
24
+ }
25
+ return `${HTTP_ROUTES.files}/${kind}/${encodeURIComponent(this.bucket)}/${encodeKey(pathOrId)}`;
26
+ }
27
+ /**
28
+ * Store a file at `path` in this bucket. `upsert: true` replaces an object
29
+ * already stored there.
30
+ * @example client.storage.from('avatars').upload(`${userId}/me.png`, file, { contentType: 'image/png' })
31
+ */
32
+ upload(path, file, options = {}) {
33
+ return settle(async () => {
34
+ const form = new FormData();
35
+ const body = uploadBlob(file, options.contentType);
36
+ if (body) {
37
+ form.append('file', body, path);
38
+ }
39
+ else {
40
+ form.append('file', file);
41
+ }
42
+ if (options.visibility)
43
+ form.append('visibility', options.visibility);
44
+ form.append('bucket', this.bucket);
45
+ form.append('path', path);
46
+ if (options.upsert)
47
+ form.append('upsert', 'true');
48
+ const created = await this.http.request(`${HTTP_ROUTES.files}/`, { method: 'POST', form });
49
+ return { path, id: created.file.id, fullPath: `${this.bucket}/${path}` };
50
+ });
51
+ }
52
+ /**
53
+ * Upload several objects, a few at a time, reporting progress per file.
54
+ *
55
+ * Uploading a folder is the common case and `Promise.all` is the common
56
+ * mistake: a hundred parallel multipart posts saturate the connection, and
57
+ * the server rate limiter answers 429 to the tail of them. Four at a time
58
+ * finishes sooner in practice and fails less.
59
+ *
60
+ * One failing file does not cancel the rest. The result reports every entry
61
+ * in the order it was given, each with its own error or `null`, so the caller
62
+ * can retry exactly what failed.
63
+ *
64
+ * ponytail: progress is per file, not per byte. Byte-level progress needs
65
+ * XMLHttpRequest, which does not exist outside a browser; if a progress bar
66
+ * has to move within one large file, that is the upgrade path.
67
+ */
68
+ async uploadMany(files, options = {}) {
69
+ const total = files.length;
70
+ const requestedConcurrency = options.concurrency ?? 4;
71
+ if (!Number.isSafeInteger(requestedConcurrency) || requestedConcurrency < 1) {
72
+ return { data: null, error: { message: 'concurrency must be a positive integer.' } };
73
+ }
74
+ const concurrency = Math.min(requestedConcurrency, total || 1);
75
+ const results = new Array(total);
76
+ let next = 0;
77
+ let completed = 0;
78
+ // A shared cursor rather than fixed slices: one slow file would otherwise
79
+ // hold up its whole slice while other workers sit idle.
80
+ const worker = async () => {
81
+ for (;;) {
82
+ const index = next++;
83
+ if (index >= total)
84
+ return;
85
+ const entry = files[index];
86
+ const { data, error } = await this.upload(entry.path, entry.file, entry.options);
87
+ results[index] = { path: entry.path, data: data ?? null, error: error?.message ?? null };
88
+ completed += 1;
89
+ options.onProgress?.({ completed, total, path: entry.path, error: error?.message ?? null });
90
+ }
91
+ };
92
+ await Promise.all(Array.from({ length: concurrency }, worker));
93
+ return { data: results, error: null };
94
+ }
95
+ /** The object's bytes. With `transform`, a resized image from the render endpoint instead. */
96
+ download(path, options = {}) {
97
+ return settle(async () => {
98
+ const route = options.transform
99
+ ? `${RENDER_ROUTE}/authenticated/${encodeURIComponent(this.bucket)}/${encodeKey(path)}?${transformQuery(options.transform)}`
100
+ : this.objectPath(path, 'object');
101
+ const res = await this.http.requestRaw(route);
102
+ return res.blob();
103
+ });
104
+ }
105
+ /** Delete these objects. One result per path, in the same order. */
106
+ remove(paths) {
107
+ return settle(() => Promise.all(paths.map(p => this.http.request(
108
+ // A file id deletes through the id route, unlike objectPath's `raw`.
109
+ UUID.test(p) ? contractPath.file(p) : this.objectPath(p, 'object'), { method: 'DELETE' }))));
110
+ }
111
+ /** Objects under a prefix, in the Supabase response shape. */
112
+ list(prefix = '', options = {}) {
113
+ return settle(async () => {
114
+ const query = new URLSearchParams();
115
+ if (prefix)
116
+ query.set('prefix', prefix);
117
+ if (options.limit !== undefined)
118
+ query.set('limit', String(options.limit));
119
+ if (options.offset !== undefined)
120
+ query.set('offset', String(options.offset));
121
+ if (options.search)
122
+ query.set('search', options.search);
123
+ if (options.sortBy?.column)
124
+ query.set('sortColumn', options.sortBy.column);
125
+ if (options.sortBy?.order)
126
+ query.set('sortOrder', options.sortBy.order);
127
+ const suffix = query.toString() ? `?${query}` : '';
128
+ const res = await this.http.request(`${HTTP_ROUTES.files}/list/${encodeURIComponent(this.bucket)}${suffix}`);
129
+ return res.objects;
130
+ });
131
+ }
132
+ /**
133
+ * Synchronous public URL (Supabase parity). Serves through the public bucket
134
+ * endpoint, or through the render endpoint when `transform` is given.
135
+ */
136
+ getPublicUrl(path, options = {}) {
137
+ const base = withoutTrailingSlash(this.baseUrl);
138
+ const publicUrl = options.transform
139
+ ? `${base}${RENDER_ROUTE}/public/${encodeURIComponent(this.bucket)}/${encodeKey(path)}?${transformQuery(options.transform)}`
140
+ : `${base}${contractPath.publicFile(this.bucket, path)}`;
141
+ return { data: { publicUrl } };
142
+ }
143
+ /**
144
+ * A download URL for the object, valid for `expiresIn` seconds (default 3600,
145
+ * maximum 7 days: the AWS SigV4 ceiling; anything outside that is a `400`).
146
+ *
147
+ * `expiresAt` reports when the URL actually stops working, and is `null` when
148
+ * nothing expires: a public object's URL is permanent, and a private object on
149
+ * the `local` storage driver resolves to the authenticated streaming endpoint,
150
+ * which is bound to the session rather than to a clock and so cannot be handed
151
+ * to a third party at all. Check it rather than assuming `expiresIn` applied,
152
+ * that assumption is exactly what this used to get wrong, silently.
153
+ */
154
+ async createSignedUrl(path, expiresIn, options = {}) {
155
+ if (options.transform && UUID.test(path)) {
156
+ return { data: null, error: { message: 'Transforms address objects by path. Pass the key you uploaded under, not a file id.' } };
157
+ }
158
+ return settle(async () => {
159
+ // With a transform the server signs a render URL, which always expires,
160
+ // whatever the driver: an S3 presign cannot carry a resize.
161
+ const query = new URLSearchParams(options.transform ? transformQuery(options.transform) : '');
162
+ if (expiresIn !== undefined)
163
+ query.set('expiresIn', String(expiresIn));
164
+ const suffix = query.toString() ? `?${query}` : '';
165
+ const res = await this.http.request(`${this.objectPath(path, 'object-url')}${suffix}`);
166
+ return { signedUrl: res.url, expiresAt: res.expiresAt ?? null };
167
+ });
168
+ }
169
+ /**
170
+ * Sign several objects in one call.
171
+ *
172
+ * There is no batch endpoint behind this: it signs each key and reports per
173
+ * entry, exactly as supabase-js does, so one missing object yields one entry
174
+ * with an `error` rather than failing the whole batch.
175
+ */
176
+ async createSignedUrls(paths, expiresIn) {
177
+ const results = await Promise.all(paths.map(async (path) => {
178
+ const { data, error } = await this.createSignedUrl(path, expiresIn);
179
+ return { path, signedUrl: data?.signedUrl ?? null, error: error?.message ?? null };
180
+ }));
181
+ return { data: results, error: null };
182
+ }
183
+ /**
184
+ * Replace the object at `path`. In supabase-js `update` is `upload` with
185
+ * upsert forced on, and the same is true here.
186
+ */
187
+ async update(path, file, options = {}) {
188
+ return this.upload(path, file, { ...options, upsert: true });
189
+ }
190
+ /** Copy an object to another key in this bucket. */
191
+ async copy(from, to, options = {}) {
192
+ return this.transfer('copy', from, to, options);
193
+ }
194
+ /** Move an object to another key in this bucket (copy, then delete the source). */
195
+ async move(from, to, options = {}) {
196
+ return this.transfer('move', from, to, options);
197
+ }
198
+ transfer(action, from, to, options) {
199
+ return settle(async () => {
200
+ const res = await this.http.request(`${HTTP_ROUTES.files}/${action}`, { method: 'POST', body: { bucket: this.bucket, from, to, upsert: options.upsert === true } });
201
+ return { path: res.fullPath ?? `${this.bucket}/${to}` };
202
+ });
203
+ }
204
+ /** One object's metadata, without downloading it. */
205
+ info(path) {
206
+ return settle(() => this.http.request(this.objectPath(path, 'object-info')));
207
+ }
208
+ /**
209
+ * Whether an object exists and this caller can read it.
210
+ *
211
+ * A 404 is the answer `false`, not a failure. Anything else (a 403, a network
212
+ * error) is reported as an error rather than as "no": treating an
213
+ * authorization failure as absence is how a UI ends up offering to create
214
+ * something that is already there.
215
+ */
216
+ async exists(path) {
217
+ const { data, error } = await this.info(path);
218
+ if (data)
219
+ return { data: true, error: null };
220
+ if (error?.status === 404)
221
+ return { data: false, error: null };
222
+ return { data: null, error: error ?? { message: 'Unknown storage error' } };
223
+ }
224
+ /**
225
+ * Mint a URL the browser can PUT the bytes to directly, skipping this server.
226
+ *
227
+ * Unlike supabase-js this needs the file's `size` and content type up front:
228
+ * the upload is reserved against the bucket quota and the signature is bound
229
+ * to that exact length, which is what stops a signed URL from becoming an
230
+ * unbounded write. Pair it with `uploadToSignedUrl`.
231
+ *
232
+ * Requires the S3 driver; the local driver has no presigned uploads.
233
+ */
234
+ createSignedUploadUrl(path, options) {
235
+ return settle(async () => {
236
+ const res = await this.http.request(`${HTTP_ROUTES.files}/presign`, {
237
+ method: 'POST',
238
+ body: {
239
+ bucket: this.bucket,
240
+ path,
241
+ size: options.size,
242
+ mime: options.contentType,
243
+ visibility: options.visibility,
244
+ },
245
+ });
246
+ // supabase-js's `token` is opaque to the caller and is handed straight
247
+ // back to uploadToSignedUrl, so it carries what finalisation needs.
248
+ const token = JSON.stringify({ url: res.uploadUrl, id: res.file.id, finalizeToken: res.finalizeToken, contentType: options.contentType, path, bucket: this.bucket });
249
+ return { signedUrl: res.uploadUrl, token, path };
250
+ });
251
+ }
252
+ /**
253
+ * Upload to a URL from `createSignedUploadUrl`: PUT the bytes to storage,
254
+ * then tell the server the object landed. The finalise step is what makes the
255
+ * row readable, so a PUT that succeeds and a finalise that fails leaves the
256
+ * reservation to expire rather than a half-visible object.
257
+ */
258
+ async uploadToSignedUrl(path, token, file, options = {}) {
259
+ let parsed;
260
+ try {
261
+ const value = JSON.parse(token);
262
+ if (!value || typeof value !== 'object' || typeof value.url !== 'string' || typeof value.id !== 'string' || !value.id
263
+ || !['http:', 'https:'].includes(new URL(value.url).protocol)
264
+ || (value.path !== undefined && value.path !== path)
265
+ || (value.bucket !== undefined && value.bucket !== this.bucket)
266
+ || (value.contentType !== undefined && typeof value.contentType !== 'string')
267
+ || (value.finalizeToken !== undefined && typeof value.finalizeToken !== 'string'))
268
+ throw new Error('Invalid upload token');
269
+ parsed = value;
270
+ }
271
+ catch {
272
+ return { data: null, error: { message: 'Invalid upload token. Use the token from createSignedUploadUrl().' } };
273
+ }
274
+ try {
275
+ const body = uploadBlob(file, options.contentType ?? parsed.contentType);
276
+ if (!body)
277
+ throw new Error('Signed uploads require a Blob, ArrayBuffer or typed array.');
278
+ const put = await this.fetchImpl(parsed.url, {
279
+ method: 'PUT',
280
+ body,
281
+ headers: { 'Content-Type': body.type || 'application/octet-stream' },
282
+ });
283
+ if (!put.ok) {
284
+ return { data: null, error: { message: `Upload failed with status ${put.status}`, status: put.status } };
285
+ }
286
+ await this.http.request(`${contractPath.file(parsed.id)}/finalize`, { method: 'POST', body: { token: parsed.finalizeToken } });
287
+ return { data: { path, id: parsed.id, fullPath: `${this.bucket}/${path}` }, error: null };
288
+ }
289
+ catch (err) {
290
+ return { data: null, error: toError(err) };
291
+ }
292
+ }
293
+ }
294
+ //# sourceMappingURL=bucket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bucket.js","sourceRoot":"","sources":["../../src/storage/bucket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { HttpClient } from "../http/index.js";
2
+ import { MotherbaseResponse } from "../types.js";
3
+ import { StorageBucket } from "./bucket.js";
4
+ import { BucketInfo, BucketOptions } from "./types.js";
5
+ /** Supabase-compatible storage client: `client.storage.from(bucket)`. */
6
+ export declare class StorageClient {
7
+ private readonly http;
8
+ private readonly baseUrl;
9
+ private readonly fetchImpl;
10
+ constructor(http: HttpClient, baseUrl: string, fetchImpl: typeof fetch);
11
+ /** The files of one bucket: upload, download, list, sign URLs. */
12
+ from(bucket: string): StorageBucket;
13
+ /**
14
+ * Bucket administration, supabase-js shaped.
15
+ *
16
+ * Every method here needs a SECRET project API key, which is the same rule
17
+ * Supabase applies (bucket administration is a service-role operation). With
18
+ * a publishable key they resolve with a 401 error, so keep them in server
19
+ * code and setup scripts, never in a browser bundle.
20
+ */
21
+ listBuckets(): Promise<MotherbaseResponse<BucketInfo[]>>;
22
+ /** One bucket's settings. Secret key only. */
23
+ getBucket(id: string): Promise<MotherbaseResponse<BucketInfo>>;
24
+ /** Create a bucket, private unless `public: true`. Secret key only. */
25
+ createBucket(id: string, options?: BucketOptions): Promise<MotherbaseResponse<BucketInfo>>;
26
+ /** Change a bucket's visibility, size limit or allowed file types. Secret key only. */
27
+ updateBucket(id: string, options: BucketOptions): Promise<MotherbaseResponse<BucketInfo>>;
28
+ /** Delete every object in the bucket, keeping the bucket itself. */
29
+ emptyBucket(id: string): Promise<MotherbaseResponse<{
30
+ emptied: boolean;
31
+ removed: number;
32
+ }>>;
33
+ /**
34
+ * Delete the bucket. A bucket that still holds objects is a `409` unless
35
+ * `force` is set, which queues a background deletion of its contents: an
36
+ * accidental `deleteBucket` must not be able to destroy a project's files in
37
+ * one unqualified call.
38
+ */
39
+ deleteBucket(id: string, options?: {
40
+ force?: boolean;
41
+ }): Promise<MotherbaseResponse<{
42
+ deleted: boolean;
43
+ }>>;
44
+ }
45
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKvD,yEAAyE;AACzE,qBAAa,aAAa;IAElB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAFT,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,KAAK;IAG5C,kEAAkE;IAClE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa;IAInC;;;;;;;OAOG;IACH,WAAW,IAAI,OAAO,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC,CAAC;IAIxD,8CAA8C;IAC9C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAI9D,uEAAuE;IACvE,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAK9F,uFAAuF;IACvF,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAIzF,oEAAoE;IACpE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAI3F;;;;;OAKG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAIjH"}
@@ -0,0 +1,55 @@
1
+ import { settle } from "../http/utils.js";
2
+ import { StorageBucket } from "./bucket.js";
3
+ import { BUCKET_ROUTE, bucketBody } from "./utils.js";
4
+ const bucketPath = (id) => `${BUCKET_ROUTE}/${encodeURIComponent(id)}`;
5
+ /** Supabase-compatible storage client: `client.storage.from(bucket)`. */
6
+ export class StorageClient {
7
+ constructor(http, baseUrl, fetchImpl) {
8
+ this.http = http;
9
+ this.baseUrl = baseUrl;
10
+ this.fetchImpl = fetchImpl;
11
+ }
12
+ /** The files of one bucket: upload, download, list, sign URLs. */
13
+ from(bucket) {
14
+ return new StorageBucket(this.http, this.baseUrl, bucket, this.fetchImpl);
15
+ }
16
+ /**
17
+ * Bucket administration, supabase-js shaped.
18
+ *
19
+ * Every method here needs a SECRET project API key, which is the same rule
20
+ * Supabase applies (bucket administration is a service-role operation). With
21
+ * a publishable key they resolve with a 401 error, so keep them in server
22
+ * code and setup scripts, never in a browser bundle.
23
+ */
24
+ listBuckets() {
25
+ return settle(async () => (await this.http.request(BUCKET_ROUTE)).buckets);
26
+ }
27
+ /** One bucket's settings. Secret key only. */
28
+ getBucket(id) {
29
+ return settle(() => this.http.request(bucketPath(id)));
30
+ }
31
+ /** Create a bucket, private unless `public: true`. Secret key only. */
32
+ createBucket(id, options = {}) {
33
+ const body = { id, ...bucketBody(options), public: options.public === true };
34
+ return settle(() => this.http.request(BUCKET_ROUTE, { method: 'POST', body }));
35
+ }
36
+ /** Change a bucket's visibility, size limit or allowed file types. Secret key only. */
37
+ updateBucket(id, options) {
38
+ return settle(() => this.http.request(bucketPath(id), { method: 'PUT', body: bucketBody(options) }));
39
+ }
40
+ /** Delete every object in the bucket, keeping the bucket itself. */
41
+ emptyBucket(id) {
42
+ return settle(() => this.http.request(`${bucketPath(id)}/empty`, { method: 'POST' }));
43
+ }
44
+ /**
45
+ * Delete the bucket. A bucket that still holds objects is a `409` unless
46
+ * `force` is set, which queues a background deletion of its contents: an
47
+ * accidental `deleteBucket` must not be able to destroy a project's files in
48
+ * one unqualified call.
49
+ */
50
+ deleteBucket(id, options = {}) {
51
+ const query = options.force ? '?force=true' : '';
52
+ return settle(() => this.http.request(`${bucketPath(id)}${query}`, { method: 'DELETE' }));
53
+ }
54
+ }
55
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,GAAG,YAAY,IAAI,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;AAE/E,yEAAyE;AACzE,MAAM,OAAO,aAAa;IACtB,YACqB,IAAgB,EAChB,OAAe,EACf,SAAuB;QAFvB,SAAI,GAAJ,IAAI,CAAY;QAChB,YAAO,GAAP,OAAO,CAAQ;QACf,cAAS,GAAT,SAAS,CAAc;IACxC,CAAC;IAEL,kEAAkE;IAClE,IAAI,CAAC,MAAc;QACf,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC;IAED;;;;;;;OAOG;IACH,WAAW;QACP,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAA4B,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC1G,CAAC;IAED,8CAA8C;IAC9C,SAAS,CAAC,EAAU;QAChB,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAa,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,uEAAuE;IACvE,YAAY,CAAC,EAAU,EAAE,UAAyB,EAAE;QAChD,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC7E,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAa,YAAY,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/F,CAAC;IAED,uFAAuF;IACvF,YAAY,CAAC,EAAU,EAAE,OAAsB;QAC3C,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAa,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACrH,CAAC;IAED,oEAAoE;IACpE,WAAW,CAAC,EAAU;QAClB,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAwC,GAAG,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACjI,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,EAAU,EAAE,UAA+B,EAAE;QACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,OAAO,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAuB,GAAG,UAAU,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACpH,CAAC;CACJ"}
@@ -0,0 +1,131 @@
1
+ import type { StorageRemoveContract, StorageUploadContract } from '@motherbase/contracts';
2
+ export type FileVisibility = 'public' | 'private';
3
+ /** Lifecycle of a stored object: `ready` unless a presigned upload is pending. */
4
+ export type FileStatus = 'pending' | 'ready' | 'expired';
5
+ /**
6
+ * A row of the storage table, as `POST /api/files/` returns it.
7
+ *
8
+ * This is the upload shape, not the `list()` shape: `list()` answers in the
9
+ * supabase-js `FileObject` form, which is a different set of fields under
10
+ * different names. Conflating the two is what the old `[key: string]: unknown`
11
+ * hid, and `file.filename` (a field the server never sent) type-checked.
12
+ */
13
+ export interface StoredFile {
14
+ id: string;
15
+ /** Bucket slug. */
16
+ bucket: string;
17
+ /** Object key inside the bucket, including any prefix. */
18
+ key: string;
19
+ mime?: string | null;
20
+ size: number;
21
+ visibility: FileVisibility;
22
+ status: FileStatus;
23
+ /** Set for public objects and for drivers that store an absolute URL. */
24
+ url?: string | null;
25
+ ownerId?: string | null;
26
+ bucketId?: string | null;
27
+ /** Deadline of a presigned upload that has not been finalised. */
28
+ uploadExpiresAt?: string | null;
29
+ createdAt: string;
30
+ updatedAt: string;
31
+ }
32
+ /**
33
+ * One object as `list()` returns it: the supabase-js `FileObject` shape, which
34
+ * is what code ported from Supabase reads (`obj.name`, `obj.metadata.size`).
35
+ */
36
+ export interface FileObject {
37
+ /** Key relative to the bucket. */
38
+ name: string;
39
+ id: string;
40
+ created_at: string | null;
41
+ updated_at: string | null;
42
+ last_accessed_at: string | null;
43
+ metadata: {
44
+ size: number;
45
+ mimetype: string | null;
46
+ cacheControl: string | null;
47
+ };
48
+ }
49
+ /** Exact payload returned by `POST /api/files/`. */
50
+ export type StorageUploadResponse = StorageUploadContract<StoredFile>;
51
+ /** Exact payload returned by `DELETE /api/files/:id`. */
52
+ export type StorageRemoveResponse = StorageRemoveContract;
53
+ /** A file-ish value accepted by multipart uploads (browser File/Blob or RN asset). */
54
+ export type UploadInput = Blob | ArrayBuffer | ArrayBufferView | {
55
+ uri: string;
56
+ name?: string;
57
+ type?: string;
58
+ };
59
+ export interface UploadOptions {
60
+ /** Object visibility. Defaults to the backend's default (private). */
61
+ visibility?: FileVisibility;
62
+ /** Content type stored with the object. Overrides what the file itself declares. */
63
+ contentType?: string;
64
+ upsert?: boolean;
65
+ }
66
+ export interface UploadResult {
67
+ /** The object key, exactly as passed to `upload`. */
68
+ path: string;
69
+ /** The server-issued file id. Still accepted anywhere a path is. */
70
+ id: string;
71
+ /** `bucket/key`. */
72
+ fullPath: string;
73
+ }
74
+ /** A bucket, in the supabase-js shape. `id` is the slug. */
75
+ export interface BucketInfo {
76
+ id: string;
77
+ name: string;
78
+ owner: string;
79
+ public: boolean;
80
+ /** Largest object the bucket accepts, in bytes. `null` defers to the project limit. */
81
+ file_size_limit: number | null;
82
+ /** MIME allowlist (`image/*` wildcards allowed). `null` accepts any type. */
83
+ allowed_mime_types: string[] | null;
84
+ created_at: string | null;
85
+ updated_at: string | null;
86
+ }
87
+ /** supabase-js `createBucket` / `updateBucket` options. */
88
+ export interface BucketOptions {
89
+ public?: boolean;
90
+ name?: string;
91
+ /** Bytes, or a string with a unit: `'20MB'`, `'1GB'`. `null` removes the limit. */
92
+ fileSizeLimit?: number | string | null;
93
+ /** `['image/*', 'application/pdf']`. `null` or `[]` accepts any type. */
94
+ allowedMimeTypes?: string[] | null;
95
+ }
96
+ /** One object's metadata, in the supabase-js `info()` shape. */
97
+ export interface ObjectInfo {
98
+ name: string;
99
+ id: string;
100
+ version: string | null;
101
+ bucket_id: string;
102
+ created_at: string | null;
103
+ updated_at: string | null;
104
+ last_accessed_at: string | null;
105
+ size: number;
106
+ content_type: string | null;
107
+ cache_control: string | null;
108
+ metadata: Record<string, unknown>;
109
+ }
110
+ /**
111
+ * supabase-js image transform options. Served by `/storage/v1/render/image`,
112
+ * resized with the same limits Supabase applies (1 to 2500 px, quality 20 to
113
+ * 100). Without `format` the server answers WebP to clients that accept it.
114
+ */
115
+ export interface TransformOptions {
116
+ width?: number;
117
+ height?: number;
118
+ resize?: 'cover' | 'contain' | 'fill';
119
+ quality?: number;
120
+ format?: 'origin' | 'webp' | 'avif';
121
+ }
122
+ export interface ListOptions {
123
+ limit?: number;
124
+ offset?: number;
125
+ search?: string;
126
+ sortBy?: {
127
+ column?: 'name' | 'created_at' | 'updated_at';
128
+ order?: 'asc' | 'desc';
129
+ };
130
+ }
131
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/storage/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { BucketOptions, TransformOptions, UploadInput } from "./types.js";
2
+ /** The wire shape of BucketOptions: the snake_case keys Supabase's API uses. */
3
+ export declare function bucketBody(options: BucketOptions): {
4
+ name: string | undefined;
5
+ public: boolean | undefined;
6
+ file_size_limit: string | number | null | undefined;
7
+ allowed_mime_types: string[] | null | undefined;
8
+ };
9
+ /** Bucket administration lives one level up from an object route. */
10
+ export declare const BUCKET_ROUTE: string;
11
+ export declare const RENDER_ROUTE: string;
12
+ /** `?width=…` for a transform, in the key order the server signs. */
13
+ export declare function transformQuery(transform: TransformOptions): string;
14
+ export declare const encodeKey: (path: string) => string;
15
+ /**
16
+ * Supabase-compatible storage bucket handle over the authenticated
17
+ * `/api/files` endpoints.
18
+ *
19
+ * Objects are addressed by path: `upload('123/pic.png')` then
20
+ * `download('123/pic.png')`. The server-issued file id still works everywhere a
21
+ * path does, because that is what every caller written before path addressing
22
+ * has stored.
23
+ */
24
+ export declare const UUID: RegExp;
25
+ /** Preserve a typed-array view's boundaries (including Node Buffer slices). */
26
+ export declare function uploadBlob(file: UploadInput, contentType?: string): Blob | undefined;
27
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/storage/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1E,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,OAAO,EAAE,aAAa;;;;;EAOhD;AAED,qEAAqE;AACrE,eAAO,MAAM,YAAY,QAAgC,CAAC;AAE1D,eAAO,MAAM,YAAY,QAA0C,CAAC;AAEpE,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,CAMlE;AAED,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,WAAsD,CAAC;AAE7F;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,QAAoE,CAAC;AAEtF,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAOpF"}
@@ -0,0 +1,43 @@
1
+ import { HTTP_ROUTES } from "@motherbase/contracts";
2
+ /** The wire shape of BucketOptions: the snake_case keys Supabase's API uses. */
3
+ export function bucketBody(options) {
4
+ return {
5
+ name: options.name,
6
+ public: options.public,
7
+ file_size_limit: options.fileSizeLimit,
8
+ allowed_mime_types: options.allowedMimeTypes,
9
+ };
10
+ }
11
+ /** Bucket administration lives one level up from an object route. */
12
+ export const BUCKET_ROUTE = `${HTTP_ROUTES.files}/bucket`;
13
+ export const RENDER_ROUTE = `${HTTP_ROUTES.storageV1}/render/image`;
14
+ /** `?width=…` for a transform, in the key order the server signs. */
15
+ export function transformQuery(transform) {
16
+ const query = new URLSearchParams();
17
+ for (const key of ['width', 'height', 'resize', 'quality', 'format']) {
18
+ if (transform[key] !== undefined)
19
+ query.set(key, String(transform[key]));
20
+ }
21
+ return query.toString();
22
+ }
23
+ export const encodeKey = (path) => path.split('/').map(encodeURIComponent).join('/');
24
+ /**
25
+ * Supabase-compatible storage bucket handle over the authenticated
26
+ * `/api/files` endpoints.
27
+ *
28
+ * Objects are addressed by path: `upload('123/pic.png')` then
29
+ * `download('123/pic.png')`. The server-issued file id still works everywhere a
30
+ * path does, because that is what every caller written before path addressing
31
+ * has stored.
32
+ */
33
+ export const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
34
+ /** Preserve a typed-array view's boundaries (including Node Buffer slices). */
35
+ export function uploadBlob(file, contentType) {
36
+ if (typeof Blob !== 'undefined' && file instanceof Blob) {
37
+ return contentType ? file.slice(0, file.size, contentType) : file;
38
+ }
39
+ const bytes = file instanceof ArrayBuffer ? file
40
+ : ArrayBuffer.isView(file) ? new Uint8Array(file.buffer, file.byteOffset, file.byteLength).slice() : undefined;
41
+ return bytes === undefined ? undefined : new Blob([bytes], { type: contentType || 'application/octet-stream' });
42
+ }
43
+ //# sourceMappingURL=utils.js.map