@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.
Files changed (45) hide show
  1. package/dist/adapters/next/app/index.d.ts +5 -3
  2. package/dist/adapters/next/app/index.d.ts.map +1 -1
  3. package/dist/adapters/next/app/index.js +38 -15
  4. package/dist/adapters/next/app/index.mjs +37 -14
  5. package/dist/adapters/next/pages/index.d.ts +5 -3
  6. package/dist/adapters/next/pages/index.d.ts.map +1 -1
  7. package/dist/adapters/next/pages/index.js +32 -12
  8. package/dist/adapters/next/pages/index.mjs +31 -11
  9. package/dist/adapters/shared.d.ts.map +1 -1
  10. package/dist/core/client/index.d.ts +56 -2
  11. package/dist/core/client/index.d.ts.map +1 -1
  12. package/dist/core/index.d.ts +2 -0
  13. package/dist/core/index.d.ts.map +1 -1
  14. package/dist/core/index.js +13 -3
  15. package/dist/core/index.mjs +14 -5
  16. package/dist/core/sdk/index.d.ts.map +1 -1
  17. package/dist/{index-50ab9e08.js → index-7cb3a3f3.mjs} +41 -5
  18. package/dist/{index-f33a00fb.js → index-9eb6248c.js} +37 -2
  19. package/dist/{index-30a3741e.mjs → index-e25c8209.js} +48 -2
  20. package/dist/libs/errors/EdgeStoreApiClientError.d.ts +8 -0
  21. package/dist/libs/errors/EdgeStoreApiClientError.d.ts.map +1 -0
  22. package/dist/libs/errors/EdgeStoreError.d.ts +36 -4
  23. package/dist/libs/errors/EdgeStoreError.d.ts.map +1 -1
  24. package/dist/libs/logger.d.ts +13 -0
  25. package/dist/libs/logger.d.ts.map +1 -0
  26. package/dist/logger-0f08f252.mjs +40 -0
  27. package/dist/logger-623f2833.js +42 -0
  28. package/dist/logger-8f098618.js +33 -0
  29. package/dist/providers/edgestore/index.d.ts.map +1 -1
  30. package/dist/providers/edgestore/index.js +10 -3
  31. package/dist/providers/edgestore/index.mjs +10 -3
  32. package/dist/{shared-5d1e7f43.js → shared-53cb59dd.js} +72 -51
  33. package/dist/{shared-30b7a2ab.mjs → shared-b14a84ee.mjs} +65 -42
  34. package/dist/{shared-88655ba7.js → shared-f8ddbf7c.js} +62 -36
  35. package/package.json +2 -2
  36. package/src/adapters/next/app/index.ts +52 -19
  37. package/src/adapters/next/pages/index.ts +43 -14
  38. package/src/adapters/shared.ts +61 -29
  39. package/src/core/client/index.ts +57 -2
  40. package/src/core/index.ts +6 -0
  41. package/src/core/sdk/index.ts +7 -1
  42. package/src/libs/errors/EdgeStoreApiClientError.ts +14 -0
  43. package/src/libs/errors/EdgeStoreError.ts +76 -7
  44. package/src/libs/logger.ts +44 -0
  45. package/src/providers/edgestore/index.ts +9 -2
@@ -2,22 +2,7 @@ import { hkdf } from '@panva/hkdf';
2
2
  import { serialize } from 'cookie';
3
3
  import { EncryptJWT, jwtDecrypt } from 'jose';
4
4
  import { v4 } from 'uuid';
5
- import { _ } from '@swc/helpers/_/_define_property';
6
-
7
- const EDGE_STORE_ERROR_CODES = {
8
- BAD_REQUEST: 400,
9
- UNAUTHORIZED: 401
10
- };
11
- class EdgeStoreError extends Error {
12
- constructor(opts){
13
- super(opts.message);
14
- _(this, "cause", void 0);
15
- _(this, "code", void 0);
16
- this.name = 'EdgeStoreError';
17
- this.code = opts.code;
18
- this.cause = opts.cause;
19
- }
20
- }
5
+ import { E as EdgeStoreError } from './index-7cb3a3f3.mjs';
21
6
 
