@edgestore/shared 0.7.0 → 1.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/errors/EdgeStoreError.d.ts +1 -1
- package/dist/errors/EdgeStoreError.d.ts.map +1 -1
- package/dist/errors/EdgeStoreError.js +4 -13
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +3 -8
- package/dist/index.d.ts +6 -6
- package/dist/index.js +3 -12
- package/dist/internals/bucketBuilder.d.ts +52 -19
- package/dist/internals/bucketBuilder.d.ts.map +1 -1
- package/dist/internals/bucketBuilder.js +47 -10
- package/dist/internals/createPathParamProxy.js +1 -3
- package/dist/internals/providerTypes.d.ts +29 -2
- package/dist/internals/providerTypes.d.ts.map +1 -1
- package/dist/internals/sharedFuncTypes.d.ts +4 -3
- package/dist/internals/sharedFuncTypes.d.ts.map +1 -1
- package/dist/internals/types.d.ts +17 -0
- package/dist/internals/types.d.ts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +15 -9
- package/src/errors/EdgeStoreError.ts +7 -8
- package/src/internals/bucketBuilder.ts +118 -25
- package/src/internals/providerTypes.ts +31 -0
- package/src/internals/sharedFuncTypes.ts +1 -0
- package/src/internals/types.ts +23 -0
- package/src/types.ts +4 -6
- package/dist/errors/EdgeStoreError.mjs +0 -49
- package/dist/errors/index.mjs +0 -23
- package/dist/index.mjs +0 -3
- package/dist/internals/bucketBuilder.mjs +0 -191
- package/dist/internals/createPathParamProxy.mjs +0 -29
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgestore/shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-next.0",
|
|
4
4
|
"description": "Upload files with ease from React/Next.js",
|
|
5
5
|
"homepage": "https://edgestore.dev",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"sideEffects": false,
|
|
8
|
+
"type": "module",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=24"
|
|
11
|
+
},
|
|
8
12
|
"repository": {
|
|
9
13
|
"type": "git",
|
|
10
14
|
"url": "https://github.com/edgestorejs/edgestore.git",
|
|
@@ -15,7 +19,6 @@
|
|
|
15
19
|
},
|
|
16
20
|
"author": "Ravi <me@ravi.com>",
|
|
17
21
|
"main": "dist/index.js",
|
|
18
|
-
"module": "dist/index.mjs",
|
|
19
22
|
"types": "dist/index.d.ts",
|
|
20
23
|
"keywords": [
|
|
21
24
|
"react",
|
|
@@ -31,8 +34,8 @@
|
|
|
31
34
|
"exports": {
|
|
32
35
|
"./package.json": "./package.json",
|
|
33
36
|
".": {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"import": "./dist/index.js",
|
|
36
39
|
"default": "./dist/index.js"
|
|
37
40
|
}
|
|
38
41
|
},
|
|
@@ -57,16 +60,19 @@
|
|
|
57
60
|
},
|
|
58
61
|
"devDependencies": {
|
|
59
62
|
"@types/node": "25.0.3",
|
|
60
|
-
"react": "19.2.
|
|
61
|
-
"react-dom": "19.2.
|
|
62
|
-
"
|
|
63
|
-
"
|
|
63
|
+
"react": "19.2.7",
|
|
64
|
+
"react-dom": "19.2.7",
|
|
65
|
+
"tsx": "4.23.1",
|
|
66
|
+
"typescript": "6.0.3",
|
|
67
|
+
"zod": "3.25.76"
|
|
64
68
|
},
|
|
65
69
|
"gitHead": "a223c4cb8df50e6b64f9db5dc2daf93848748da9",
|
|
66
70
|
"scripts": {
|
|
67
71
|
"build": "rollup --config rollup.config.ts --configPlugin rollup-plugin-swc3",
|
|
68
72
|
"dev": "pnpm build --watch",
|
|
69
73
|
"codegen:entrypoints": "tsx entrypoints.script.ts",
|
|
70
|
-
"
|
|
74
|
+
"test": "vitest run",
|
|
75
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
76
|
+
"lint": "eslint --cache --report-unused-disable-directives src"
|
|
71
77
|
}
|
|
72
78
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type Simplify } from '../types';
|
|
2
2
|
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
4
3
|
export const EDGE_STORE_ERROR_CODES = {
|
|
5
4
|
BAD_REQUEST: 400,
|
|
6
5
|
FILE_TOO_LARGE: 400,
|
|
@@ -21,11 +20,11 @@ export type EdgeStoreErrorDetails<TCode extends EdgeStoreErrorCodeKey> =
|
|
|
21
20
|
fileSize: number;
|
|
22
21
|
}
|
|
23
22
|
: TCode extends 'MIME_TYPE_NOT_ALLOWED'
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
? {
|
|
24
|
+
allowedMimeTypes: string[];
|
|
25
|
+
mimeType: string;
|
|
26
|
+
}
|
|
27
|
+
: never;
|
|
29
28
|
|
|
30
29
|
export type EdgeStoreJsonResponse = Simplify<
|
|
31
30
|
| {
|
|
@@ -84,7 +83,7 @@ export class EdgeStoreError<TCode extends EdgeStoreErrorCodeKey> extends Error {
|
|
|
84
83
|
message:
|
|
85
84
|
this.code === 'SERVER_ERROR' ? 'Internal server error' : this.message,
|
|
86
85
|
code: this.code,
|
|
87
|
-
details: this.details
|
|
88
|
-
}
|
|
86
|
+
details: this.details,
|
|
87
|
+
} as EdgeStoreJsonResponse;
|
|
89
88
|
}
|
|
90
89
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { EdgeStoreError } from '../errors';
|
|
2
3
|
import { type KeysOfUnion, type MaybePromise, type Simplify } from '../types';
|
|
3
4
|
import { createPathParamProxy } from './createPathParamProxy';
|
|
4
5
|
|
|
@@ -36,6 +37,11 @@ export type InferBucketPathObject<TBucket extends Builder<any, AnyDef>> =
|
|
|
36
37
|
[TKey in InferBucketPathKeys<TBucket>]: string;
|
|
37
38
|
};
|
|
38
39
|
|
|
40
|
+
export type InferBucketPathOrder<TBucket extends Builder<any, AnyDef>> =
|
|
41
|
+
InferBucketPathKeys<TBucket> extends never
|
|
42
|
+
? []
|
|
43
|
+
: InferBucketPathKeys<TBucket>[];
|
|
44
|
+
|
|
39
45
|
export type InferBucketPathObjectFromDef<TDef extends AnyDef> =
|
|
40
46
|
InferBucketPathKeysFromDef<TDef> extends never
|
|
41
47
|
? Record<string, never>
|
|
@@ -53,7 +59,11 @@ type InferMetadataObjectFromDef<TDef extends AnyDef> =
|
|
|
53
59
|
? Awaited<ReturnType<TDef['metadata']>>
|
|
54
60
|
: Record<string, never>;
|
|
55
61
|
|
|
56
|
-
export type
|
|
62
|
+
export type AnyContextValue = string | undefined | null | AnyContext;
|
|
63
|
+
|
|
64
|
+
export interface AnyContext {
|
|
65
|
+
[key: string]: AnyContextValue;
|
|
66
|
+
}
|
|
57
67
|
|
|
58
68
|
export type AnyInput = z.AnyZodObject | z.ZodNever;
|
|
59
69
|
|
|
@@ -77,9 +87,7 @@ type Conditions<TPath extends AnyPath> = {
|
|
|
77
87
|
export type AccessControlSchema<TCtx, TDef extends AnyDef> = Merge<
|
|
78
88
|
{
|
|
79
89
|
[TKey in keyof TCtx]?:
|
|
80
|
-
|
|
|
81
|
-
| PathParam<TDef['path']>
|
|
82
|
-
| Conditions<TDef['path']>;
|
|
90
|
+
string | PathParam<TDef['path']> | Conditions<TDef['path']>;
|
|
83
91
|
},
|
|
84
92
|
{
|
|
85
93
|
OR?: AccessControlSchema<TCtx, TDef>[];
|
|
@@ -88,6 +96,14 @@ export type AccessControlSchema<TCtx, TDef extends AnyDef> = Merge<
|
|
|
88
96
|
}
|
|
89
97
|
>;
|
|
90
98
|
|
|
99
|
+
export type AccessControl<TCtx, TDef extends AnyDef> =
|
|
100
|
+
'private' | AccessControlSchema<TCtx, TDef>;
|
|
101
|
+
|
|
102
|
+
export type AutoSignedUrlsConfig = {
|
|
103
|
+
expiresIn?: number;
|
|
104
|
+
includeThumbnails?: boolean;
|
|
105
|
+
};
|
|
106
|
+
|
|
91
107
|
type BucketConfig = {
|
|
92
108
|
/**
|
|
93
109
|
* Maximum size for a single file in bytes
|
|
@@ -107,19 +123,17 @@ type BucketConfig = {
|
|
|
107
123
|
accept?: string[];
|
|
108
124
|
};
|
|
109
125
|
|
|
110
|
-
type FileInfo = {
|
|
111
|
-
size: number;
|
|
112
|
-
type: string;
|
|
113
|
-
extension: string;
|
|
114
|
-
fileName?: string;
|
|
115
|
-
replaceTargetUrl?: string;
|
|
116
|
-
temporary: boolean;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
126
|
type BeforeUploadFn<TCtx, TDef extends AnyDef> = (params: {
|
|
120
127
|
ctx: TCtx;
|
|
121
128
|
input: z.infer<TDef['input']>;
|
|
122
|
-
fileInfo:
|
|
129
|
+
fileInfo: {
|
|
130
|
+
size: number;
|
|
131
|
+
type: string;
|
|
132
|
+
extension: string;
|
|
133
|
+
fileName?: string;
|
|
134
|
+
replaceTargetUrl?: string;
|
|
135
|
+
temporary: boolean;
|
|
136
|
+
};
|
|
123
137
|
}) => MaybePromise<boolean>;
|
|
124
138
|
|
|
125
139
|
type BeforeDeleteFn<TCtx, TDef extends AnyDef> = (params: {
|
|
@@ -155,7 +169,8 @@ type Def<
|
|
|
155
169
|
path: TPath;
|
|
156
170
|
metadata: TMetadata;
|
|
157
171
|
bucketConfig?: BucketConfig;
|
|
158
|
-
accessControl?:
|
|
172
|
+
accessControl?: AccessControl<any, any>;
|
|
173
|
+
autoSignedUrls?: AutoSignedUrlsConfig;
|
|
159
174
|
beforeUpload?: BeforeUploadFn<any, any>;
|
|
160
175
|
beforeDelete?: BeforeDeleteFn<any, any>;
|
|
161
176
|
};
|
|
@@ -187,6 +202,7 @@ type Builder<TCtx, TDef extends AnyDef> = {
|
|
|
187
202
|
metadata: TDef['metadata'];
|
|
188
203
|
bucketConfig: TDef['bucketConfig'];
|
|
189
204
|
accessControl: TDef['accessControl'];
|
|
205
|
+
autoSignedUrls: TDef['autoSignedUrls'];
|
|
190
206
|
beforeUpload: TDef['beforeUpload'];
|
|
191
207
|
beforeDelete: TDef['beforeDelete'];
|
|
192
208
|
}
|
|
@@ -217,6 +233,7 @@ type Builder<TCtx, TDef extends AnyDef> = {
|
|
|
217
233
|
metadata: TDef['metadata'];
|
|
218
234
|
bucketConfig: TDef['bucketConfig'];
|
|
219
235
|
accessControl: TDef['accessControl'];
|
|
236
|
+
autoSignedUrls: TDef['autoSignedUrls'];
|
|
220
237
|
beforeUpload: TDef['beforeUpload'];
|
|
221
238
|
beforeDelete: TDef['beforeDelete'];
|
|
222
239
|
}
|
|
@@ -237,6 +254,7 @@ type Builder<TCtx, TDef extends AnyDef> = {
|
|
|
237
254
|
metadata: MetadataFn<any, any, TMetadata>;
|
|
238
255
|
bucketConfig: TDef['bucketConfig'];
|
|
239
256
|
accessControl: TDef['accessControl'];
|
|
257
|
+
autoSignedUrls: TDef['autoSignedUrls'];
|
|
240
258
|
beforeUpload: TDef['beforeUpload'];
|
|
241
259
|
beforeDelete: TDef['beforeDelete'];
|
|
242
260
|
}
|
|
@@ -247,7 +265,26 @@ type Builder<TCtx, TDef extends AnyDef> = {
|
|
|
247
265
|
* This means that images will only be accessible from within your app.
|
|
248
266
|
* And only if it passes the check set in this function.
|
|
249
267
|
*/
|
|
250
|
-
accessControl(accessControl:
|
|
268
|
+
accessControl(accessControl: AccessControl<TCtx, TDef>): Builder<
|
|
269
|
+
TCtx,
|
|
270
|
+
{
|
|
271
|
+
type: TDef['type'];
|
|
272
|
+
input: TDef['input'];
|
|
273
|
+
path: TDef['path'];
|
|
274
|
+
metadata: TDef['metadata'];
|
|
275
|
+
bucketConfig: TDef['bucketConfig'];
|
|
276
|
+
accessControl: AccessControl<any, any>;
|
|
277
|
+
autoSignedUrls: TDef['autoSignedUrls'];
|
|
278
|
+
beforeUpload: TDef['beforeUpload'];
|
|
279
|
+
beforeDelete: TDef['beforeDelete'];
|
|
280
|
+
}
|
|
281
|
+
>;
|
|
282
|
+
/**
|
|
283
|
+
* Automatically return temporary signed read URLs after uploads.
|
|
284
|
+
*
|
|
285
|
+
* This requires explicit non-public access control.
|
|
286
|
+
*/
|
|
287
|
+
autoSignedUrls(config?: AutoSignedUrlsConfig): Builder<
|
|
251
288
|
TCtx,
|
|
252
289
|
{
|
|
253
290
|
type: TDef['type'];
|
|
@@ -255,7 +292,8 @@ type Builder<TCtx, TDef extends AnyDef> = {
|
|
|
255
292
|
path: TDef['path'];
|
|
256
293
|
metadata: TDef['metadata'];
|
|
257
294
|
bucketConfig: TDef['bucketConfig'];
|
|
258
|
-
accessControl:
|
|
295
|
+
accessControl: TDef['accessControl'];
|
|
296
|
+
autoSignedUrls: AutoSignedUrlsConfig;
|
|
259
297
|
beforeUpload: TDef['beforeUpload'];
|
|
260
298
|
beforeDelete: TDef['beforeDelete'];
|
|
261
299
|
}
|
|
@@ -274,6 +312,7 @@ type Builder<TCtx, TDef extends AnyDef> = {
|
|
|
274
312
|
metadata: TDef['metadata'];
|
|
275
313
|
bucketConfig: TDef['bucketConfig'];
|
|
276
314
|
accessControl: TDef['accessControl'];
|
|
315
|
+
autoSignedUrls: TDef['autoSignedUrls'];
|
|
277
316
|
beforeUpload: BeforeUploadFn<any, any>;
|
|
278
317
|
beforeDelete: TDef['beforeDelete'];
|
|
279
318
|
}
|
|
@@ -292,6 +331,7 @@ type Builder<TCtx, TDef extends AnyDef> = {
|
|
|
292
331
|
metadata: TDef['metadata'];
|
|
293
332
|
bucketConfig: TDef['bucketConfig'];
|
|
294
333
|
accessControl: TDef['accessControl'];
|
|
334
|
+
autoSignedUrls: TDef['autoSignedUrls'];
|
|
295
335
|
beforeUpload: TDef['beforeUpload'];
|
|
296
336
|
beforeDelete: BeforeDeleteFn<any, any>;
|
|
297
337
|
}
|
|
@@ -330,7 +370,8 @@ function createBuilder<
|
|
|
330
370
|
path: TPath;
|
|
331
371
|
metadata: TMetadata;
|
|
332
372
|
bucketConfig?: BucketConfig;
|
|
333
|
-
accessControl?:
|
|
373
|
+
accessControl?: AccessControl<any, any>;
|
|
374
|
+
autoSignedUrls?: AutoSignedUrlsConfig;
|
|
334
375
|
beforeUpload?: BeforeUploadFn<any, any>;
|
|
335
376
|
beforeDelete?: BeforeDeleteFn<any, any>;
|
|
336
377
|
}
|
|
@@ -355,11 +396,31 @@ function createBuilder<
|
|
|
355
396
|
}) as any;
|
|
356
397
|
},
|
|
357
398
|
path(pathResolver) {
|
|
358
|
-
// TODO: Should throw a runtime error in the following cases:
|
|
359
|
-
// 1. in case of multiple keys in one object
|
|
360
|
-
// 2. in case of duplicate keys
|
|
361
399
|
const pathParamProxy = createPathParamProxy();
|
|
362
400
|
const params = pathResolver(pathParamProxy);
|
|
401
|
+
const pathKeys = new Set<string>();
|
|
402
|
+
for (const param of params) {
|
|
403
|
+
const entries = Object.entries(param);
|
|
404
|
+
if (entries.length !== 1) {
|
|
405
|
+
const foundKeys = entries.map(([key]) => key);
|
|
406
|
+
throw new EdgeStoreError({
|
|
407
|
+
message: `Path params must have exactly one key. Found keys: ${
|
|
408
|
+
foundKeys.length > 0 ? foundKeys.join(', ') : '(none)'
|
|
409
|
+
}`,
|
|
410
|
+
code: 'SERVER_ERROR',
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
const key = entries[0]?.[0];
|
|
414
|
+
if (key !== undefined && pathKeys.has(key)) {
|
|
415
|
+
throw new EdgeStoreError({
|
|
416
|
+
message: `Duplicate path param found: ${key}`,
|
|
417
|
+
code: 'SERVER_ERROR',
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (key !== undefined) {
|
|
421
|
+
pathKeys.add(key);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
363
424
|
return createNewBuilder(_def, {
|
|
364
425
|
path: params,
|
|
365
426
|
}) as any;
|
|
@@ -370,10 +431,36 @@ function createBuilder<
|
|
|
370
431
|
}) as any;
|
|
371
432
|
},
|
|
372
433
|
accessControl(accessControl) {
|
|
434
|
+
if (
|
|
435
|
+
typeof accessControl === 'object' &&
|
|
436
|
+
Object.keys(accessControl).length === 0
|
|
437
|
+
) {
|
|
438
|
+
throw new EdgeStoreError({
|
|
439
|
+
message:
|
|
440
|
+
'Empty accessControl objects are not allowed. Use accessControl("private") for signed-URL-only private files.',
|
|
441
|
+
code: 'SERVER_ERROR',
|
|
442
|
+
});
|
|
443
|
+
}
|
|
373
444
|
return createNewBuilder(_def, {
|
|
374
445
|
accessControl: accessControl,
|
|
375
446
|
}) as any;
|
|
376
447
|
},
|
|
448
|
+
autoSignedUrls(config) {
|
|
449
|
+
if (_def.accessControl === undefined) {
|
|
450
|
+
throw new EdgeStoreError({
|
|
451
|
+
message:
|
|
452
|
+
'autoSignedUrls requires a non-public bucket. Add accessControl("private") or an access-control schema first.',
|
|
453
|
+
code: 'SERVER_ERROR',
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
return createNewBuilder(_def, {
|
|
457
|
+
autoSignedUrls: {
|
|
458
|
+
expiresIn: config?.expiresIn,
|
|
459
|
+
includeThumbnails:
|
|
460
|
+
config?.includeThumbnails ?? (_def.type === 'IMAGE' ? true : false),
|
|
461
|
+
},
|
|
462
|
+
}) as any;
|
|
463
|
+
},
|
|
377
464
|
beforeUpload(beforeUpload) {
|
|
378
465
|
return createNewBuilder(_def, {
|
|
379
466
|
beforeUpload,
|
|
@@ -397,7 +484,13 @@ class EdgeStoreBuilder<TCtx = Record<string, never>> {
|
|
|
397
484
|
}
|
|
398
485
|
}
|
|
399
486
|
|
|
400
|
-
export type EdgeStoreRouter<
|
|
487
|
+
export type EdgeStoreRouter<
|
|
488
|
+
TCtx,
|
|
489
|
+
TBuckets extends Record<string, Builder<TCtx, AnyDef>> = Record<
|
|
490
|
+
string,
|
|
491
|
+
Builder<TCtx, AnyDef>
|
|
492
|
+
>,
|
|
493
|
+
> = {
|
|
401
494
|
/**
|
|
402
495
|
* Only used for types
|
|
403
496
|
* @internal
|
|
@@ -405,10 +498,10 @@ export type EdgeStoreRouter<TCtx> = {
|
|
|
405
498
|
$config: {
|
|
406
499
|
ctx: TCtx;
|
|
407
500
|
};
|
|
408
|
-
buckets:
|
|
501
|
+
buckets: TBuckets;
|
|
409
502
|
};
|
|
410
503
|
|
|
411
|
-
export type AnyRouter = EdgeStoreRouter<any
|
|
504
|
+
export type AnyRouter = EdgeStoreRouter<any, Record<string, AnyBuilder>>;
|
|
412
505
|
|
|
413
506
|
function createRouterFactory<TCtx>() {
|
|
414
507
|
return function createRouterInner<
|
|
@@ -419,7 +512,7 @@ function createRouterFactory<TCtx>() {
|
|
|
419
512
|
ctx: undefined as TCtx,
|
|
420
513
|
},
|
|
421
514
|
buckets,
|
|
422
|
-
} satisfies EdgeStoreRouter<TCtx>;
|
|
515
|
+
} satisfies EdgeStoreRouter<TCtx, TBuckets>;
|
|
423
516
|
};
|
|
424
517
|
}
|
|
425
518
|
|
|
@@ -50,6 +50,10 @@ export type RequestUploadParams = {
|
|
|
50
50
|
replaceTargetUrl?: string;
|
|
51
51
|
temporary: boolean;
|
|
52
52
|
};
|
|
53
|
+
autoSignedUrls?: {
|
|
54
|
+
expiresIn?: number;
|
|
55
|
+
includeThumbnails?: boolean;
|
|
56
|
+
};
|
|
53
57
|
};
|
|
54
58
|
|
|
55
59
|
export type RequestUploadPartsParams = {
|
|
@@ -88,6 +92,10 @@ export type RequestUploadRes =
|
|
|
88
92
|
uploadUrl: string;
|
|
89
93
|
accessUrl: string;
|
|
90
94
|
thumbnailUrl?: string | null;
|
|
95
|
+
accessSignedUrl?: string;
|
|
96
|
+
accessSignedThumbnailUrl?: string | null;
|
|
97
|
+
accessSignedUrlExpiresAt?: Date | string;
|
|
98
|
+
accessSignedUrlExpiresIn?: number;
|
|
91
99
|
}
|
|
92
100
|
| {
|
|
93
101
|
multipart: {
|
|
@@ -102,8 +110,28 @@ export type RequestUploadRes =
|
|
|
102
110
|
};
|
|
103
111
|
accessUrl: string;
|
|
104
112
|
thumbnailUrl?: string | null;
|
|
113
|
+
accessSignedUrl?: string;
|
|
114
|
+
accessSignedThumbnailUrl?: string | null;
|
|
115
|
+
accessSignedUrlExpiresAt?: Date | string;
|
|
116
|
+
accessSignedUrlExpiresIn?: number;
|
|
105
117
|
};
|
|
106
118
|
|
|
119
|
+
export type GetSignedUrlsParams = {
|
|
120
|
+
bucketName: string;
|
|
121
|
+
urls: string[];
|
|
122
|
+
expiresIn?: number;
|
|
123
|
+
includeThumbnails?: boolean;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export type GetSignedUrlRes = {
|
|
127
|
+
url: string;
|
|
128
|
+
signedUrl: string;
|
|
129
|
+
expiresAt: Date;
|
|
130
|
+
expiresIn: number;
|
|
131
|
+
thumbnailUrl?: string | null;
|
|
132
|
+
signedThumbnailUrl?: string | null;
|
|
133
|
+
};
|
|
134
|
+
|
|
107
135
|
export type ConfirmUpload = {
|
|
108
136
|
bucket: AnyBuilder;
|
|
109
137
|
url: string;
|
|
@@ -133,6 +161,9 @@ export type Provider = {
|
|
|
133
161
|
requestUploadParts: (
|
|
134
162
|
params: RequestUploadPartsParams,
|
|
135
163
|
) => MaybePromise<RequestUploadPartsRes>;
|
|
164
|
+
getSignedUrls?: (
|
|
165
|
+
params: GetSignedUrlsParams,
|
|
166
|
+
) => MaybePromise<GetSignedUrlRes[]>;
|
|
136
167
|
completeMultipartUpload: (
|
|
137
168
|
params: CompleteMultipartUploadParams,
|
|
138
169
|
) => MaybePromise<CompleteMultipartUploadRes>;
|
package/src/internals/types.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
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
|
+
|
|
1
16
|
export type UploadOptions = {
|
|
2
17
|
/**
|
|
3
18
|
* e.g. 'my-file-name.jpg'
|
|
@@ -26,4 +41,12 @@ export type UploadOptions = {
|
|
|
26
41
|
* This avoids unnecessary zombie files in the bucket.
|
|
27
42
|
*/
|
|
28
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;
|
|
29
52
|
};
|
package/src/types.ts
CHANGED
|
@@ -21,8 +21,8 @@ export type FlatOverwrite<TType, TWith> = InferOptional<
|
|
|
21
21
|
[TKey in keyof TType | keyof TWith]: TKey extends keyof TWith
|
|
22
22
|
? TWith[TKey]
|
|
23
23
|
: TKey extends keyof TType
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
? TType[TKey]
|
|
25
|
+
: never;
|
|
26
26
|
},
|
|
27
27
|
UndefinedKeys<TType> | UndefinedKeys<TWith>
|
|
28
28
|
>;
|
|
@@ -49,9 +49,8 @@ export type Maybe<TType> = TType | null | undefined;
|
|
|
49
49
|
/**
|
|
50
50
|
* @internal
|
|
51
51
|
*/
|
|
52
|
-
export type ThenArg<TType> =
|
|
53
|
-
? ThenArg<U>
|
|
54
|
-
: TType;
|
|
52
|
+
export type ThenArg<TType> =
|
|
53
|
+
TType extends PromiseLike<infer U> ? ThenArg<U> : TType;
|
|
55
54
|
|
|
56
55
|
/**
|
|
57
56
|
* @internal
|
|
@@ -66,7 +65,6 @@ export type Simplify<TType> = TType extends any[] | Date
|
|
|
66
65
|
*/
|
|
67
66
|
export type Prettify<TType> = {
|
|
68
67
|
[K in keyof TType]: TType[K];
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
70
68
|
} & {};
|
|
71
69
|
|
|
72
70
|
/**
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
function _define_property(obj, key, value) {
|
|
2
|
-
if (key in obj) {
|
|
3
|
-
Object.defineProperty(obj, key, {
|
|
4
|
-
value: value,
|
|
5
|
-
enumerable: true,
|
|
6
|
-
configurable: true,
|
|
7
|
-
writable: true
|
|
8
|
-
});
|
|
9
|
-
} else {
|
|
10
|
-
obj[key] = value;
|
|
11
|
-
}
|
|
12
|
-
return obj;
|
|
13
|
-
}
|
|
14
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */ const EDGE_STORE_ERROR_CODES = {
|
|
15
|
-
BAD_REQUEST: 400,
|
|
16
|
-
FILE_TOO_LARGE: 400,
|
|
17
|
-
MIME_TYPE_NOT_ALLOWED: 400,
|
|
18
|
-
UNAUTHORIZED: 401,
|
|
19
|
-
UPLOAD_NOT_ALLOWED: 403,
|
|
20
|
-
DELETE_NOT_ALLOWED: 403,
|
|
21
|
-
CREATE_CONTEXT_ERROR: 500,
|
|
22
|
-
SERVER_ERROR: 500
|
|
23
|
-
};
|
|
24
|
-
class EdgeStoreError extends Error {
|
|
25
|
-
formattedMessage() {
|
|
26
|
-
return `${this.message}${this.details ? `\n Details: ${JSON.stringify(this.details)}` : ''}${this.cause ? `\n Caused by: ${this.cause.message}` : ''}`;
|
|
27
|
-
}
|
|
28
|
-
formattedJson() {
|
|
29
|
-
return {
|
|
30
|
-
message: this.code === 'SERVER_ERROR' ? 'Internal server error' : this.message,
|
|
31
|
-
code: this.code,
|
|
32
|
-
details: this.details
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
constructor(opts){
|
|
36
|
-
super(opts.message);
|
|
37
|
-
_define_property(this, "cause", void 0);
|
|
38
|
-
_define_property(this, "code", void 0);
|
|
39
|
-
_define_property(this, "level", void 0);
|
|
40
|
-
_define_property(this, "details", void 0);
|
|
41
|
-
this.name = 'EdgeStoreError';
|
|
42
|
-
this.code = opts.code;
|
|
43
|
-
this.cause = opts.cause;
|
|
44
|
-
this.level = EDGE_STORE_ERROR_CODES[opts.code] >= 500 ? 'error' : 'warn';
|
|
45
|
-
this.details = 'details' in opts ? opts.details : undefined;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export { EDGE_STORE_ERROR_CODES, EdgeStoreError };
|
package/dist/errors/index.mjs
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
function _define_property(obj, key, value) {
|
|
2
|
-
if (key in obj) {
|
|
3
|
-
Object.defineProperty(obj, key, {
|
|
4
|
-
value: value,
|
|
5
|
-
enumerable: true,
|
|
6
|
-
configurable: true,
|
|
7
|
-
writable: true
|
|
8
|
-
});
|
|
9
|
-
} else {
|
|
10
|
-
obj[key] = value;
|
|
11
|
-
}
|
|
12
|
-
return obj;
|
|
13
|
-
}
|
|
14
|
-
class EdgeStoreApiClientError extends Error {
|
|
15
|
-
constructor(opts){
|
|
16
|
-
super(opts.response.message);
|
|
17
|
-
_define_property(this, "data", void 0);
|
|
18
|
-
this.name = 'EdgeStoreApiClientError';
|
|
19
|
-
this.data = opts.response;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export { EdgeStoreApiClientError };
|
package/dist/index.mjs
DELETED