@edgestore/server 0.1.5-alpha.0 → 0.1.5-alpha.10

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 (71) hide show
  1. package/adapters/express/index.d.ts +1 -0
  2. package/adapters/express/index.js +1 -0
  3. package/dist/adapters/express/index.d.ts +20 -0
  4. package/dist/adapters/express/index.d.ts.map +1 -0
  5. package/dist/adapters/express/index.js +117 -0
  6. package/dist/adapters/express/index.mjs +113 -0
  7. package/dist/adapters/next/app/index.d.ts +5 -3
  8. package/dist/adapters/next/app/index.d.ts.map +1 -1
  9. package/dist/adapters/next/app/index.js +45 -16
  10. package/dist/adapters/next/app/index.mjs +44 -15
  11. package/dist/adapters/next/pages/index.d.ts +5 -3
  12. package/dist/adapters/next/pages/index.d.ts.map +1 -1
  13. package/dist/adapters/next/pages/index.js +37 -13
  14. package/dist/adapters/next/pages/index.mjs +36 -12
  15. package/dist/adapters/shared.d.ts +19 -1
  16. package/dist/adapters/shared.d.ts.map +1 -1
  17. package/dist/core/client/index.d.ts +116 -4
  18. package/dist/core/client/index.d.ts.map +1 -1
  19. package/dist/core/index.d.ts +2 -0
  20. package/dist/core/index.d.ts.map +1 -1
  21. package/dist/core/index.js +109 -34
  22. package/dist/core/index.mjs +110 -36
  23. package/dist/core/sdk/index.d.ts.map +1 -1
  24. package/dist/{index-f33a00fb.js → index-0c401ce1.js} +38 -4
  25. package/dist/{index-50ab9e08.js → index-23d1ede9.mjs} +42 -7
  26. package/dist/{index-30a3741e.mjs → index-a2e7ca9e.js} +49 -4
  27. package/dist/libs/errors/EdgeStoreApiClientError.d.ts +8 -0
  28. package/dist/libs/errors/EdgeStoreApiClientError.d.ts.map +1 -0
  29. package/dist/libs/errors/EdgeStoreCredentialsError.d.ts.map +1 -1
  30. package/dist/libs/errors/EdgeStoreError.d.ts +36 -4
  31. package/dist/libs/errors/EdgeStoreError.d.ts.map +1 -1
  32. package/dist/libs/logger.d.ts +13 -0
  33. package/dist/libs/logger.d.ts.map +1 -0
  34. package/dist/logger-7ea2248c.mjs +40 -0
  35. package/dist/logger-b530a3e1.js +42 -0
  36. package/dist/logger-e0066db9.js +33 -0
  37. package/dist/providers/aws/index.js +1 -1
  38. package/dist/providers/aws/index.mjs +1 -1
  39. package/dist/providers/azure/index.d.ts +20 -0
  40. package/dist/providers/azure/index.d.ts.map +1 -0
  41. package/dist/providers/azure/index.js +61 -0
  42. package/dist/providers/azure/index.mjs +57 -0
  43. package/dist/providers/edgestore/index.d.ts.map +1 -1
  44. package/dist/providers/edgestore/index.js +10 -3
  45. package/dist/providers/edgestore/index.mjs +10 -3
  46. package/dist/providers/types.d.ts +1 -0
  47. package/dist/providers/types.d.ts.map +1 -1
  48. package/dist/{shared-306c1af2.js → shared-06cb0d86.js} +150 -61
  49. package/dist/{shared-9fad0d51.js → shared-d474acc6.js} +114 -46
  50. package/dist/{shared-6dea9e91.mjs → shared-d7ea66fb.mjs} +141 -52
  51. package/dist/types.d.ts +6 -0
  52. package/dist/types.d.ts.map +1 -1
  53. package/package.json +17 -2
  54. package/providers/azure/index.d.ts +1 -0
  55. package/providers/azure/index.js +1 -0
  56. package/src/adapters/express/index.ts +164 -0
  57. package/src/adapters/next/app/index.ts +63 -20
  58. package/src/adapters/next/pages/index.ts +52 -15
  59. package/src/adapters/shared.ts +142 -40
  60. package/src/core/client/index.ts +233 -51
  61. package/src/core/index.ts +6 -0
  62. package/src/core/sdk/index.ts +7 -1
  63. package/src/libs/errors/EdgeStoreApiClientError.ts +14 -0
  64. package/src/libs/errors/EdgeStoreCredentialsError.ts +1 -2
  65. package/src/libs/errors/EdgeStoreError.ts +74 -7
  66. package/src/libs/logger.ts +44 -0
  67. package/src/providers/aws/index.ts +1 -1
  68. package/src/providers/azure/index.ts +89 -0
  69. package/src/providers/edgestore/index.ts +9 -2
  70. package/src/providers/types.ts +1 -0
  71. package/src/types.ts +8 -0
