@edgestore/server 0.1.5-alpha.4 → 0.1.5-alpha.5
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/adapters/next/app/index.d.ts +5 -3
- package/dist/adapters/next/app/index.d.ts.map +1 -1
- package/dist/adapters/next/app/index.js +38 -15
- package/dist/adapters/next/app/index.mjs +37 -14
- package/dist/adapters/next/pages/index.d.ts +5 -3
- package/dist/adapters/next/pages/index.d.ts.map +1 -1
- package/dist/adapters/next/pages/index.js +32 -12
- package/dist/adapters/next/pages/index.mjs +31 -11
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/core/client/index.d.ts +56 -2
- package/dist/core/client/index.d.ts.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +13 -3
- package/dist/core/index.mjs +14 -5
- package/dist/core/sdk/index.d.ts.map +1 -1
- package/dist/{index-50ab9e08.js → index-7cb3a3f3.mjs} +41 -5
- package/dist/{index-f33a00fb.js → index-9eb6248c.js} +37 -2
- package/dist/{index-30a3741e.mjs → index-e25c8209.js} +48 -2
- package/dist/libs/errors/EdgeStoreApiClientError.d.ts +8 -0
- package/dist/libs/errors/EdgeStoreApiClientError.d.ts.map +1 -0
- package/dist/libs/errors/EdgeStoreError.d.ts +36 -4
- package/dist/libs/errors/EdgeStoreError.d.ts.map +1 -1
- package/dist/libs/logger.d.ts +13 -0
- package/dist/libs/logger.d.ts.map +1 -0
- package/dist/logger-0f08f252.mjs +40 -0
- package/dist/logger-623f2833.js +42 -0
- package/dist/logger-8f098618.js +33 -0
- package/dist/providers/edgestore/index.d.ts.map +1 -1
- package/dist/providers/edgestore/index.js +10 -3
- package/dist/providers/edgestore/index.mjs +10 -3
- package/dist/{shared-5d1e7f43.js → shared-53cb59dd.js} +72 -51
- package/dist/{shared-30b7a2ab.mjs → shared-b14a84ee.mjs} +65 -42
- package/dist/{shared-88655ba7.js → shared-f8ddbf7c.js} +62 -36
- package/package.json +2 -2
- package/src/adapters/next/app/index.ts +52 -19
- package/src/adapters/next/pages/index.ts +43 -14
- package/src/adapters/shared.ts +61 -29
- package/src/core/client/index.ts +57 -2
- package/src/core/index.ts +6 -0
- package/src/core/sdk/index.ts +7 -1
- package/src/libs/errors/EdgeStoreApiClientError.ts +14 -0
- package/src/libs/errors/EdgeStoreError.ts +76 -7
- package/src/libs/logger.ts +44 -0
- package/src/providers/edgestore/index.ts +9 -2
package/src/adapters/shared.ts
CHANGED
|
@@ -82,7 +82,10 @@ export async function requestUpload<TCtx>(params: {
|
|
|
82
82
|
const ctx = await getContext(ctxToken);
|
|
83
83
|
const bucket = router.buckets[bucketName];
|
|
84
84
|
if (!bucket) {
|
|
85
|
-
throw new
|
|
85
|
+
throw new EdgeStoreError({
|
|
86
|
+
message: `Bucket ${bucketName} not found`,
|
|
87
|
+
code: 'BAD_REQUEST',
|
|
88
|
+
});
|
|
86
89
|
}
|
|
87
90
|
if (bucket._def.beforeUpload) {
|
|
88
91
|
const canUpload = await bucket._def.beforeUpload?.({
|
|
@@ -98,15 +101,22 @@ export async function requestUpload<TCtx>(params: {
|
|
|
98
101
|
},
|
|
99
102
|
});
|
|
100
103
|
if (!canUpload) {
|
|
101
|
-
throw new
|
|
104
|
+
throw new EdgeStoreError({
|
|
105
|
+
message: 'Upload not allowed for the current context',
|
|
106
|
+
code: 'UPLOAD_NOT_ALLOWED',
|
|
107
|
+
});
|
|
102
108
|
}
|
|
103
109
|
}
|
|
104
110
|
|
|
105
111
|
if (bucket._def.type === 'IMAGE') {
|
|
106
112
|
if (!IMAGE_MIME_TYPES.includes(fileInfo.type)) {
|
|
107
113
|
throw new EdgeStoreError({
|
|
108
|
-
code: '
|
|
114
|
+
code: 'MIME_TYPE_NOT_ALLOWED',
|
|
109
115
|
message: 'Only images are allowed in this bucket',
|
|
116
|
+
details: {
|
|
117
|
+
allowedMimeTypes: IMAGE_MIME_TYPES,
|
|
118
|
+
mimeType: fileInfo.type,
|
|
119
|
+
},
|
|
110
120
|
});
|
|
111
121
|
}
|
|
112
122
|
}
|
|
@@ -114,8 +124,12 @@ export async function requestUpload<TCtx>(params: {
|
|
|
114
124
|
if (bucket._def.bucketConfig?.maxSize) {
|
|
115
125
|
if (fileInfo.size > bucket._def.bucketConfig.maxSize) {
|
|
116
126
|
throw new EdgeStoreError({
|
|
117
|
-
code: '
|
|
127
|
+
code: 'FILE_TOO_LARGE',
|
|
118
128
|
message: `File size is too big. Max size is ${bucket._def.bucketConfig.maxSize}`,
|
|
129
|
+
details: {
|
|
130
|
+
maxFileSize: bucket._def.bucketConfig.maxSize,
|
|
131
|
+
fileSize: fileInfo.size,
|
|
132
|
+
},
|
|
119
133
|
});
|
|
120
134
|
}
|
|
121
135
|
}
|
|
@@ -137,10 +151,14 @@ export async function requestUpload<TCtx>(params: {
|
|
|
137
151
|
}
|
|
138
152
|
if (!accepted) {
|
|
139
153
|
throw new EdgeStoreError({
|
|
140
|
-
code: '
|
|
154
|
+
code: 'MIME_TYPE_NOT_ALLOWED',
|
|
141
155
|
message: `"${
|
|
142
156
|
fileInfo.type
|
|
143
157
|
}" is not allowed. Accepted types are ${JSON.stringify(accept)}`,
|
|
158
|
+
details: {
|
|
159
|
+
allowedMimeTypes: accept,
|
|
160
|
+
mimeType: fileInfo.type,
|
|
161
|
+
},
|
|
144
162
|
});
|
|
145
163
|
}
|
|
146
164
|
}
|
|
@@ -190,7 +208,6 @@ export async function requestUploadParts<TCtx>(params: {
|
|
|
190
208
|
}) {
|
|
191
209
|
const {
|
|
192
210
|
provider,
|
|
193
|
-
router,
|
|
194
211
|
ctxToken,
|
|
195
212
|
body: { multipart, path },
|
|
196
213
|
} = params;
|
|
@@ -201,10 +218,6 @@ export async function requestUploadParts<TCtx>(params: {
|
|
|
201
218
|
});
|
|
202
219
|
}
|
|
203
220
|
await getContext(ctxToken); // just to check if the token is valid
|
|
204
|
-
const bucket = router.buckets[multipart.uploadId];
|
|
205
|
-
if (!bucket) {
|
|
206
|
-
throw new Error(`Bucket ${multipart.uploadId} not found`);
|
|
207
|
-
}
|
|
208
221
|
return await provider.requestUploadParts({
|
|
209
222
|
multipart,
|
|
210
223
|
path,
|
|
@@ -242,7 +255,10 @@ export async function completeMultipartUpload<TCtx>(params: {
|
|
|
242
255
|
await getContext(ctxToken); // just to check if the token is valid
|
|
243
256
|
const bucket = router.buckets[bucketName];
|
|
244
257
|
if (!bucket) {
|
|
245
|
-
throw new
|
|
258
|
+
throw new EdgeStoreError({
|
|
259
|
+
message: `Bucket ${bucketName} not found`,
|
|
260
|
+
code: 'BAD_REQUEST',
|
|
261
|
+
});
|
|
246
262
|
}
|
|
247
263
|
return await provider.completeMultipartUpload({
|
|
248
264
|
uploadId,
|
|
@@ -278,7 +294,10 @@ export async function confirmUpload<TCtx>(params: {
|
|
|
278
294
|
await getContext(ctxToken); // just to check if the token is valid
|
|
279
295
|
const bucket = router.buckets[bucketName];
|
|
280
296
|
if (!bucket) {
|
|
281
|
-
throw new
|
|
297
|
+
throw new EdgeStoreError({
|
|
298
|
+
message: `Bucket ${bucketName} not found`,
|
|
299
|
+
code: 'BAD_REQUEST',
|
|
300
|
+
});
|
|
282
301
|
}
|
|
283
302
|
|
|
284
303
|
return await provider.confirmUpload({
|
|
@@ -314,13 +333,18 @@ export async function deleteFile<TCtx>(params: {
|
|
|
314
333
|
const ctx = await getContext(ctxToken);
|
|
315
334
|
const bucket = router.buckets[bucketName];
|
|
316
335
|
if (!bucket) {
|
|
317
|
-
throw new
|
|
336
|
+
throw new EdgeStoreError({
|
|
337
|
+
message: `Bucket ${bucketName} not found`,
|
|
338
|
+
code: 'BAD_REQUEST',
|
|
339
|
+
});
|
|
318
340
|
}
|
|
319
341
|
|
|
320
342
|
if (!bucket._def.beforeDelete) {
|
|
321
|
-
throw new
|
|
322
|
-
|
|
323
|
-
|
|
343
|
+
throw new EdgeStoreError({
|
|
344
|
+
message:
|
|
345
|
+
'You need to define beforeDelete if you want to delete files directly from the frontend.',
|
|
346
|
+
code: 'SERVER_ERROR',
|
|
347
|
+
});
|
|
324
348
|
}
|
|
325
349
|
|
|
326
350
|
const fileInfo = await provider.getFile({
|
|
@@ -332,7 +356,10 @@ export async function deleteFile<TCtx>(params: {
|
|
|
332
356
|
fileInfo,
|
|
333
357
|
});
|
|
334
358
|
if (!canDelete) {
|
|
335
|
-
throw new
|
|
359
|
+
throw new EdgeStoreError({
|
|
360
|
+
message: 'Delete not allowed for the current context',
|
|
361
|
+
code: 'DELETE_NOT_ALLOWED',
|
|
362
|
+
});
|
|
336
363
|
}
|
|
337
364
|
return await provider.deleteFile({
|
|
338
365
|
bucket,
|
|
@@ -344,9 +371,10 @@ async function encryptJWT(ctx: any) {
|
|
|
344
371
|
const secret =
|
|
345
372
|
process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
|
|
346
373
|
if (!secret) {
|
|
347
|
-
throw new
|
|
348
|
-
'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
|
|
349
|
-
|
|
374
|
+
throw new EdgeStoreError({
|
|
375
|
+
message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
|
|
376
|
+
code: 'SERVER_ERROR',
|
|
377
|
+
});
|
|
350
378
|
}
|
|
351
379
|
const encryptionSecret = await getDerivedEncryptionKey(secret);
|
|
352
380
|
return await new EncryptJWT(ctx)
|
|
@@ -361,9 +389,10 @@ async function decryptJWT(token: string) {
|
|
|
361
389
|
const secret =
|
|
362
390
|
process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
|
|
363
391
|
if (!secret) {
|
|
364
|
-
throw new
|
|
365
|
-
'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not
|
|
366
|
-
|
|
392
|
+
throw new EdgeStoreError({
|
|
393
|
+
message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
|
|
394
|
+
code: 'SERVER_ERROR',
|
|
395
|
+
});
|
|
367
396
|
}
|
|
368
397
|
const encryptionSecret = await getDerivedEncryptionKey(secret);
|
|
369
398
|
const { payload } = await jwtDecrypt(token, encryptionSecret, {
|
|
@@ -395,7 +424,10 @@ export function buildPath(params: {
|
|
|
395
424
|
const path = pathParams.map((param) => {
|
|
396
425
|
const paramEntries = Object.entries(param);
|
|
397
426
|
if (paramEntries[0] === undefined) {
|
|
398
|
-
throw new
|
|
427
|
+
throw new EdgeStoreError({
|
|
428
|
+
message: `Empty path param found in: ${JSON.stringify(pathParams)}`,
|
|
429
|
+
code: 'SERVER_ERROR',
|
|
430
|
+
});
|
|
399
431
|
}
|
|
400
432
|
const [key, value] = paramEntries[0];
|
|
401
433
|
// this is a string like: "ctx.xxx" or "input.yyy.zzz"
|
|
@@ -403,7 +435,10 @@ export function buildPath(params: {
|
|
|
403
435
|
.split('.')
|
|
404
436
|
.reduce((acc2: any, key: string) => {
|
|
405
437
|
if (acc2[key] === undefined) {
|
|
406
|
-
throw new
|
|
438
|
+
throw new EdgeStoreError({
|
|
439
|
+
message: `Missing key ${key} in ${JSON.stringify(acc2)}`,
|
|
440
|
+
code: 'BAD_REQUEST',
|
|
441
|
+
});
|
|
407
442
|
}
|
|
408
443
|
return acc2[key];
|
|
409
444
|
}, params.pathAttrs as any) as string;
|
|
@@ -427,10 +462,7 @@ export function parsePath(path: { key: string; value: string }[]) {
|
|
|
427
462
|
};
|
|
428
463
|
}
|
|
429
464
|
|
|
430
|
-
async function getContext(token
|
|
431
|
-
if (!token) {
|
|
432
|
-
throw new Error('No token');
|
|
433
|
-
}
|
|
465
|
+
async function getContext(token: string) {
|
|
434
466
|
return await decryptJWT(token);
|
|
435
467
|
}
|
|
436
468
|
|
package/src/core/client/index.ts
CHANGED
|
@@ -50,6 +50,26 @@ export type UploadOptions = {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export type UploadFileRequest<TBucket extends AnyBuilder> = {
|
|
53
|
+
/**
|
|
54
|
+
* Can be a string or a blob.
|
|
55
|
+
*
|
|
56
|
+
* If it's a string, it will be converted to a blob with the type `text/plain`.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* // string
|
|
61
|
+
* content: "some text"
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* // blob
|
|
67
|
+
* content: {
|
|
68
|
+
* blob: new Blob([text], { type: "text/csv" }),
|
|
69
|
+
* extension: "csv",
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
53
73
|
content:
|
|
54
74
|
| string
|
|
55
75
|
| {
|
|
@@ -125,15 +145,50 @@ type EdgeStoreClient<TRouter extends AnyRouter> = {
|
|
|
125
145
|
getFile: (params: {
|
|
126
146
|
url: string;
|
|
127
147
|
}) => Promise<GetFileRes<TRouter['buckets'][K]>>;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Use this function to upload a file to the bucket directly from your backend.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* // simple example
|
|
155
|
+
* await backendClient.myBucket.upload({
|
|
156
|
+
* content: "some text",
|
|
157
|
+
* });
|
|
158
|
+
* ```
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* // complete example
|
|
163
|
+
* await backendClient.myBucket.upload({
|
|
164
|
+
* content: {
|
|
165
|
+
* blob: new Blob([text], { type: "text/csv" }),
|
|
166
|
+
* extension: "csv",
|
|
167
|
+
* },
|
|
168
|
+
* options: {
|
|
169
|
+
* temporary: true,
|
|
170
|
+
* replaceTargetUrl: replaceUrl,
|
|
171
|
+
* manualFileName: "test.csv",
|
|
172
|
+
* },
|
|
173
|
+
* ctx: {
|
|
174
|
+
* userId: "123",
|
|
175
|
+
* userRole: "admin",
|
|
176
|
+
* },
|
|
177
|
+
* input: {
|
|
178
|
+
* type: "post",
|
|
179
|
+
* },
|
|
180
|
+
* });
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
128
183
|
upload: (
|
|
129
184
|
params: UploadFileRequest<TRouter['buckets'][K]>,
|
|
130
185
|
) => Promise<Prettify<UploadFileRes<TRouter['buckets'][K]>>>;
|
|
131
186
|
/**
|
|
132
|
-
* Confirm a temporary file upload.
|
|
187
|
+
* Confirm a temporary file upload directly from your backend.
|
|
133
188
|
*/
|
|
134
189
|
confirmUpload: (params: { url: string }) => Promise<{ success: boolean }>;
|
|
135
190
|
/**
|
|
136
|
-
* Programmatically delete a file.
|
|
191
|
+
* Programmatically delete a file directly from your backend.
|
|
137
192
|
*/
|
|
138
193
|
deleteFile: (params: { url: string }) => Promise<{
|
|
139
194
|
success: boolean;
|
package/src/core/index.ts
CHANGED
|
@@ -7,5 +7,11 @@ export type {
|
|
|
7
7
|
InferBucketPathObject,
|
|
8
8
|
InferMetadataObject,
|
|
9
9
|
} from './internals/bucketBuilder';
|
|
10
|
+
export type {
|
|
11
|
+
EdgeStoreErrorCodeKey,
|
|
12
|
+
EdgeStoreErrorDetails,
|
|
13
|
+
EdgeStoreJsonResponse,
|
|
14
|
+
} from '../libs/errors/EdgeStoreError';
|
|
15
|
+
export { EdgeStoreApiClientError } from '../libs/errors/EdgeStoreApiClientError';
|
|
10
16
|
|
|
11
17
|
export type AnyRouter = EdgeStoreRouter<any>;
|
package/src/core/sdk/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type AnyRouter } from '..';
|
|
2
2
|
import EdgeStoreCredentialsError from '../../libs/errors/EdgeStoreCredentialsError';
|
|
3
|
+
import EdgeStoreError from '../../libs/errors/EdgeStoreError';
|
|
3
4
|
import { type AnyContext, type AnyMetadata } from '../internals/bucketBuilder';
|
|
4
5
|
|
|
5
6
|
const API_ENDPOINT =
|
|
@@ -93,7 +94,12 @@ export const edgeStoreRawSdk = {
|
|
|
93
94
|
path: bucket._def.path.map((p: { [key: string]: () => string }) => {
|
|
94
95
|
const paramEntries = Object.entries(p);
|
|
95
96
|
if (paramEntries[0] === undefined) {
|
|
96
|
-
throw new
|
|
97
|
+
throw new EdgeStoreError({
|
|
98
|
+
message: `Empty path param found in: ${JSON.stringify(
|
|
99
|
+
bucket._def.path,
|
|
100
|
+
)}`,
|
|
101
|
+
code: 'SERVER_ERROR',
|
|
102
|
+
});
|
|
97
103
|
}
|
|
98
104
|
const [key, value] = paramEntries[0];
|
|
99
105
|
return {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
|
|
3
|
+
import { type EdgeStoreJsonResponse } from './EdgeStoreError';
|
|
4
|
+
|
|
5
|
+
export class EdgeStoreApiClientError extends Error {
|
|
6
|
+
public readonly data: EdgeStoreJsonResponse;
|
|
7
|
+
|
|
8
|
+
constructor(opts: { response: EdgeStoreJsonResponse }) {
|
|
9
|
+
super(opts.response.message);
|
|
10
|
+
this.name = 'EdgeStoreApiClientError';
|
|
11
|
+
|
|
12
|
+
this.data = opts.response;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -1,24 +1,93 @@
|
|
|
1
|
+
import { type Simplify } from '../../types';
|
|
2
|
+
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
1
4
|
export const EDGE_STORE_ERROR_CODES = {
|
|
2
5
|
BAD_REQUEST: 400,
|
|
6
|
+
FILE_TOO_LARGE: 400,
|
|
7
|
+
MIME_TYPE_NOT_ALLOWED: 400,
|
|
3
8
|
UNAUTHORIZED: 401,
|
|
9
|
+
UPLOAD_NOT_ALLOWED: 403,
|
|
10
|
+
DELETE_NOT_ALLOWED: 403,
|
|
11
|
+
CREATE_CONTEXT_ERROR: 500,
|
|
12
|
+
SERVER_ERROR: 500,
|
|
4
13
|
} as const;
|
|
5
14
|
|
|
6
15
|
export type EdgeStoreErrorCodeKey = keyof typeof EDGE_STORE_ERROR_CODES;
|
|
7
16
|
|
|
8
|
-
|
|
17
|
+
export type EdgeStoreErrorDetails<TCode extends EdgeStoreErrorCodeKey> =
|
|
18
|
+
TCode extends 'FILE_TOO_LARGE'
|
|
19
|
+
? {
|
|
20
|
+
maxFileSize: number;
|
|
21
|
+
fileSize: number;
|
|
22
|
+
}
|
|
23
|
+
: TCode extends 'MIME_TYPE_NOT_ALLOWED'
|
|
24
|
+
? {
|
|
25
|
+
allowedMimeTypes: string[];
|
|
26
|
+
mimeType: string;
|
|
27
|
+
}
|
|
28
|
+
: never;
|
|
29
|
+
|
|
30
|
+
export type EdgeStoreJsonResponse = Simplify<
|
|
31
|
+
| {
|
|
32
|
+
message: string;
|
|
33
|
+
code: 'FILE_TOO_LARGE';
|
|
34
|
+
details: EdgeStoreErrorDetails<'FILE_TOO_LARGE'>;
|
|
35
|
+
}
|
|
36
|
+
| {
|
|
37
|
+
message: string;
|
|
38
|
+
code: 'MIME_TYPE_NOT_ALLOWED';
|
|
39
|
+
details: EdgeStoreErrorDetails<'MIME_TYPE_NOT_ALLOWED'>;
|
|
40
|
+
}
|
|
41
|
+
| {
|
|
42
|
+
message: string;
|
|
43
|
+
code: Exclude<
|
|
44
|
+
EdgeStoreErrorCodeKey,
|
|
45
|
+
'FILE_TOO_LARGE' | 'MIME_TYPE_NOT_ALLOWED'
|
|
46
|
+
>;
|
|
47
|
+
}
|
|
48
|
+
>;
|
|
49
|
+
|
|
50
|
+
class EdgeStoreError<TCode extends EdgeStoreErrorCodeKey> extends Error {
|
|
9
51
|
public readonly cause?: Error;
|
|
10
|
-
public readonly code:
|
|
52
|
+
public readonly code: TCode;
|
|
53
|
+
public readonly level: 'error' | 'warn';
|
|
54
|
+
public readonly details: EdgeStoreErrorDetails<TCode>;
|
|
11
55
|
|
|
12
|
-
constructor(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
56
|
+
constructor(
|
|
57
|
+
opts: {
|
|
58
|
+
message: string;
|
|
59
|
+
code: TCode;
|
|
60
|
+
cause?: Error;
|
|
61
|
+
} & (EdgeStoreErrorDetails<TCode> extends undefined
|
|
62
|
+
? object
|
|
63
|
+
: {
|
|
64
|
+
details: EdgeStoreErrorDetails<TCode>;
|
|
65
|
+
}),
|
|
66
|
+
) {
|
|
17
67
|
super(opts.message);
|
|
18
68
|
this.name = 'EdgeStoreError';
|
|
19
69
|
|
|
20
70
|
this.code = opts.code;
|
|
21
71
|
this.cause = opts.cause;
|
|
72
|
+
this.level = EDGE_STORE_ERROR_CODES[opts.code] >= 500 ? 'error' : 'warn';
|
|
73
|
+
this.details = 'details' in opts ? opts.details : undefined!;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
formattedMessage(): string {
|
|
77
|
+
return `EdgeStore${this.level === 'error' ? 'Error' : 'Info'}: ${
|
|
78
|
+
this.message
|
|
79
|
+
}${this.details ? `\n Details: ${JSON.stringify(this.details)}` : ''}${
|
|
80
|
+
this.cause ? `\n Caused by: ${this.cause.message}` : ''
|
|
81
|
+
}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
formattedJson(): EdgeStoreJsonResponse {
|
|
85
|
+
return {
|
|
86
|
+
message:
|
|
87
|
+
this.code === 'SERVER_ERROR' ? 'Internal server error' : this.message,
|
|
88
|
+
code: this.code,
|
|
89
|
+
details: this.details as any,
|
|
90
|
+
} satisfies EdgeStoreJsonResponse;
|
|
22
91
|
}
|
|
23
92
|
}
|
|
24
93
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
3
|
+
const logLevel = ['debug', 'info', 'warn', 'error', 'none'] as const;
|
|
4
|
+
|
|
5
|
+
export type LogLevel = typeof logLevel[number];
|
|
6
|
+
|
|
7
|
+
class Logger {
|
|
8
|
+
private logLevel: LogLevel;
|
|
9
|
+
|
|
10
|
+
constructor(logLevel?: LogLevel) {
|
|
11
|
+
this.logLevel =
|
|
12
|
+
logLevel ?? process.env.NODE_ENV === 'production' ? 'error' : 'info';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
private shouldLog(level: LogLevel): boolean {
|
|
16
|
+
return logLevel.indexOf(level) >= logLevel.indexOf(this.logLevel);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
debug(message?: any, ...optionalParams: any[]): void {
|
|
20
|
+
if (this.shouldLog('debug')) {
|
|
21
|
+
console.debug(message, ...optionalParams);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
info(message?: any, ...optionalParams: any[]): void {
|
|
26
|
+
if (this.shouldLog('info')) {
|
|
27
|
+
console.info(message, ...optionalParams);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
warn(message?: any, ...optionalParams: any[]): void {
|
|
32
|
+
if (this.shouldLog('warn')) {
|
|
33
|
+
console.warn(message, ...optionalParams);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
error(message?: any, ...optionalParams: any[]): void {
|
|
38
|
+
if (this.shouldLog('error')) {
|
|
39
|
+
console.error(message, ...optionalParams);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default Logger;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { initEdgeStoreSdk } from '../../core/sdk';
|
|
2
2
|
import EdgeStoreCredentialsError from '../../libs/errors/EdgeStoreCredentialsError';
|
|
3
|
+
import EdgeStoreError from '../../libs/errors/EdgeStoreError';
|
|
3
4
|
import { type Provider, type RequestUploadRes } from '../types';
|
|
4
5
|
|
|
5
6
|
const DEFAULT_BASE_URL = 'https://files.edgestore.dev';
|
|
@@ -111,7 +112,10 @@ export function EdgeStoreProvider(
|
|
|
111
112
|
thumbnailUrl: res.thumbnailUrl,
|
|
112
113
|
};
|
|
113
114
|
} else {
|
|
114
|
-
throw new
|
|
115
|
+
throw new EdgeStoreError({
|
|
116
|
+
message: 'Could not get upload url',
|
|
117
|
+
code: 'SERVER_ERROR',
|
|
118
|
+
});
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
const res = await edgeStoreSdk.requestUpload({
|
|
@@ -126,7 +130,10 @@ export function EdgeStoreProvider(
|
|
|
126
130
|
thumbnailUrl: res.thumbnailUrl,
|
|
127
131
|
};
|
|
128
132
|
}
|
|
129
|
-
throw new
|
|
133
|
+
throw new EdgeStoreError({
|
|
134
|
+
message: 'Could not get upload url',
|
|
135
|
+
code: 'SERVER_ERROR',
|
|
136
|
+
});
|
|
130
137
|
},
|
|
131
138
|
requestUploadParts: async ({ multipart, path }) => {
|
|
132
139
|
const res = await edgeStoreSdk.requestUploadParts({
|