@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,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-0c401ce1.js';
18
6
 
19
7
  const IMAGE_MIME_TYPES = [
20
8
  'image/jpeg',
@@ -30,7 +18,9 @@ const IMAGE_MIME_TYPES = [
30
18
  // TODO: change it to 1 hour when we have a way to refresh the token
31
19
  const DEFAULT_MAX_AGE = 30 * 24 * 60 * 60; // 30 days
32
20
  async function init(params) {
21
+ const log = globalThis._EDGE_STORE_LOGGER;
33
22
  const { ctx, provider, router } = params;
23
+ log.debug('Running [init]', { ctx });
34
24
  const ctxToken = await encryptJWT(ctx);
35
25
  const { token } = await provider.init({
36
26
  ctx,
@@ -49,6 +39,7 @@ async function init(params) {
49
39
  }));
50
40
  }
51
41
  const baseUrl = await provider.getBaseUrl();
42
+ log.debug('Finished [init]', { ctx, newCookies, token, baseUrl });
52
43
  return {
53
44
  newCookies,
54
45
  token,
@@ -57,6 +48,8 @@ async function init(params) {
57
48
  }
58
49
  async function requestUpload(params) {
59
50
  const { provider, router, ctxToken, body: { bucketName, input, fileInfo }, } = params;
51
+ const log = globalThis._EDGE_STORE_LOGGER;
52
+ log.debug('Running [requestUpload]', { bucketName, input, fileInfo });
60
53
  if (!ctxToken) {
61
54
  throw new EdgeStoreError({
62
55
  message: 'Missing edgestore-ctx cookie',
@@ -64,11 +57,16 @@ async function requestUpload(params) {
64
57
  });
65
58
  }
66
59
  const ctx = await getContext(ctxToken);
60
+ log.debug('Decrypted Context', { ctx });
67
61
  const bucket = router.buckets[bucketName];
68
62
  if (!bucket) {
69
- throw new Error(`Bucket ${bucketName} not found`);
63
+ throw new EdgeStoreError({
64
+ message: `Bucket ${bucketName} not found`,
65
+ code: 'BAD_REQUEST',
66
+ });
70
67
  }
71
68
  if (bucket._def.beforeUpload) {
69
+ log.debug('Running [beforeUpload]');
72
70
  const canUpload = await bucket._def.beforeUpload?.({
73
71
  ctx,
74
72
  input,
@@ -81,23 +79,35 @@ async function requestUpload(params) {
81
79
  temporary: fileInfo.temporary,
82
80
  },
83
81
  });
82
+ log.debug('Finished [beforeUpload]', { canUpload });
84
83
  if (!canUpload) {
85
- throw new Error('Upload not allowed');
84
+ throw new EdgeStoreError({
85
+ message: 'Upload not allowed for the current context',
86
+ code: 'UPLOAD_NOT_ALLOWED',
87
+ });
86
88
  }
87
89
  }
88
90
  if (bucket._def.type === 'IMAGE') {
89
91
  if (!IMAGE_MIME_TYPES.includes(fileInfo.type)) {
90
92
  throw new EdgeStoreError({
91
- code: 'BAD_REQUEST',
93
+ code: 'MIME_TYPE_NOT_ALLOWED',
92
94
  message: 'Only images are allowed in this bucket',
95
+ details: {
96
+ allowedMimeTypes: IMAGE_MIME_TYPES,
97
+ mimeType: fileInfo.type,
98
+ },
93
99
  });
94
100
  }
95
101
  }
96
102
  if (bucket._def.bucketConfig?.maxSize) {
97
103
  if (fileInfo.size > bucket._def.bucketConfig.maxSize) {
98
104
  throw new EdgeStoreError({
99
- code: 'BAD_REQUEST',
105
+ code: 'FILE_TOO_LARGE',
100
106
  message: `File size is too big. Max size is ${bucket._def.bucketConfig.maxSize}`,
107
+ details: {
108
+ maxFileSize: bucket._def.bucketConfig.maxSize,
109
+ fileSize: fileInfo.size,
110
+ },
101
111
  });
102
112
  }
103
113
  }
@@ -119,8 +129,12 @@ async function requestUpload(params) {
119
129
  }
120
130
  if (!accepted) {
121
131
  throw new EdgeStoreError({
122
- code: 'BAD_REQUEST',
132
+ code: 'MIME_TYPE_NOT_ALLOWED',
123
133
  message: `"${fileInfo.type}" is not allowed. Accepted types are ${JSON.stringify(accept)}`,
134
+ details: {
135
+ allowedMimeTypes: accept,
136
+ mimeType: fileInfo.type,
137
+ },
124
138
  });
125
139
  }
126
140
  }
@@ -131,6 +145,12 @@ async function requestUpload(params) {
131
145
  });
132
146
  const metadata = await bucket._def.metadata?.({ ctx, input });
133
147
  const isPublic = bucket._def.accessControl === undefined;
148
+ log.debug('upload info', {
149
+ path,
150
+ metadata,
151
+ isPublic,
152
+ bucketType: bucket._def.type,
153
+ });
134
154
  const requestUploadRes = await provider.requestUpload({
135
155
  bucketName,
136
156
  bucketType: bucket._def.type,
@@ -141,11 +161,8 @@ async function requestUpload(params) {
141
161
  metadata,
142
162
  },
143
163
  });
144
- const parsedPath = path.reduce((acc, curr) => {
145
- acc[curr.key] = curr.value;
146
- return acc;
147
- }, {});
148
- const pathOrder = path.map((p) => p.key);
164
+ const { parsedPath, pathOrder } = parsePath(path);
165
+ log.debug('Finished [requestUpload]');
149
166
  return {
150
167
  ...requestUploadRes,
151
168
  size: fileInfo.size,
@@ -156,7 +173,9 @@ async function requestUpload(params) {
156
173
  };
157
174
  }
158
175
  async function requestUploadParts(params) {
159
- const { provider, router, ctxToken, body: { multipart, path }, } = params;
176
+ const { provider, ctxToken, body: { multipart, path }, } = params;
177
+ const log = globalThis._EDGE_STORE_LOGGER;
178
+ log.debug('Running [requestUploadParts]', { multipart, path });
160
179
  if (!ctxToken) {
161
180
  throw new EdgeStoreError({
162
181
  message: 'Missing edgestore-ctx cookie',
@@ -164,17 +183,21 @@ async function requestUploadParts(params) {
164
183
  });
165
184
  }
166
185
  await getContext(ctxToken); // just to check if the token is valid
167
- const bucket = router.buckets[multipart.uploadId];
168
- if (!bucket) {
169
- throw new Error(`Bucket ${multipart.uploadId} not found`);
170
- }
171
- return await provider.requestUploadParts({
186
+ const res = await provider.requestUploadParts({
172
187
  multipart,
173
188
  path,
174
189
  });
190
+ log.debug('Finished [requestUploadParts]');
191
+ return res;
175
192
  }
176
193
  async function completeMultipartUpload(params) {
177
194
  const { provider, router, ctxToken, body: { bucketName, uploadId, key, parts }, } = params;
195
+ const log = globalThis._EDGE_STORE_LOGGER;
196
+ log.debug('Running [completeMultipartUpload]', {
197
+ bucketName,
198
+ uploadId,
199
+ key,
200
+ });
178
201
  if (!ctxToken) {
179
202
  throw new EdgeStoreError({
180
203
  message: 'Missing edgestore-ctx cookie',
@@ -184,16 +207,23 @@ async function completeMultipartUpload(params) {
184
207
  await getContext(ctxToken); // just to check if the token is valid
185
208
  const bucket = router.buckets[bucketName];
186
209
  if (!bucket) {
187
- throw new Error(`Bucket ${bucketName} not found`);
210
+ throw new EdgeStoreError({
211
+ message: `Bucket ${bucketName} not found`,
212
+ code: 'BAD_REQUEST',
213
+ });
188
214
  }
189
- return await provider.completeMultipartUpload({
215
+ const res = await provider.completeMultipartUpload({
190
216
  uploadId,
191
217
  key,
192
218
  parts,
193
219
  });
220
+ log.debug('Finished [completeMultipartUpload]');
221
+ return res;
194
222
  }
195
223
  async function confirmUpload(params) {
196
224
  const { provider, router, ctxToken, body: { bucketName, url }, } = params;
225
+ const log = globalThis._EDGE_STORE_LOGGER;
226
+ log.debug('Running [confirmUpload]', { bucketName, url });
197
227
  if (!ctxToken) {
198
228
  throw new EdgeStoreError({
199
229
  message: 'Missing edgestore-ctx cookie',
@@ -203,15 +233,22 @@ async function confirmUpload(params) {
203
233
  await getContext(ctxToken); // just to check if the token is valid
204
234
  const bucket = router.buckets[bucketName];
205
235
  if (!bucket) {
206
- throw new Error(`Bucket ${bucketName} not found`);
236
+ throw new EdgeStoreError({
237
+ message: `Bucket ${bucketName} not found`,
238
+ code: 'BAD_REQUEST',
239
+ });
207
240
  }
208
- return await provider.confirmUpload({
241
+ const res = await provider.confirmUpload({
209
242
  bucket,
210
243
  url: unproxyUrl(url),
211
244
  });
245
+ log.debug('Finished [confirmUpload]');
246
+ return res;
212
247
  }
213
248
  async function deleteFile(params) {
214
249
  const { provider, router, ctxToken, body: { bucketName, url }, } = params;
250
+ const log = globalThis._EDGE_STORE_LOGGER;
251
+ log.debug('Running [deleteFile]', { bucketName, url });
215
252
  if (!ctxToken) {
216
253
  throw new EdgeStoreError({
217
254
  message: 'Missing edgestore-ctx cookie',
@@ -221,30 +258,44 @@ async function deleteFile(params) {
221
258
  const ctx = await getContext(ctxToken);
222
259
  const bucket = router.buckets[bucketName];
223
260
  if (!bucket) {
224
- throw new Error(`Bucket ${bucketName} not found`);
261
+ throw new EdgeStoreError({
262
+ message: `Bucket ${bucketName} not found`,
263
+ code: 'BAD_REQUEST',
264
+ });
225
265
  }
226
266
  if (!bucket._def.beforeDelete) {
227
- throw new Error('You need to define beforeDelete if you want to delete files directly from the frontend.');
267
+ throw new EdgeStoreError({
268
+ message: 'You need to define beforeDelete if you want to delete files directly from the frontend.',
269
+ code: 'SERVER_ERROR',
270
+ });
228
271
  }
229
272
  const fileInfo = await provider.getFile({
230
- url,
273
+ url: unproxyUrl(url),
231
274
  });
232
275
  const canDelete = await bucket._def.beforeDelete({
233
276
  ctx,
234
277
  fileInfo,
235
278
  });
236
279
  if (!canDelete) {
237
- throw new Error('Delete not allowed');
280
+ throw new EdgeStoreError({
281
+ message: 'Delete not allowed for the current context',
282
+ code: 'DELETE_NOT_ALLOWED',
283
+ });
238
284
  }
239
- return await provider.deleteFile({
285
+ const res = await provider.deleteFile({
240
286
  bucket,
241
287
  url: unproxyUrl(url),
242
288
  });
289
+ log.debug('Finished [deleteFile]');
290
+ return res;
243
291
  }
244
292
  async function encryptJWT(ctx) {
245
293
  const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
246
294
  if (!secret) {
247
- throw new Error('EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined');
295
+ throw new EdgeStoreError({
296
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
297
+ code: 'SERVER_ERROR',
298
+ });
248
299
  }
249
300
  const encryptionSecret = await getDerivedEncryptionKey(secret);
250
301
  return await new EncryptJWT(ctx)
@@ -257,7 +308,10 @@ async function encryptJWT(ctx) {
257
308
  async function decryptJWT(token) {
258
309
  const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
259
310
  if (!secret) {
260
- throw new Error('EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not set');
311
+ throw new EdgeStoreError({
312
+ message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
313
+ code: 'SERVER_ERROR',
314
+ });
261
315
  }
262
316
  const encryptionSecret = await getDerivedEncryptionKey(secret);
263
317
  const { payload } = await jwtDecrypt(token, encryptionSecret, {
@@ -274,7 +328,10 @@ function buildPath(params) {
274
328
  const path = pathParams.map((param) => {
275
329
  const paramEntries = Object.entries(param);
276
330
  if (paramEntries[0] === undefined) {
277
- throw new Error('Missing path param');
331
+ throw new EdgeStoreError({
332
+ message: `Empty path param found in: ${JSON.stringify(pathParams)}`,
333
+ code: 'SERVER_ERROR',
334
+ });
278
335
  }
279
336
  const [key, value] = paramEntries[0];
280
337
  // this is a string like: "ctx.xxx" or "input.yyy.zzz"
@@ -282,7 +339,10 @@ function buildPath(params) {
282
339
  .split('.')
283
340
  .reduce((acc2, key) => {
284
341
  if (acc2[key] === undefined) {
285
- throw new Error(`Missing key ${key} in ${JSON.stringify(acc2)}`);
342
+ throw new EdgeStoreError({
343
+ message: `Missing key ${key} in ${JSON.stringify(acc2)}`,
344
+ code: 'BAD_REQUEST',
345
+ });
286
346
  }
287
347
  return acc2[key];
288
348
  }, params.pathAttrs);
@@ -293,10 +353,18 @@ function buildPath(params) {
293
353
  });
294
354
  return path;
295
355
  }
356
+ function parsePath(path) {
357
+ const parsedPath = path.reduce((acc, curr) => {
358
+ acc[curr.key] = curr.value;
359
+ return acc;
360
+ }, {});
361
+ const pathOrder = path.map((p) => p.key);
362
+ return {
363
+ parsedPath,
364
+ pathOrder,
365
+ };
366
+ }
296
367
  async function getContext(token) {
297
- if (!token) {
298
- throw new Error('No token');
299
- }
300
368
  return await decryptJWT(token);
301
369
  }
302
370
  /**
@@ -317,4 +385,4 @@ function unproxyUrl(url) {
317
385
  return url;
318
386
  }
319
387
 
320
- export { EdgeStoreError as E, requestUploadParts as a, confirmUpload as b, completeMultipartUpload as c, deleteFile as d, EDGE_STORE_ERROR_CODES as e, init as i, requestUpload as r };
388
+ 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 };