@@ -2,7 +2,9 @@ import { type NextRequest } from 'next/server';
2
2
  import { type EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
3
3
  import EdgeStoreError, {
4
4
  EDGE_STORE_ERROR_CODES,
5
+ type EdgeStoreErrorCodeKey,
5
6
  } from '../../../libs/errors/EdgeStoreError';
7
+ import Logger, { type LogLevel } from '../../../libs/logger';
6
8
  import { EdgeStoreProvider } from '../../../providers/edgestore';
7
9
  import { type Provider } from '../../../providers/types';
8
10
  import { type MaybePromise } from '../../../types';
@@ -24,26 +26,54 @@ export type CreateContextOptions = {
24
26
  req: NextRequest;
25
27
  };
26
28
 
27
- export type Config<TCtx> = TCtx extends Record<string, never>
28
- ? {
29
- provider?: Provider;
30
- router: EdgeStoreRouter<TCtx>;
31
- }
29
+ export type Config<TCtx> = {
30
+ provider?: Provider;
31
+ router: EdgeStoreRouter<TCtx>;
32
+ logLevel?: LogLevel;
33
+ } & (TCtx extends Record<string, never>
34
+ ? object
32
35
  : {
33
36
  provider?: Provider;
34
37
  router: EdgeStoreRouter<TCtx>;
35
38
  createContext: (opts: CreateContextOptions) => MaybePromise<TCtx>;
36
- };
39
+ });
40
+
41
+ declare const globalThis: {
42
+ _EDGE_STORE_LOGGER: Logger;
43
+ };
37
44
 
38
45
  export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
39
46
  const { provider = EdgeStoreProvider() } = config;