22
7
  const IMAGE_MIME_TYPES = [
23
8
  'image/jpeg',
@@ -69,7 +54,10 @@ async function requestUpload(params) {
69
54
  const ctx = await getContext(ctxToken);
70
55
  const bucket = router.buckets[bucketName];
71
56
  if (!bucket) {
72
- throw new Error(`Bucket ${bucketName} not found`);
57
+ throw new EdgeStoreError({
58
+ message: `Bucket ${bucketName} not found`,
59
+ code: 'BAD_REQUEST'
60
+ });
73
61
  }
74
62
  if (bucket._def.beforeUpload) {
75
63
  const canUpload = await bucket._def.beforeUpload?.({
@@ -85,22 +73,33 @@ async function requestUpload(params) {
85
73
  }
86
74
  });
87
75
  if (!canUpload) {
88
- throw new Error('Upload not allowed');
76
+ throw new EdgeStoreError({
77
+ message: 'Upload not allowed for the current context',
78
+ code: 'UPLOAD_NOT_ALLOWED'
79
+ });
89
80
  }
90
81
  }
91
82
  if (bucket._def.type === 'IMAGE') {
92
83
  if (!IMAGE_MIME_TYPES.includes(fileInfo.type)) {
93
84
  throw new EdgeStoreError({
94
- code: 'BAD_REQUEST',
95
- message: 'Only images are allowed in this bucket'
85
+ code: 'MIME_TYPE_NOT_ALLOWED',
86
+ message: 'Only images are allowed in this bucket',
87
+ details: {
88
+ allowedMimeTypes: IMAGE_MIME_TYPES,
89
+ mimeType: fileInfo.type
90
+ }
96
91
  });
97
92
  }
98
93
  }
99
94
  if (bucket._def.bucketConfig?.maxSize) {
100
95
  if (fileInfo.size > bucket._def.bucketConfig.maxSize) {
101
96
  throw new EdgeStoreError({
102
- code: 'BAD_REQUEST',
103
- message: `File size is too big. Max size is ${bucket._def.bucketConfig.maxSize}`
97
+ code: 'FILE_TOO_LARGE',
98
+ message: `File size is too big. Max size is ${bucket._def.bucketConfig.maxSize}`,
99
+ details: {
100
+ maxFileSize: bucket._def.bucketConfig.maxSize,
101
+ fileSize: fileInfo.size
102
+ }
104
103
  });
105
104
  }
106
105
  }
@@ -121,8 +120,12 @@ async function requestUpload(params) {
121
120
  }
122
121
  if (!accepted) {
123
122
  throw new EdgeStoreError({
124
- code: 'BAD_REQUEST',
125
- message: `"${fileInfo.type}" is not allowed. Accepted types are ${JSON.stringify(accept)}`
123
+ code: 'MIME_TYPE_NOT_ALLOWED',
124
+ message: `"${fileInfo.type}" is not allowed. Accepted types are ${JSON.stringify(accept)}`,
125
+ details: {
126
+ allowedMimeTypes: accept,
127
+ mimeType: fileInfo.type
128
+ }
126
129
  });
127
130
  }
128
131
  }
@@ -160,7 +163,7 @@ async function requestUpload(params) {
160
163
  };
161
164
  }
