@edgestore/shared 0.0.0-canary-20260730114359

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 (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/errors/EdgeStoreError.d.ts +47 -0
  4. package/dist/errors/EdgeStoreError.d.ts.map +1 -0
  5. package/dist/errors/EdgeStoreError.js +43 -0
  6. package/dist/errors/index.d.ts +9 -0
  7. package/dist/errors/index.d.ts.map +1 -0
  8. package/dist/errors/index.js +20 -0
  9. package/dist/index.d.ts +8 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +3 -0
  12. package/dist/internals/bucketBuilder.d.ts +315 -0
  13. package/dist/internals/bucketBuilder.d.ts.map +1 -0
  14. package/dist/internals/bucketBuilder.js +230 -0
  15. package/dist/internals/createPathParamProxy.d.ts +21 -0
  16. package/dist/internals/createPathParamProxy.d.ts.map +1 -0
  17. package/dist/internals/createPathParamProxy.js +29 -0
  18. package/dist/internals/providerCapabilities.d.ts +44 -0
  19. package/dist/internals/providerCapabilities.d.ts.map +1 -0
  20. package/dist/internals/providerTypes.d.ts +270 -0
  21. package/dist/internals/providerTypes.d.ts.map +1 -0
  22. package/dist/internals/sharedFuncTypes.d.ts +30 -0
  23. package/dist/internals/sharedFuncTypes.d.ts.map +1 -0
  24. package/dist/internals/types.d.ts +47 -0
  25. package/dist/internals/types.d.ts.map +1 -0
  26. package/dist/types.d.ts +94 -0
  27. package/dist/types.d.ts.map +1 -0
  28. package/package.json +81 -0
  29. package/src/errors/EdgeStoreError.ts +89 -0
  30. package/src/errors/index.ts +14 -0
  31. package/src/index.ts +7 -0
  32. package/src/internals/bucketBuilder.ts +677 -0
  33. package/src/internals/createPathParamProxy.ts +40 -0
  34. package/src/internals/providerCapabilities.ts +126 -0
  35. package/src/internals/providerTypes.ts +388 -0
  36. package/src/internals/sharedFuncTypes.ts +38 -0
  37. package/src/internals/types.ts +52 -0
  38. package/src/types.ts +146 -0
@@ -0,0 +1,126 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import type {
3
+ BackendFile,
4
+ GetSignedUrlRes,
5
+ ProviderFileMutationResult,
6
+ } from './providerTypes';
7
+
8
+ export type ProviderCapabilityName =
9
+ | 'upload'
10
+ | 'get'
11
+ | 'list'
12
+ | 'confirm'
13
+ | 'delete'
14
+ | 'restore'
15
+ | 'getSignedUrls';
16
+
17
+ export type ProviderCapability<
18
+ TProvider,
19
+ TName extends ProviderCapabilityName,
20
+ > = TName extends 'upload'
21
+ ? TProvider extends { uploads: { upload: infer TOperation } }
22
+ ? Extract<TOperation, (...args: never[]) => unknown>
23
+ : never
24
+ : TProvider extends {
25
+ files: infer TFiles;
26
+ }
27
+ ? TName extends keyof TFiles
28
+ ? Extract<TFiles[TName], (...args: never[]) => unknown>
29
+ : never
30
+ : never;
31
+
32
+ export type ProviderCapabilityInput<
33
+ TProvider,
34
+ TName extends ProviderCapabilityName,
35
+ > = Parameters<ProviderCapability<TProvider, TName>>[0];
36
+
37
+ export type ProviderCapabilityResult<
38
+ TProvider,
39
+ TName extends ProviderCapabilityName,
40
+ > = Awaited<ReturnType<ProviderCapability<TProvider, TName>>>;
41
+
42
+ type ProviderReferenceSchema<TProvider> = TProvider extends {
43
+ reference: {
44
+ schema: infer TSchema extends StandardSchemaV1;
45
+ };
46
+ }
47
+ ? TSchema
48
+ : never;
49
+
50
+ export type ProviderReferenceInput<TProvider> = StandardSchemaV1.InferInput<
51
+ ProviderReferenceSchema<TProvider>
52
+ >;
53
+
54
+ export type ProviderReference<TProvider> = StandardSchemaV1.InferOutput<
55
+ ProviderReferenceSchema<TProvider>
56
+ >;
57
+
58
+ export type ProviderCursor<TProvider> = TProvider extends {
59
+ files: {
60
+ cursorSchema: infer TSchema extends StandardSchemaV1;
61
+ };
62
+ }
63
+ ? StandardSchemaV1.InferOutput<TSchema>
64
+ : string;
65
+
66
+ export type ProviderCapabilityFile<
67
+ TProvider,
68
+ TName extends 'upload' | 'get' | 'list',
69
+ > = TName extends 'upload'
70
+ ? ProviderCapabilityResult<TProvider, TName> extends {
71
+ file: infer TFile extends BackendFile;
72
+ }
73
+ ? TFile
74
+ : never
75
+ : TName extends 'list'
76
+ ? ProviderCapabilityResult<TProvider, TName> extends {
77
+ items: (infer TFile extends BackendFile)[];
78
+ }
79
+ ? TFile
80
+ : never
81
+ : ProviderCapabilityResult<TProvider, TName> extends BackendFile
82
+ ? ProviderCapabilityResult<TProvider, TName>
83
+ : never;
84
+
85
+ export type ProviderMutationItem<
86
+ TProvider,
87
+ TName extends 'confirm' | 'delete' | 'restore',
88
+ > =
89
+ ProviderCapabilityResult<TProvider, TName> extends {
90
+ results: (infer TItem)[];
91
+ }
92
+ ? TItem
93
+ : never;
94
+
95
+ export type ProviderMutationError<
96
+ TProvider,
97
+ TName extends 'confirm' | 'delete' | 'restore',
98
+ > =
99
+ Extract<ProviderMutationItem<TProvider, TName>, { success: false }> extends {
100
+ error: infer TError;
101
+ }
102
+ ? TError
103
+ : never;
104
+
105
+ type ProviderMutationErrorCode<
106
+ TProvider,
107
+ TName extends 'confirm' | 'delete' | 'restore',
108
+ > =
109
+ ProviderMutationError<TProvider, TName> extends {
110
+ code: infer TErrorCode extends string;
111
+ }
112
+ ? TErrorCode
113
+ : never;
114
+
115
+ export type ProviderSignedUrlResult<TProvider> =
116
+ ProviderCapabilityResult<
117
+ TProvider,
118
+ 'getSignedUrls'
119
+ > extends (infer TResult extends GetSignedUrlRes)[]
120
+ ? TResult
121
+ : never;
122
+
123
+ export type ProviderMutationResult<
124
+ TProvider,
125
+ TName extends 'confirm' | 'delete' | 'restore',
126
+ > = ProviderFileMutationResult<ProviderMutationErrorCode<TProvider, TName>>;
@@ -0,0 +1,388 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import { type MaybePromise } from '../types';
3
+ import {
4
+ type AnyContext,
5
+ type AnyMetadata,
6
+ type EdgeStoreRouter,
7
+ } from './bucketBuilder';
8
+
9
+ export type InitParams<TCtx extends AnyContext = AnyContext> = {
10
+ ctx: TCtx;
11
+ router: EdgeStoreRouter<TCtx>;
12
+ };
13
+
14
+ export type ClientInit = {
15
+ path: string;
16
+ headers?: Record<string, string>;
17
+ };
18
+
19
+ export type InitRes = {
20
+ token?: string;
21
+ clientInit?: ClientInit;
22
+ };
23
+
24
+ export type RequestUploadParams = {
25
+ multipart?: {
26
+ uploadId?: string;
27
+ parts: number[];
28
+ };
29
+ bucketName: string;
30
+ bucketType: string;
31
+ fileInfo: {
32
+ type?: string;
33
+ size: number;
34
+ extension: string;
35
+ isPublic: boolean;
36
+ fileName?: string;
37
+ path: {
38
+ key: string;
39
+ value: string;
40
+ }[];
41
+ metadata: AnyMetadata;
42
+ replaceTargetUrl?: string;
43
+ temporary: boolean;
44
+ };
45
+ autoSignedUrls?: {
46
+ expiresIn?: number;
47
+ includeThumbnails?: boolean;
48
+ };
49
+ };
50
+
51
+ export type ProviderFilterValue =
52
+ | string
53
+ | Partial<{
54
+ eq: string;
55
+ neq: string;
56
+ gt: string;
57
+ gte: string;
58
+ lt: string;
59
+ lte: string;
60
+ startsWith: string;
61
+ endsWith: string;
62
+ between: [string, string];
63
+ }>;
64
+
65
+ export type ListFilesFilter = {
66
+ AND?: ListFilesFilter[];
67
+ OR?: ListFilesFilter[];
68
+ uploadedAt?: ProviderFilterValue;
69
+ path?: Record<string, ProviderFilterValue>;
70
+ metadata?: Record<string, ProviderFilterValue>;
71
+ };
72
+
73
+ export type FileReference = { id: string } | { key: string } | { url: string };
74
+
75
+ export type ProviderFile = {
76
+ id: string;
77
+ url: string;
78
+ key: string;
79
+ thumbnailUrl: string | null;
80
+ thumbnailKey: string | null;
81
+ bucketId: string;
82
+ bucketName: string;
83
+ projectId: string;
84
+ accountId: string;
85
+ name: string;
86
+ path: Record<string, string>;
87
+ metadata: Record<string, string>;
88
+ sizeBytes: number;
89
+ mimeType: string | null;
90
+ state: 'requested' | 'uploaded' | 'deleted' | 'replace_requested';
91
+ temporary: boolean;
92
+ uploadedAt: Date;
93
+ updatedAt: Date;
94
+ };
95
+
96
+ export type BackendFile = {
97
+ url: string;
98
+ sizeBytes: number;
99
+ path: Record<string, string>;
100
+ metadata: Record<string, string>;
101
+ uploadedAt: Date | string;
102
+ updatedAt: Date | string;
103
+ };
104
+
105
+ export type ProviderFileMutationResult<
106
+ TErrorCode extends string =
107
+ | 'FILE_NOT_CONFIRMABLE'
108
+ | 'FILE_NOT_DELETABLE'
109
+ | 'FILE_NOT_RESTORABLE'
110
+ | 'INVALID_FILE_REF',
111
+ > = {
112
+ results: (
113
+ | { success: true }
114
+ | {
115
+ success: false;
116
+ error: {
117
+ code: TErrorCode;
118
+ message: string;
119
+ };
120
+ }
121
+ )[];
122
+ };
123
+
124
+ export type BackendUploadParams = {
125
+ bucketName: string;
126
+ bucketType: string;
127
+ fileInfo: RequestUploadParams['fileInfo'];
128
+ autoSignedUrls?: RequestUploadParams['autoSignedUrls'];
129
+ source: Blob;
130
+ signal?: AbortSignal;
131
+ onProgress?: (progress: {
132
+ transferredBytes: number;
133
+ totalBytes: number;
134
+ percentage: number;
135
+ phase: 'preparing' | 'uploading' | 'processing';
136
+ }) => void;
137
+ };
138
+
139
+ export type BackendUploadResult<TFile extends BackendFile = ProviderFile> = {
140
+ file: TFile;
141
+ signedReadUrl?: {
142
+ signedUrl: string;
143
+ signedThumbnailUrl?: string | null;
144
+ expiresAt: Date | string;
145
+ expiresIn: number;
146
+ };
147
+ };
148
+
149
+ export type BackendUploadOperation<TFile extends BackendFile = ProviderFile> = (
150
+ params: BackendUploadParams,
151
+ ) => MaybePromise<BackendUploadResult<TFile>>;
152
+
153
+ export type BackendGetFileOperation<
154
+ TFile extends BackendFile = ProviderFile,
155
+ TFileReference = FileReference,
156
+ > = (params: {
157
+ bucketName: string;
158
+ file: TFileReference;
159
+ }) => MaybePromise<TFile>;
160
+
161
+ export type BackendListFilesResult<
162
+ TFile extends BackendFile = ProviderFile,
163
+ TCursor = string,
164
+ > = {
165
+ items: TFile[];
166
+ limit: number;
167
+ nextCursor: TCursor | null;
168
+ hasMore: boolean;
169
+ };
170
+
171
+ export type BackendListFilesOperation<
172
+ TFile extends BackendFile = ProviderFile,
173
+ TCursor = string,
174
+ > = (params: {
175
+ bucketName: string;
176
+ filter?: ListFilesFilter;
177
+ cursor?: TCursor;
178
+ limit?: number;
179
+ }) => MaybePromise<BackendListFilesResult<TFile, TCursor>>;
180
+
181
+ export type BackendFileMutationOperation<
182
+ TFileReference = FileReference,
183
+ TErrorCode extends string =
184
+ | 'FILE_NOT_CONFIRMABLE'
185
+ | 'FILE_NOT_DELETABLE'
186
+ | 'FILE_NOT_RESTORABLE'
187
+ | 'INVALID_FILE_REF',
188
+ > = (params: {
189
+ bucketName: string;
190
+ files: TFileReference[];
191
+ }) => MaybePromise<ProviderFileMutationResult<TErrorCode>>;
192
+
193
+ export type BackendGetSignedUrlsOperation<
194
+ TFileReference = FileReference,
195
+ TResult extends GetSignedUrlRes = GetSignedUrlRes,
196
+ > = (params: {
197
+ bucketName: string;
198
+ files: TFileReference[];
199
+ expiresIn?: number;
200
+ includeThumbnails?: boolean;
201
+ }) => MaybePromise<TResult[]>;
202
+
203
+ export type RequestUploadPartsParams = {
204
+ multipart: {
205
+ uploadId: string;
206
+ parts: number[];
207
+ };
208
+ path: string;
209
+ };
210
+
211
+ export type RequestUploadPartsRes = {
212
+ multipart: {
213
+ uploadId: string;
214
+ parts: {
215
+ partNumber: number;
216
+ uploadUrl: string;
217
+ }[];
218
+ };
219
+ };
220
+
221
+ export type CompleteMultipartUploadParams = {
222
+ uploadId: string;
223
+ key: string;
224
+ parts: {
225
+ partNumber: number;
226
+ eTag: string;
227
+ }[];
228
+ };
229
+
230
+ type RequestUploadAccess = {
231
+ accessUrl: string;
232
+ thumbnailUrl?: string | null;
233
+ accessSignedUrl?: string;
234
+ accessSignedThumbnailUrl?: string | null;
235
+ accessSignedUrlExpiresAt?: Date | string;
236
+ accessSignedUrlExpiresIn?: number;
237
+ };
238
+
239
+ export type SinglePartRequestUploadRes = RequestUploadAccess & {
240
+ uploadUrl: string;
241
+ };
242
+
243
+ export type MultipartRequestUploadRes = RequestUploadAccess & {
244
+ multipart: {
245
+ key: string;
246
+ uploadId: string;
247
+ partSize: number;
248
+ totalParts: number;
249
+ parts: {
250
+ partNumber: number;
251
+ uploadUrl: string;
252
+ }[];
253
+ };
254
+ };
255
+
256
+ export type RequestUploadRes =
257
+ SinglePartRequestUploadRes | MultipartRequestUploadRes;
258
+
259
+ export type GetSignedUrlRes = {
260
+ url: string;
261
+ signedUrl: string;
262
+ expiresAt: Date;
263
+ expiresIn: number;
264
+ thumbnailUrl?: string | null;
265
+ signedThumbnailUrl?: string | null;
266
+ };
267
+
268
+ export type ProviderReferenceDefinition<
269
+ TSchema extends StandardSchemaV1 = StandardSchemaV1,
270
+ > = {
271
+ schema: TSchema;
272
+ fromUrl: (url: string) => MaybePromise<unknown>;
273
+ };
274
+
275
+ type ProviderUploadBase<
276
+ TUpload extends BackendUploadOperation<BackendFile> | undefined =
277
+ BackendUploadOperation<BackendFile> | undefined,
278
+ > = {
279
+ upload?: TUpload;
280
+ };
281
+
282
+ export type ProviderMultipartUploads = {
283
+ requestParts: (
284
+ params: RequestUploadPartsParams,
285
+ ) => MaybePromise<RequestUploadPartsRes>;
286
+ complete: (params: CompleteMultipartUploadParams) => MaybePromise<void>;
287
+ };
288
+
289
+ export type ProviderUploads<
290
+ TUpload extends BackendUploadOperation<BackendFile> | undefined =
291
+ BackendUploadOperation<BackendFile> | undefined,
292
+ > =
293
+ | (ProviderUploadBase<TUpload> & {
294
+ request: (
295
+ params: RequestUploadParams,
296
+ ) => MaybePromise<SinglePartRequestUploadRes>;
297
+ multipart?: never;
298
+ })
299
+ | (ProviderUploadBase<TUpload> & {
300
+ request: (params: RequestUploadParams) => MaybePromise<RequestUploadRes>;
301
+ multipart: ProviderMultipartUploads;
302
+ });
303
+
304
+ export type ProviderFiles<
305
+ TFileReference = FileReference,
306
+ TCursor = string,
307
+ TGet extends BackendGetFileOperation<BackendFile, TFileReference> =
308
+ BackendGetFileOperation<BackendFile, TFileReference>,
309
+ TList extends BackendListFilesOperation<BackendFile, TCursor> | undefined =
310
+ BackendListFilesOperation<BackendFile, TCursor> | undefined,
311
+ TConfirm extends
312
+ BackendFileMutationOperation<TFileReference, string> | undefined =
313
+ BackendFileMutationOperation<TFileReference, string> | undefined,
314
+ TDelete extends
315
+ BackendFileMutationOperation<TFileReference, string> | undefined =
316
+ BackendFileMutationOperation<TFileReference, string> | undefined,
317
+ TRestore extends
318
+ BackendFileMutationOperation<TFileReference, string> | undefined =
319
+ BackendFileMutationOperation<TFileReference, string> | undefined,
320
+ TGetSignedUrls extends
321
+ BackendGetSignedUrlsOperation<TFileReference> | undefined =
322
+ BackendGetSignedUrlsOperation<TFileReference> | undefined,
323
+ > = {
324
+ cursorSchema?: StandardSchemaV1<unknown, TCursor>;
325
+ get: TGet;
326
+ list?: TList;
327
+ confirm?: TConfirm;
328
+ delete?: TDelete;
329
+ restore?: TRestore;
330
+ getSignedUrls?: TGetSignedUrls;
331
+ };
332
+
333
+ export type EdgeStoreProvider<
334
+ TReferenceSchema extends StandardSchemaV1 = StandardSchemaV1<
335
+ unknown,
336
+ FileReference
337
+ >,
338
+ TCursor = string,
339
+ TUploads extends ProviderUploads = ProviderUploads,
340
+ TFiles extends ProviderFiles<
341
+ StandardSchemaV1.InferOutput<TReferenceSchema>,
342
+ TCursor
343
+ > = ProviderFiles<StandardSchemaV1.InferOutput<TReferenceSchema>, TCursor>,
344
+ > = {
345
+ name: string;
346
+ baseUrl: string | (() => MaybePromise<string>);
347
+ init: <TCtx extends AnyContext>(
348
+ params: InitParams<TCtx>,
349
+ ) => MaybePromise<InitRes>;
350
+ reference: ProviderReferenceDefinition<TReferenceSchema>;
351
+ uploads: TUploads;
352
+ files: TFiles;
353
+ };
354
+
355
+ export type AnyEdgeStoreProvider = EdgeStoreProvider<
356
+ StandardSchemaV1<any, any>,
357
+ any,
358
+ ProviderUploads,
359
+ ProviderFiles<any, any>
360
+ >;
361
+
362
+ declare const routerFileFieldsProviderBrand: unique symbol;
363
+
364
+ /**
365
+ * @internal Marks providers whose read contract persists the router-derived
366
+ * path and metadata fields.
367
+ */
368
+ export type RouterFileFieldsProvider = {
369
+ readonly [routerFileFieldsProviderBrand]: true;
370
+ };
371
+
372
+ export type DefaultEdgeStoreProvider = EdgeStoreProvider<
373
+ StandardSchemaV1<unknown, FileReference>,
374
+ string
375
+ > &
376
+ RouterFileFieldsProvider & {
377
+ uploads: ProviderUploads<BackendUploadOperation> & {
378
+ upload: BackendUploadOperation;
379
+ };
380
+ files: ProviderFiles<FileReference, string> & {
381
+ get: BackendGetFileOperation;
382
+ list: BackendListFilesOperation;
383
+ confirm: BackendFileMutationOperation;
384
+ delete: BackendFileMutationOperation;
385
+ restore: BackendFileMutationOperation;
386
+ getSignedUrls: BackendGetSignedUrlsOperation;
387
+ };
388
+ };
@@ -0,0 +1,38 @@
1
+ import { type Simplify } from '../types';
2
+ import { type AnyMetadata } from './bucketBuilder';
3
+ import {
4
+ type ClientInit,
5
+ type RequestUploadPartsRes,
6
+ type RequestUploadRes,
7
+ } from './providerTypes';
8
+
9
+ export type SharedInitRes = {
10
+ newCookies: string[];
11
+ baseUrl: string;
12
+ providerName: string;
13
+ clientInit?: ClientInit;
14
+ };
15
+ export type SharedRequestUploadRes = Simplify<
16
+ RequestUploadRes & {
17
+ size: number;
18
+ uploadedAt: string;
19
+ path: Record<string, string>;
20
+ pathOrder: string[];
21
+ metadata: AnyMetadata;
22
+ }
23
+ >;
24
+ export type SharedRequestUploadPartsRes = RequestUploadPartsRes;
25
+
26
+ export type SharedFileMutationRes = {
27
+ succeeded: string[];
28
+ failed: {
29
+ url: string;
30
+ error: {
31
+ code: string;
32
+ message: string;
33
+ };
34
+ }[];
35
+ };
36
+
37
+ export type SharedConfirmUploadsRes = SharedFileMutationRes;
38
+ export type SharedDeleteFilesRes = SharedFileMutationRes;
@@ -0,0 +1,52 @@
1
+ import { type MaybePromise } from '../types';
2
+
3
+ export type ClientUploadTransform = (params: {
4
+ file: File;
5
+ extension: string;
6
+ signal?: AbortSignal;
7
+ }) => MaybePromise<
8
+ | File
9
+ | Blob
10
+ | {
11
+ file: File | Blob;
12
+ extension: string;
13
+ }
14
+ >;
15
+
16
+ export type UploadOptions = {
17
+ /**
18
+ * e.g. 'my-file-name.jpg'
19
+ *
20
+ * By default, a unique file name will be generated for each upload.
21
+ * If you want to use a custom file name, you can use this option.
22
+ * If you use the same file name for multiple uploads, the previous file will be overwritten.
23
+ * But it might take some time for the CDN cache to be cleared.
24
+ * So maybe you will keep seeing the old file for a while.
25
+ *
26
+ * If you want to replace an existing file, immediately leave the `manualFileName` option empty and use the `replaceTargetUrl` option.
27
+ */
28
+ manualFileName?: string;
29
+ /**
30
+ * Use this to replace an existing file.
31
+ * It will automatically delete the existing file when the upload is complete.
32
+ */
33
+ replaceTargetUrl?: string;
34
+ /**
35
+ * If true, the file needs to be confirmed by using the `confirm` function.
36
+ * If the file is not confirmed within 24 hours, it will be deleted.
37
+ *
38
+ * This is useful for pages where the file is uploaded as soon as it is selected,
39
+ * but the user can leave the page without submitting the form.
40
+ *
41
+ * This avoids unnecessary zombie files in the bucket.
42
+ */
43
+ temporary?: boolean;
44
+ /**
45
+ * Transform the file before it is validated and uploaded.
46
+ *
47
+ * This can be used to compress images, convert formats, encrypt files, etc.
48
+ * The transformed file's size, MIME type, and extension will be used for the
49
+ * upload request.
50
+ */
51
+ transform?: ClientUploadTransform;
52
+ };