47
+ const log = new Logger(config.logLevel);
48
+ globalThis._EDGE_STORE_LOGGER = log;
49
+ log.debug('Creating Edge Store Next handler (app adapter)');
50
+
40
51
  return async (req: NextRequest) => {
41
52
  try {
42
- if (req.nextUrl.pathname.endsWith('/init')) {
43
- const ctx =
44
- 'createContext' in config
45
- ? await config.createContext({ req })
46
- : ({} as TCtx);
53
+ if (!('nextUrl' in req))
54
+ throw new EdgeStoreError({
55
+ message:
56
+ 'Error running the app adapter. Make sure you are importing the correct adapter in your router configuration',
57
+ code: 'SERVER_ERROR',
58
+ });
59
+ if (req.nextUrl.pathname.endsWith('/health')) {
60
+ return new Response('OK', {
61
+ status: 200,
62
+ });
63
+ } else if (req.nextUrl.pathname.endsWith('/init')) {
64
+ let ctx = {} as TCtx;
65
+ try {
66
+ ctx =
67
+ 'createContext' in config
68
+ ? await config.createContext({ req })
69
+ : ({} as TCtx);
70
+ } catch (err) {
71
+ throw new EdgeStoreError({
72
+ message: 'Error creating context',
73
+ code: 'CREATE_CONTEXT_ERROR',
74
+ cause: err instanceof Error ? err : undefined,
75
+ });
76
+ }
47
77
  const { newCookies, token, baseUrl } = await init({
48
78
  ctx,
49
79
  provider,
@@ -157,17 +187,30 @@ export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
157
187
  }
158
188
  } catch (err) {
159
189
  if (err instanceof EdgeStoreError) {
160
- return new Response(err.message, {
161
- status: EDGE_STORE_ERROR_CODES[err.code],
162
- });
163
- } else if (err instanceof Error) {
164
- return new Response(err.message, {
165
- status: 500,
190
+ log[err.level](err.formattedMessage());
191
+ if (err.cause) log[err.level](err.cause);
192
+ return new Response(JSON.stringify(err.formattedJson()), {
193
+ status: EDGE_STORE_ERROR_CODES[err.code as EdgeStoreErrorCodeKey],
194
+ headers: {
195
+ 'Content-Type': 'application/json',
196
+ },
166
197
  });
167
198
  }
168
- return new Response('Internal server error', {
169
- status: 500,
170
- });
199
+ log.error(err);
200
+ return new Response(
201
+ JSON.stringify(
202
+ new EdgeStoreError({
203
+ message: 'Internal server error',
204
+ code: 'SERVER_ERROR',
205
+ }).formattedJson(),
206
+ ),
207
+ {
208
+ status: 500,
209
+ headers: {
210
+ 'Content-Type': 'application/json',
211
+ },
212
+ },
213
+ );
171
214
  }
172
215
  };
173
216
  }
@@ -2,7 +2,9 @@ import { type NextApiRequest, type NextApiResponse } from 'next/types';
2
2
  import { type EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
3
3
  import EdgeStoreError, {
4
4
  EDGE_STORE_ERROR_CODES,
5
+ type EdgeStoreErrorCodeKey,
5
6
  } from '../../../libs/errors/EdgeStoreError';
7
+ import Logger, { type LogLevel } from '../../../libs/logger';
6
8
  import { EdgeStoreProvider } from '../../../providers/edgestore';
7
9
  import { type Provider } from '../../../providers/types';
8
10
  import { type MaybePromise } from '../../../types';
@@ -25,26 +27,52 @@ export type CreateContextOptions = {
25
27
  res: NextApiResponse;
26
28
  };
27
29
 
28
- export type Config<TCtx> = TCtx extends Record<string, never>
29
- ? {
30
- provider?: Provider;
31
- router: EdgeStoreRouter<TCtx>;
32
- }
30
+ export type Config<TCtx> = {
31
+ provider?: Provider;
32
+ router: EdgeStoreRouter<TCtx>;
33
+ logLevel?: LogLevel;
34
+ } & (TCtx extends Record<string, never>
35
+ ? object
33
36
  : {
34
37
  provider?: Provider;
35
38
  router: EdgeStoreRouter<TCtx>;
36
39
  createContext: (opts: CreateContextOptions) => MaybePromise<TCtx>;
37
- };
40
+ });
41
+
42
+ declare const globalThis: {
43
+ _EDGE_STORE_LOGGER: Logger;
44
+ };
38
45
 
39
46
  export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
40
47
  const { provider = EdgeStoreProvider() } = config;
48
+ const log = new Logger(config.logLevel);
49
+ globalThis._EDGE_STORE_LOGGER = log;
50
+ log.debug('Creating Edge Store Next handler (pages adapter)');
51
+
41
52
  return async (req: NextApiRequest, res: NextApiResponse) => {
42
53
  try {
43
- if (req.url?.includes?.('/init')) {
44
- const ctx =
45
- 'createContext' in config
46
- ? await config.createContext({ req, res })
47
- : ({} as TCtx);
54
+ if (!('json' in res))
55
+ throw new EdgeStoreError({
56
+ message:
57
+ 'Error running the pages adapter. Make sure you are importing the correct adapter in your router configuration',
58
+ code: 'SERVER_ERROR',
59
+ });
60
+ if (req.url?.includes?.('/health')) {
61
+ res.send('OK');
62
+ } else if (req.url?.includes?.('/init')) {
63
+ let ctx = {} as TCtx;
64
+ try {
65
+ ctx =
66
+ 'createContext' in config
67
+ ? await config.createContext({ req, res })
68
+ : ({} as TCtx);
69
+ } catch (err) {
70
+ throw new EdgeStoreError({
71
+ message: 'Error creating context',
72
+ code: 'CREATE_CONTEXT_ERROR',
73
+ cause: err instanceof Error ? err : undefined,
74
+ });
75
+ }
48
76
  const { newCookies, token, baseUrl } = await init({
49
77
  ctx,
50
78
  provider,
@@ -123,11 +151,20 @@ export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
123
151
  }
124
152
  } catch (err) {
125
153
  if (err instanceof EdgeStoreError) {
126
- res.status(EDGE_STORE_ERROR_CODES[err.code]).send(err.message);
127
- } else if (err instanceof Error) {
128
- res.status(500).send(err.message);
154
+ log[err.level](err.formattedMessage());
155
+ if (err.cause) log[err.level](err.cause);
156
+ res
157
+ .status(EDGE_STORE_ERROR_CODES[err.code as EdgeStoreErrorCodeKey])
158
+ .json(err.formattedJson());
159
+ } else {
160
+ log.error(err);
161
+ res.status(500).send(
162
+ new EdgeStoreError({
163
+ message: 'Internal Server Error',
164
+ code: 'SERVER_ERROR',
165
+ }).formattedJson(),
166
+ );
129
167
  }
130
- res.status(500).send('Internal server error');
131
168
  }
132
169
  };
133
170
  }
@@ -7,18 +7,25 @@ import {
7
7
  type EdgeStoreRouter,
8
8
  } from '../core/internals/bucketBuilder';
9
9
  import EdgeStoreError from '../libs/errors/EdgeStoreError';
10
+ import type Logger from '../libs/logger';
10
11
  import { type Provider } from '../providers/types';
11
12
  import { IMAGE_MIME_TYPES } from './imageTypes';
12
13
 
13
14
  // TODO: change it to 1 hour when we have a way to refresh the token
14
15
  const DEFAULT_MAX_AGE = 30 * 24 * 60 * 60; // 30 days
15
16
 
17
+ declare const globalThis: {
18
+ _EDGE_STORE_LOGGER: Logger;
19
+ };
20
+
16
21
  export async function init<TCtx>(params: {
17
22
  provider: Provider;
18
23
  router: EdgeStoreRouter<TCtx>;
19
24
  ctx: TCtx;
20
25
  }) {
26
+ const log = globalThis._EDGE_STORE_LOGGER;
21
27
  const { ctx, provider, router } = params;
28
+ log.debug('Running [init]', { ctx });
22
29
  const ctxToken = await encryptJWT(ctx);
23
30
  const { token } = await provider.init({
24
31
  ctx,
@@ -40,6 +47,8 @@ export async function init<TCtx>(params: {
40
47
  }
41
48
  const baseUrl = await provider.getBaseUrl();
42
49
 
50
+ log.debug('Finished [init]', { ctx, newCookies, token, baseUrl });
51
+
43
52
  return {
44
53
  newCookies,
45
54
  token,
@@ -72,6 +81,8 @@ export async function requestUpload<TCtx>(params: {
72
81
  ctxToken,
73
82
  body: { bucketName, input, fileInfo },
74
83
  } = params;
84
+ const log = globalThis._EDGE_STORE_LOGGER;
85
+ log.debug('Running [requestUpload]', { bucketName, input, fileInfo });
75
86
 
76
87
  if (!ctxToken) {
77
88
  throw new EdgeStoreError({
@@ -80,11 +91,18 @@ export async function requestUpload<TCtx>(params: {
80
91
  });
81
92
  }
82
93
  const ctx = await getContext(ctxToken);
94
+
95
+ log.debug('Decrypted Context', { ctx });
96
+
83
97
  const bucket = router.buckets[bucketName];
84
98
  if (!bucket) {
85
- throw new Error(`Bucket ${bucketName} not found`);
99
+ throw new EdgeStoreError({
100
+ message: `Bucket ${bucketName} not found`,
101
+ code: 'BAD_REQUEST',
102
+ });
86
103
  }
87
104
  if (bucket._def.beforeUpload) {
105
+ log.debug('Running [beforeUpload]');
88
106
  const canUpload = await bucket._def.beforeUpload?.({
89
107
  ctx,
90
108
  input,
@@ -97,16 +115,24 @@ export async function requestUpload<TCtx>(params: {
97
115
  temporary: fileInfo.temporary,
98
116
  },
99
117
  });
118
+ log.debug('Finished [beforeUpload]', { canUpload });
100
119
  if (!canUpload) {
101
- throw new Error('Upload not allowed');
120
+ throw new EdgeStoreError({
121
+ message: 'Upload not allowed for the current context',
122
+ code: 'UPLOAD_NOT_ALLOWED',
123
+ });
102
124
  }
103
125
  }
104
126
 
105
127
  if (bucket._def.type === 'IMAGE') {
106
128
  if (!IMAGE_MIME_TYPES.includes(fileInfo.type)) {
107
129
  throw new EdgeStoreError({
108
- code: 'BAD_REQUEST',
130
+ code: 'MIME_TYPE_NOT_ALLOWED',
109
131
  message: 'Only images are allowed in this bucket',
132
+ details: {
133
+ allowedMimeTypes: IMAGE_MIME_TYPES,
134
+ mimeType: fileInfo.type,
135
+ },
110
136
  });
111
137
  }
112
138
  }
@@ -114,8 +140,12 @@ export async function requestUpload<TCtx>(params: {
114
140
  if (bucket._def.bucketConfig?.maxSize) {
115
141
  if (fileInfo.size > bucket._def.bucketConfig.maxSize) {
116
142
  throw new EdgeStoreError({
117
- code: 'BAD_REQUEST',
143
+ code: 'FILE_TOO_LARGE',
118
144
  message: `File size is too big. Max size is ${bucket._def.bucketConfig.maxSize}`,
145
+ details: {
146
+ maxFileSize: bucket._def.bucketConfig.maxSize,
147
+ fileSize: fileInfo.size,
148
+ },
119
149
  });
120
150
  }
121
151
  }
@@ -137,10 +167,14 @@ export async function requestUpload<TCtx>(params: {
137
167
  }
138
168
  if (!accepted) {
139
169
  throw new EdgeStoreError({
140
- code: 'BAD_REQUEST',
170
+ code: 'MIME_TYPE_NOT_ALLOWED',
141
171
  message: `"${
142
172
  fileInfo.type
143
173
  }" is not allowed. Accepted types are ${JSON.stringify(accept)}`,
174
+ details: {
175
+ allowedMimeTypes: accept,
176
+ mimeType: fileInfo.type,
177
+ },
144
178
  });
145
179
  }
146
180
  }
@@ -152,6 +186,14 @@ export async function requestUpload<TCtx>(params: {
152
186
  });
153
187
  const metadata = await bucket._def.metadata?.({ ctx, input });
154
188
  const isPublic = bucket._def.accessControl === undefined;
189
+
190
+ log.debug('upload info', {
191
+ path,
192
+ metadata,
193
+ isPublic,
194
+ bucketType: bucket._def.type,
195
+ });
196
+
155
197
  const requestUploadRes = await provider.requestUpload({
156
198
  bucketName,
157
199
  bucketType: bucket._def.type,
@@ -162,12 +204,10 @@ export async function requestUpload<TCtx>(params: {
162
204
  metadata,
163
205
  },
164
206
  });
165
- const parsedPath = path.reduce<Record<string, string>>((acc, curr) => {
166
- acc[curr.key] = curr.value;
167
- return acc;
168
- }, {});
207
+ const { parsedPath, pathOrder } = parsePath(path);
208
+
209
+ log.debug('Finished [requestUpload]');
169
210
 
170
- const pathOrder = path.map((p) => p.key);
171
211
  return {
172
212
  ...requestUploadRes,
173
213
  size: fileInfo.size,
@@ -194,10 +234,13 @@ export async function requestUploadParts<TCtx>(params: {
194
234
  }) {
195
235
  const {
196
236
  provider,
197
- router,
198
237
  ctxToken,
199
238
  body: { multipart, path },
200
239
  } = params;
240
+
241
+ const log = globalThis._EDGE_STORE_LOGGER;
242
+ log.debug('Running [requestUploadParts]', { multipart, path });
243
+
201
244
  if (!ctxToken) {
202
245
  throw new EdgeStoreError({
203
246
  message: 'Missing edgestore-ctx cookie',
@@ -205,14 +248,15 @@ export async function requestUploadParts<TCtx>(params: {
205
248
  });
206
249
  }
207
250
  await getContext(ctxToken); // just to check if the token is valid
208
- const bucket = router.buckets[multipart.uploadId];
209
- if (!bucket) {
210
- throw new Error(`Bucket ${multipart.uploadId} not found`);
211
- }
212
- return await provider.requestUploadParts({
251
+
252
+ const res = await provider.requestUploadParts({
213
253
  multipart,
214
254
  path,
215
255
  });
256
+
257
+ log.debug('Finished [requestUploadParts]');
258
+
259
+ return res;
216
260
  }
217
261
 
218
262
  export type CompleteMultipartUploadBody = {
@@ -237,6 +281,14 @@ export async function completeMultipartUpload<TCtx>(params: {
237
281
  ctxToken,
238
282
  body: { bucketName, uploadId, key, parts },
239
283
  } = params;
284
+
285
+ const log = globalThis._EDGE_STORE_LOGGER;
286
+ log.debug('Running [completeMultipartUpload]', {
287
+ bucketName,
288
+ uploadId,
289
+ key,
290
+ });
291
+
240
292
  if (!ctxToken) {
241
293
  throw new EdgeStoreError({
242
294
  message: 'Missing edgestore-ctx cookie',
@@ -246,13 +298,21 @@ export async function completeMultipartUpload<TCtx>(params: {
246
298
  await getContext(ctxToken); // just to check if the token is valid
247
299
  const bucket = router.buckets[bucketName];
248
300
  if (!bucket) {
249
- throw new Error(`Bucket ${bucketName} not found`);
301
+ throw new EdgeStoreError({
302
+ message: `Bucket ${bucketName} not found`,
303
+ code: 'BAD_REQUEST',
304
+ });
250
305
  }
251
- return await provider.completeMultipartUpload({
306
+
307
+ const res = await provider.completeMultipartUpload({
252
308
  uploadId,
253
309
  key,
254
310
  parts,
255
311
  });
312
+
313
+ log.debug('Finished [completeMultipartUpload]');
314
+
315
+ return res;
256
316
  }
257
317
 
258
318
  export type ConfirmUploadBody = {
@@ -273,6 +333,9 @@ export async function confirmUpload<TCtx>(params: {
273
333
  body: { bucketName, url },
274
334
  } = params;
275
335
 
336
+ const log = globalThis._EDGE_STORE_LOGGER;
337
+ log.debug('Running [confirmUpload]', { bucketName, url });
338
+
276
339
  if (!ctxToken) {
277
340
  throw new EdgeStoreError({
278
341
  message: 'Missing edgestore-ctx cookie',
@@ -282,13 +345,19 @@ export async function confirmUpload<TCtx>(params: {
282
345
  await getContext(ctxToken); // just to check if the token is valid
283
346
  const bucket = router.buckets[bucketName];
284
347
  if (!bucket) {
285
- throw new Error(`Bucket ${bucketName} not found`);
348
+ throw new EdgeStoreError({
349
+ message: `Bucket ${bucketName} not found`,
350
+ code: 'BAD_REQUEST',
351
+ });
286
352
  }
287
353
 
288
- return await provider.confirmUpload({
354
+ const res = await provider.confirmUpload({
289
355
  bucket,
290
356
  url: unproxyUrl(url),
291
357
  });
358
+
359
+ log.debug('Finished [confirmUpload]');
360
+ return res;
292
361
  }
293
362
 
294
363
  export type DeleteFileBody = {
@@ -309,6 +378,9 @@ export async function deleteFile<TCtx>(params: {
309
378
  body: { bucketName, url },
310
379
  } = params;
311
380
 
381
+ const log = globalThis._EDGE_STORE_LOGGER;
382
+ log.debug('Running [deleteFile]', { bucketName, url });
383
+
312
384
  if (!ctxToken) {
313
385
  throw new EdgeStoreError({
314
386
  message: 'Missing edgestore-ctx cookie',
@@ -318,38 +390,52 @@ export async function deleteFile<TCtx>(params: {
318
390
  const ctx = await getContext(ctxToken);
319
391
  const bucket = router.buckets[bucketName];
320
392
  if (!bucket) {
321
- throw new Error(`Bucket ${bucketName} not found`);
393
+ throw new EdgeStoreError({
394
+ message: `Bucket ${bucketName} not found`,
395
+ code: 'BAD_REQUEST',
396
+ });
322
397
  }
323
398
 
324
399
  if (!bucket._def.beforeDelete) {
325
- throw new Error(
326
- 'You need to define beforeDelete if you want to delete files directly from the frontend.',
327
- );
400
+ throw new EdgeStoreError({
401
+ message:
402
+ 'You need to define beforeDelete if you want to delete files directly from the frontend.',
403
+ code: 'SERVER_ERROR',
404
+ });
328
405
  }
329
406
 
330
407
  const fileInfo = await provider.getFile({
331
- url,
408
+ url: unproxyUrl(url),
332
409
  });
410
+
333
411
  const canDelete = await bucket._def.beforeDelete({
334
412
  ctx,
335
413
  fileInfo,
336
414
  });
337
415
  if (!canDelete) {
338
- throw new Error('Delete not allowed');
416
+ throw new EdgeStoreError({
417
+ message: 'Delete not allowed for the current context',
418
+ code: 'DELETE_NOT_ALLOWED',
419
+ });
339
420
  }
340
- return await provider.deleteFile({
421
+ const res = await provider.deleteFile({
341
422
  bucket,
342
423
  url: unproxyUrl(url),
343
424
  });
425
+
426
+ log.debug('Finished [deleteFile]');
427
+
428
+ return res;
344
429
  }
345
430
 
346
431
  async function encryptJWT(ctx: any) {
347
432
  const secret =
348
433
  process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
349
434
  if (!secret) {
350
- throw new Error(
351
- 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
352
- );
435
+ throw new EdgeStoreError({
436
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
437
+ code: 'SERVER_ERROR',
438
+ });
353
439
  }
354
440
  const encryptionSecret = await getDerivedEncryptionKey(secret);
355
441
  return await new EncryptJWT(ctx)
@@ -364,9 +450,10 @@ async function decryptJWT(token: string) {
364
450
  const secret =
365
451
  process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
366
452
  if (!secret) {
367
- throw new Error(
368
- 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not set',
369
- );
453
+ throw new EdgeStoreError({
454
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
455
+ code: 'SERVER_ERROR',
456
+ });
370
457
  }
371
458
  const encryptionSecret = await getDerivedEncryptionKey(secret);
372
459
  const { payload } = await jwtDecrypt(token, encryptionSecret, {
@@ -385,7 +472,7 @@ async function getDerivedEncryptionKey(secret: string) {
385
472
  );
386
473
  }
387
474
 
388
- function buildPath(params: {
475
+ export function buildPath(params: {
389
476
  fileInfo: RequestUploadBody['fileInfo'];
390
477
  bucket: AnyBuilder;
391
478
  pathAttrs: {
@@ -398,7 +485,10 @@ function buildPath(params: {
398
485
  const path = pathParams.map((param) => {
399
486
  const paramEntries = Object.entries(param);
400
487
  if (paramEntries[0] === undefined) {
401
- throw new Error('Missing path param');
488
+ throw new EdgeStoreError({
489
+ message: `Empty path param found in: ${JSON.stringify(pathParams)}`,
490
+ code: 'SERVER_ERROR',
491
+ });
402
492
  }
403
493
  const [key, value] = paramEntries[0];
404
494
  // this is a string like: "ctx.xxx" or "input.yyy.zzz"
@@ -406,7 +496,10 @@ function buildPath(params: {
406
496
  .split('.')
407
497
  .reduce((acc2: any, key: string) => {
408
498
  if (acc2[key] === undefined) {
409
- throw new Error(`Missing key ${key} in ${JSON.stringify(acc2)}`);
499
+ throw new EdgeStoreError({
500
+ message: `Missing key ${key} in ${JSON.stringify(acc2)}`,
501
+ code: 'BAD_REQUEST',
502
+ });
410
503
  }
411
504
  return acc2[key];
412
505
  }, params.pathAttrs as any) as string;
@@ -418,10 +511,19 @@ function buildPath(params: {
418
511
  return path;
419
512
  }
420
513
 
421
- async function getContext(token?: string) {
422
- if (!token) {
423
- throw new Error('No token');
424
- }
514
+ export function parsePath(path: { key: string; value: string }[]) {
515
+ const parsedPath = path.reduce<Record<string, string>>((acc, curr) => {
516
+ acc[curr.key] = curr.value;
517
+ return acc;
518
+ }, {});
519
+ const pathOrder = path.map((p) => p.key);
520
+ return {
521
+ parsedPath,
522
+ pathOrder,
523
+ };
524
+ }
525
+
526
+ async function getContext(token: string) {
425
527
  return await decryptJWT(token);
426
528
  }
427
529