162
165
  async function requestUploadParts(params) {
163
- const { provider, router, ctxToken, body: { multipart, path } } = params;
166
+ const { provider, ctxToken, body: { multipart, path } } = params;
164
167
  if (!ctxToken) {
165
168
  throw new EdgeStoreError({
166
169
  message: 'Missing edgestore-ctx cookie',
@@ -168,10 +171,6 @@ async function requestUploadParts(params) {
168
171
  });
169
172
  }
170
173
  await getContext(ctxToken); // just to check if the token is valid
171
- const bucket = router.buckets[multipart.uploadId];
172
- if (!bucket) {
173
- throw new Error(`Bucket ${multipart.uploadId} not found`);
174
- }
175
174
  return await provider.requestUploadParts({
176
175
  multipart,
177
176
  path
@@ -188,7 +187,10 @@ async function completeMultipartUpload(params) {
188
187
  await getContext(ctxToken); // just to check if the token is valid
189
188
  const bucket = router.buckets[bucketName];
190
189
  if (!bucket) {
191
- throw new Error(`Bucket ${bucketName} not found`);
190
+ throw new EdgeStoreError({
191
+ message: `Bucket ${bucketName} not found`,
192
+ code: 'BAD_REQUEST'
193
+ });
192
194
  }
193
195
  return await provider.completeMultipartUpload({
194
196
  uploadId,
@@ -207,7 +209,10 @@ async function confirmUpload(params) {
207
209
  await getContext(ctxToken); // just to check if the token is valid
208
210
  const bucket = router.buckets[bucketName];
209
211
  if (!bucket) {
210
- throw new Error(`Bucket ${bucketName} not found`);
212
+ throw new EdgeStoreError({
213
+ message: `Bucket ${bucketName} not found`,
214
+ code: 'BAD_REQUEST'
215
+ });
211
216
  }
212
217
  return await provider.confirmUpload({
213
218
  bucket,
@@ -225,10 +230,16 @@ async function deleteFile(params) {
225
230
  const ctx = await getContext(ctxToken);
226
231
  const bucket = router.buckets[bucketName];
227
232
  if (!bucket) {
228
- throw new Error(`Bucket ${bucketName} not found`);
233
+ throw new EdgeStoreError({
234
+ message: `Bucket ${bucketName} not found`,
235
+ code: 'BAD_REQUEST'
236
+ });
229
237
  }
230
238
  if (!bucket._def.beforeDelete) {
231
- throw new Error('You need to define beforeDelete if you want to delete files directly from the frontend.');
239
+ throw new EdgeStoreError({
240
+ message: 'You need to define beforeDelete if you want to delete files directly from the frontend.',
241
+ code: 'SERVER_ERROR'
242
+ });
232
243
  }
233
244
  const fileInfo = await provider.getFile({
234
245
  url
@@ -238,7 +249,10 @@ async function deleteFile(params) {
238
249
  fileInfo
239
250
  });
240
251
  if (!canDelete) {
241
- throw new Error('Delete not allowed');
252
+ throw new EdgeStoreError({
253
+ message: 'Delete not allowed for the current context',
254
+ code: 'DELETE_NOT_ALLOWED'
255
+ });
242
256
  }
243
257
  return await provider.deleteFile({
244
258
  bucket,
@@ -248,7 +262,10 @@ async function deleteFile(params) {
248
262
  async function encryptJWT(ctx) {
249
263
  const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
250
264
  if (!secret) {
251
- throw new Error('EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined');
265
+ throw new EdgeStoreError({
266
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
267
+ code: 'SERVER_ERROR'
268
+ });
252
269
  }
253
270
  const encryptionSecret = await getDerivedEncryptionKey(secret);
254
271
  return await new EncryptJWT(ctx).setProtectedHeader({
@@ -259,7 +276,10 @@ async function encryptJWT(ctx) {
259
276
  async function decryptJWT(token) {
260
277
  const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
261
278
  if (!secret) {
262
- throw new Error('EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not set');
279
+ throw new EdgeStoreError({
280
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
281
+ code: 'SERVER_ERROR'
282
+ });
263
283
  }
264
284
  const encryptionSecret = await getDerivedEncryptionKey(secret);
265
285
  const { payload } = await jwtDecrypt(token, encryptionSecret, {
@@ -276,13 +296,19 @@ function buildPath(params) {
276
296
  const path = pathParams.map((param)=>{
277
297
  const paramEntries = Object.entries(param);
278
298
  if (paramEntries[0] === undefined) {
279
- throw new Error('Missing path param');
299
+ throw new EdgeStoreError({
300
+ message: `Empty path param found in: ${JSON.stringify(pathParams)}`,
301
+ code: 'SERVER_ERROR'
302
+ });
280
303
  }
281
304
  const [key, value] = paramEntries[0];
282
305
  // this is a string like: "ctx.xxx" or "input.yyy.zzz"
283
306
  const currParamVal = value().split('.').reduce((acc2, key)=>{
284
307
  if (acc2[key] === undefined) {
285
- throw new Error(`Missing key ${key} in ${JSON.stringify(acc2)}`);
308
+ throw new EdgeStoreError({
309
+ message: `Missing key ${key} in ${JSON.stringify(acc2)}`,
310
+ code: 'BAD_REQUEST'
311
+ });
286
312
  }
287
313
  return acc2[key];
288
314
  }, params.pathAttrs);
@@ -305,9 +331,6 @@ function parsePath(path) {
305
331
  };
306
332
  }
307
333
  async function getContext(token) {
308
- if (!token) {
309
- throw new Error('No token');
310
- }
311
334
  return await decryptJWT(token);
312
335
  }
313
336
  /**
@@ -327,4 +350,4 @@ async function getContext(token) {
327
350
  return url;
328
351
  }
329
352
 
330
- export { EdgeStoreError as E, requestUploadParts as a, buildPath as b, completeMultipartUpload as c, confirmUpload as d, deleteFile as e, EDGE_STORE_ERROR_CODES as f, init as i, parsePath as p, requestUpload as r };
353
+ export { requestUploadParts as a, buildPath as b, completeMultipartUpload as c, confirmUpload as d, deleteFile as e, init as i, parsePath as p, requestUpload as r };
@@ -2,19 +2,7 @@ import { hkdf } from '@panva/hkdf';
2
2
  import { serialize } from 'cookie';
3
3
  import { EncryptJWT, jwtDecrypt } from 'jose';
4
4
  import { v4 } from 'uuid';
5
-
6
- const EDGE_STORE_ERROR_CODES = {
7
- BAD_REQUEST: 400,
8
- UNAUTHORIZED: 401,
9
- };
10
- class EdgeStoreError extends Error {
11
- constructor(opts) {
12
- super(opts.message);
13
- this.name = 'EdgeStoreError';
14
- this.code = opts.code;
15
- this.cause = opts.cause;
16
- }
17
- }
5
+ import { E as EdgeStoreError } from './index-9eb6248c.js';
18
6
 
19
7
  const IMAGE_MIME_TYPES = [
20
8
  'image/jpeg',
@@ -66,7 +54,10 @@ async function requestUpload(params) {
66
54
  const ctx = await getContext(ctxToken);
67
55
  const bucket = router.buckets[bucketName];
68
56
  if (!bucket) {
69
- throw new Error(`Bucket ${bucketName} not found`);
57
+ throw new EdgeStoreError({
58
+ message: `Bucket ${bucketName} not found`,
59
+ code: 'BAD_REQUEST',
60
+ });
70
61
  }
71
62
  if (bucket._def.beforeUpload) {
72
63
  const canUpload = await bucket._def.beforeUpload?.({
@@ -82,22 +73,33 @@ async function requestUpload(params) {
82
73
  },
83
74
  });
84
75
  if (!canUpload) {
85
- throw new Error('Upload not allowed');
76
+ throw new EdgeStoreError({
77
+ message: 'Upload not allowed for the current context',
78
+ code: 'UPLOAD_NOT_ALLOWED',
79
+ });
86
80
  }
87
81
  }
88
82
  if (bucket._def.type === 'IMAGE') {
89
83
  if (!IMAGE_MIME_TYPES.includes(fileInfo.type)) {
90
84
  throw new EdgeStoreError({
91
- code: 'BAD_REQUEST',
85
+ code: 'MIME_TYPE_NOT_ALLOWED',
92
86
  message: 'Only images are allowed in this bucket',
87
+ details: {
88
+ allowedMimeTypes: IMAGE_MIME_TYPES,
89
+ mimeType: fileInfo.type,
90
+ },
93
91
  });
94
92
  }
95
93
  }
96
94
  if (bucket._def.bucketConfig?.maxSize) {
97
95
  if (fileInfo.size > bucket._def.bucketConfig.maxSize) {
98
96
  throw new EdgeStoreError({
99
- code: 'BAD_REQUEST',
97
+ code: 'FILE_TOO_LARGE',
100
98
  message: `File size is too big. Max size is ${bucket._def.bucketConfig.maxSize}`,
99
+ details: {
100
+ maxFileSize: bucket._def.bucketConfig.maxSize,
101
+ fileSize: fileInfo.size,
102
+ },
101
103
  });
102
104
  }
103
105
  }
@@ -119,8 +121,12 @@ async function requestUpload(params) {
119
121
  }
120
122
  if (!accepted) {
121
123
  throw new EdgeStoreError({
122
- code: 'BAD_REQUEST',
124
+ code: 'MIME_TYPE_NOT_ALLOWED',
123
125
  message: `"${fileInfo.type}" is not allowed. Accepted types are ${JSON.stringify(accept)}`,
126
+ details: {
127
+ allowedMimeTypes: accept,
128
+ mimeType: fileInfo.type,
129
+ },
124
130
  });
125
131
  }
126
132
  }
@@ -152,7 +158,7 @@ async function requestUpload(params) {
152
158
  };
153
159
  }
154
160
  async function requestUploadParts(params) {
155
- const { provider, router, ctxToken, body: { multipart, path }, } = params;
161
+ const { provider, ctxToken, body: { multipart, path }, } = params;
156
162
  if (!ctxToken) {
157
163
  throw new EdgeStoreError({
158
164
  message: 'Missing edgestore-ctx cookie',
@@ -160,10 +166,6 @@ async function requestUploadParts(params) {
160
166
  });
161
167
  }
162
168
  await getContext(ctxToken); // just to check if the token is valid
163
- const bucket = router.buckets[multipart.uploadId];
164
- if (!bucket) {
165
- throw new Error(`Bucket ${multipart.uploadId} not found`);
166
- }
167
169
  return await provider.requestUploadParts({
168
170
  multipart,
169
171
  path,
@@ -180,7 +182,10 @@ async function completeMultipartUpload(params) {
180
182
  await getContext(ctxToken); // just to check if the token is valid
181
183
  const bucket = router.buckets[bucketName];
182
184
  if (!bucket) {
183
- throw new Error(`Bucket ${bucketName} not found`);
185
+ throw new EdgeStoreError({
186
+ message: `Bucket ${bucketName} not found`,
187
+ code: 'BAD_REQUEST',
188
+ });
184
189
  }
185
190
  return await provider.completeMultipartUpload({
186
191
  uploadId,
@@ -199,7 +204,10 @@ async function confirmUpload(params) {
199
204
  await getContext(ctxToken); // just to check if the token is valid
200
205
  const bucket = router.buckets[bucketName];
201
206
  if (!bucket) {
202
- throw new Error(`Bucket ${bucketName} not found`);
207
+ throw new EdgeStoreError({
208
+ message: `Bucket ${bucketName} not found`,
209
+ code: 'BAD_REQUEST',
210
+ });
203
211
  }
204
212
  return await provider.confirmUpload({
205
213
  bucket,
@@ -217,10 +225,16 @@ async function deleteFile(params) {
217
225
  const ctx = await getContext(ctxToken);
218
226
  const bucket = router.buckets[bucketName];
219
227
  if (!bucket) {
220
- throw new Error(`Bucket ${bucketName} not found`);
228
+ throw new EdgeStoreError({
229
+ message: `Bucket ${bucketName} not found`,
230
+ code: 'BAD_REQUEST',
231
+ });
221
232
  }
222
233
  if (!bucket._def.beforeDelete) {
223
- throw new Error('You need to define beforeDelete if you want to delete files directly from the frontend.');
234
+ throw new EdgeStoreError({
235
+ message: 'You need to define beforeDelete if you want to delete files directly from the frontend.',
236
+ code: 'SERVER_ERROR',
237
+ });
224
238
  }
225
239
  const fileInfo = await provider.getFile({
226
240
  url,
@@ -230,7 +244,10 @@ async function deleteFile(params) {
230
244
  fileInfo,
231
245
  });
232
246
  if (!canDelete) {
233
- throw new Error('Delete not allowed');
247
+ throw new EdgeStoreError({
248
+ message: 'Delete not allowed for the current context',
249
+ code: 'DELETE_NOT_ALLOWED',
250
+ });
234
251
  }
235
252
  return await provider.deleteFile({
236
253
  bucket,
@@ -240,7 +257,10 @@ async function deleteFile(params) {
240
257
  async function encryptJWT(ctx) {
241
258
  const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
242
259
  if (!secret) {
243
- throw new Error('EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined');
260
+ throw new EdgeStoreError({
261
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
262
+ code: 'SERVER_ERROR',
263
+ });
244
264
  }
245
265
  const encryptionSecret = await getDerivedEncryptionKey(secret);
246
266
  return await new EncryptJWT(ctx)
@@ -253,7 +273,10 @@ async function encryptJWT(ctx) {
253
273
  async function decryptJWT(token) {
254
274
  const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
255
275
  if (!secret) {
256
- throw new Error('EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not set');
276
+ throw new EdgeStoreError({
277
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
278
+ code: 'SERVER_ERROR',
279
+ });
257
280
  }
258
281
  const encryptionSecret = await getDerivedEncryptionKey(secret);
259
282
  const { payload } = await jwtDecrypt(token, encryptionSecret, {
@@ -270,7 +293,10 @@ function buildPath(params) {
270
293
  const path = pathParams.map((param) => {
271
294
  const paramEntries = Object.entries(param);
272
295
  if (paramEntries[0] === undefined) {
273
- throw new Error('Missing path param');
296
+ throw new EdgeStoreError({
297
+ message: `Empty path param found in: ${JSON.stringify(pathParams)}`,
298
+ code: 'SERVER_ERROR',
299
+ });
274
300
  }
275
301
  const [key, value] = paramEntries[0];
276
302
  // this is a string like: "ctx.xxx" or "input.yyy.zzz"
@@ -278,7 +304,10 @@ function buildPath(params) {
278
304
  .split('.')
279
305
  .reduce((acc2, key) => {
280
306
  if (acc2[key] === undefined) {
281
- throw new Error(`Missing key ${key} in ${JSON.stringify(acc2)}`);
307
+ throw new EdgeStoreError({
308
+ message: `Missing key ${key} in ${JSON.stringify(acc2)}`,
309
+ code: 'BAD_REQUEST',
310
+ });
282
311
  }
283
312
  return acc2[key];
284
313
  }, params.pathAttrs);
@@ -301,9 +330,6 @@ function parsePath(path) {
301
330
  };
302
331
  }
303
332
  async function getContext(token) {
304
- if (!token) {
305
- throw new Error('No token');
306
- }
307
333
  return await decryptJWT(token);
308
334
  }
309
335
  /**
@@ -324,4 +350,4 @@ function unproxyUrl(url) {
324
350
  return url;
325
351
  }
326
352
 
327
- export { EdgeStoreError as E, requestUploadParts as a, buildPath as b, completeMultipartUpload as c, confirmUpload as d, deleteFile as e, EDGE_STORE_ERROR_CODES as f, init as i, parsePath as p, requestUpload as r };
353
+ export { requestUploadParts as a, buildPath as b, completeMultipartUpload as c, confirmUpload as d, deleteFile as e, init as i, parsePath as p, requestUpload as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgestore/server",
3
- "version": "0.1.5-alpha.4",
3
+ "version": "0.1.5-alpha.5",
4
4
  "description": "Upload files with ease from React/Next.js",
5
5
  "homepage": "https://edgestore.dev",
6
6
  "repository": "https://github.com/edgestorejs/edgestore.git",
@@ -127,5 +127,5 @@
127
127
  "typescript": "^5.1.6",
128
128
  "zod": "^3.21.4"
129
129
  },
130
- "gitHead": "ae79c8b36dd3969ae3c0c3d5b8294961faf9e497"
130
+ "gitHead": "eb9944bf86d040a4bcbe8753cb428be5cf3e0cf7"
131
131
  }
@@ -1,8 +1,11 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
1
2
  import { type NextRequest } from 'next/server';
2
3
  import { type EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
3
4
  import EdgeStoreError, {
4
5
  EDGE_STORE_ERROR_CODES,
6
+ type EdgeStoreErrorCodeKey,
5
7
  } from '../../../libs/errors/EdgeStoreError';
8
+ import Logger, { type LogLevel } from '../../../libs/logger';
6
9
  import { EdgeStoreProvider } from '../../../providers/edgestore';
7
10
  import { type Provider } from '../../../providers/types';
8
11
  import { type MaybePromise } from '../../../types';
@@ -24,26 +27,43 @@ export type CreateContextOptions = {
24
27
  req: NextRequest;
25
28
  };
26
29
 
27
- export type Config<TCtx> = TCtx extends Record<string, never>
28
- ? {
29
- provider?: Provider;
30
- router: EdgeStoreRouter<TCtx>;
31
- }
30
+ export type Config<TCtx> = {
31
+ provider?: Provider;
32
+ router: EdgeStoreRouter<TCtx>;
33
+ logLevel?: LogLevel;
34
+ } & (TCtx extends Record<string, never>
35
+ ? {}
32
36
  : {
33
37
  provider?: Provider;
34
38
  router: EdgeStoreRouter<TCtx>;
35
39
  createContext: (opts: CreateContextOptions) => MaybePromise<TCtx>;
36
- };
40
+ });
37
41
 
38
42
  export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
39
43
  const { provider = EdgeStoreProvider() } = config;
44
+ const log = new Logger(config.logLevel);
40
45
  return async (req: NextRequest) => {
41
46
  try {
47
+ if (!('nextUrl' in req))
48
+ throw new EdgeStoreError({
49
+ message:
50
+ 'Error running the app adapter. Make sure you are importing the correct adapter in your router configuration',
51
+ code: 'SERVER_ERROR',
52
+ });
42
53
  if (req.nextUrl.pathname.endsWith('/init')) {
43
- const ctx =
44
- 'createContext' in config
45
- ? await config.createContext({ req })
46
- : ({} as TCtx);
54
+ let ctx = {} as TCtx;
55
+ try {
56
+ ctx =
57
+ 'createContext' in config
58
+ ? await config.createContext({ req })
59
+ : ({} as TCtx);
60
+ } catch (err) {
61
+ throw new EdgeStoreError({
62
+ message: 'Error creating context',
63
+ code: 'CREATE_CONTEXT_ERROR',
64
+ cause: err instanceof Error ? err : undefined,
65
+ });
66
+ }
47
67
  const { newCookies, token, baseUrl } = await init({
48
68
  ctx,
49
69
  provider,
@@ -157,17 +177,30 @@ export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
157
177
  }
158
178
  } catch (err) {
159
179
  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,
180
+ log[err.level](err.formattedMessage());
181
+ if (err.cause) log[err.level](err.cause);
182
+ return new Response(JSON.stringify(err.formattedJson()), {
183
+ status: EDGE_STORE_ERROR_CODES[err.code as EdgeStoreErrorCodeKey],
184
+ headers: {
185
+ 'Content-Type': 'application/json',
186
+ },
166
187
  });
167
188
  }
168
- return new Response('Internal server error', {
169
- status: 500,
170
- });
189
+ log.error(err);
190
+ return new Response(
191
+ JSON.stringify(
192
+ new EdgeStoreError({
193
+ message: 'Internal server error',
194
+ code: 'SERVER_ERROR',
195
+ }).formattedJson(),
196
+ ),
197
+ {
198
+ status: 500,
199
+ headers: {
200
+ 'Content-Type': 'application/json',
201
+ },
202
+ },
203
+ );
171
204
  }
172
205
  };
173
206
  }
@@ -1,8 +1,11 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
1
2
  import { type NextApiRequest, type NextApiResponse } from 'next/types';
2
3
  import { type EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
3
4
  import EdgeStoreError, {
4
5
  EDGE_STORE_ERROR_CODES,
6
+ type EdgeStoreErrorCodeKey,
5
7
  } from '../../../libs/errors/EdgeStoreError';
8
+ import Logger, { type LogLevel } from '../../../libs/logger';
6
9
  import { EdgeStoreProvider } from '../../../providers/edgestore';
7
10
  import { type Provider } from '../../../providers/types';
8
11
  import { type MaybePromise } from '../../../types';
@@ -25,26 +28,43 @@ export type CreateContextOptions = {
25
28
  res: NextApiResponse;
26
29
  };
27
30
 
28
- export type Config<TCtx> = TCtx extends Record<string, never>
29
- ? {
30
- provider?: Provider;
31
- router: EdgeStoreRouter<TCtx>;
32
- }
31
+ export type Config<TCtx> = {
32
+ provider?: Provider;
33
+ router: EdgeStoreRouter<TCtx>;
34
+ logLevel?: LogLevel;
35
+ } & (TCtx extends Record<string, never>
36
+ ? {}
33
37
  : {
34
38
  provider?: Provider;
35
39
  router: EdgeStoreRouter<TCtx>;
36
40
  createContext: (opts: CreateContextOptions) => MaybePromise<TCtx>;
37
- };
41
+ });
38
42
 
39
43
  export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
40
44
  const { provider = EdgeStoreProvider() } = config;
45
+ const log = new Logger(config.logLevel);
41
46
  return async (req: NextApiRequest, res: NextApiResponse) => {
42
47
  try {
48
+ if (!('json' in res))
49
+ throw new EdgeStoreError({
50
+ message:
51
+ 'Error running the pages adapter. Make sure you are importing the correct adapter in your router configuration',
52
+ code: 'SERVER_ERROR',
53
+ });
43
54
  if (req.url?.includes?.('/init')) {
44
- const ctx =
45
- 'createContext' in config
46
- ? await config.createContext({ req, res })
47
- : ({} as TCtx);
55
+ let ctx = {} as TCtx;
56
+ try {
57
+ ctx =
58
+ 'createContext' in config
59
+ ? await config.createContext({ req, res })
60
+ : ({} as TCtx);
61
+ } catch (err) {
62
+ throw new EdgeStoreError({
63
+ message: 'Error creating context',
64
+ code: 'CREATE_CONTEXT_ERROR',
65
+ cause: err instanceof Error ? err : undefined,
66
+ });
67
+ }
48
68
  const { newCookies, token, baseUrl } = await init({
49
69
  ctx,
50
70
  provider,
@@ -123,11 +143,20 @@ export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
123
143
  }
124
144
  } catch (err) {
125
145
  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);
146
+ log[err.level](err.formattedMessage());
147
+ if (err.cause) log[err.level](err.cause);
148
+ res
149
+ .status(EDGE_STORE_ERROR_CODES[err.code as EdgeStoreErrorCodeKey])
150
+ .json(err.formattedJson());
151
+ } else {
152
+ log.error(err);
153
+ res.status(500).send(
154
+ new EdgeStoreError({
155
+ message: 'Internal Server Error',
156
+ code: 'SERVER_ERROR',
157
+ }).formattedJson(),
158
+ );
129
159
  }
130
- res.status(500).send('Internal server error');
131
160
  }
132
161
  };
133
162
  }