@edgestore/server 0.4.0 → 0.5.1

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 (69) hide show
  1. package/adapters/astro/index.d.ts +1 -0
  2. package/adapters/astro/index.js +1 -0
  3. package/adapters/hono/index.d.ts +1 -0
  4. package/adapters/hono/index.js +1 -0
  5. package/adapters/remix/index.d.ts +1 -0
  6. package/adapters/remix/index.js +1 -0
  7. package/dist/adapters/astro/index.d.ts +14 -0
  8. package/dist/adapters/astro/index.d.ts.map +1 -0
  9. package/dist/adapters/astro/index.js +183 -0
  10. package/dist/adapters/astro/index.mjs +179 -0
  11. package/dist/adapters/express/index.js +3 -3
  12. package/dist/adapters/express/index.mjs +3 -3
  13. package/dist/adapters/fastify/index.js +3 -3
  14. package/dist/adapters/fastify/index.mjs +3 -3
  15. package/dist/adapters/hono/index.d.ts +82 -0
  16. package/dist/adapters/hono/index.d.ts.map +1 -0
  17. package/dist/adapters/hono/index.js +137 -0
  18. package/dist/adapters/hono/index.mjs +133 -0
  19. package/dist/adapters/next/app/index.js +3 -3
  20. package/dist/adapters/next/app/index.mjs +3 -3
  21. package/dist/adapters/next/pages/index.js +3 -3
  22. package/dist/adapters/next/pages/index.mjs +3 -3
  23. package/dist/adapters/remix/index.d.ts +18 -0
  24. package/dist/adapters/remix/index.d.ts.map +1 -0
  25. package/dist/adapters/remix/index.js +158 -0
  26. package/dist/adapters/remix/index.mjs +154 -0
  27. package/dist/adapters/shared.d.ts +2 -0
  28. package/dist/adapters/shared.d.ts.map +1 -1
  29. package/dist/adapters/start/index.js +3 -3
  30. package/dist/adapters/start/index.mjs +3 -3
  31. package/dist/core/index.js +3 -3
  32. package/dist/core/index.mjs +4 -4
  33. package/dist/core/sdk/index.d.ts.map +1 -1
  34. package/dist/{index-a7cc3cd3.mjs → index-2848cb40.mjs} +3 -2
  35. package/dist/{index-474a21c4.js → index-421c502f.js} +3 -2
  36. package/dist/{index-b689bf59.js → index-7b259533.js} +5 -4
  37. package/dist/libs/logger.d.ts +1 -1
  38. package/dist/libs/logger.d.ts.map +1 -1
  39. package/dist/providers/aws/index.d.ts +15 -1
  40. package/dist/providers/aws/index.d.ts.map +1 -1
  41. package/dist/providers/aws/index.js +28 -8
  42. package/dist/providers/aws/index.mjs +28 -8
  43. package/dist/providers/azure/index.d.ts.map +1 -1
  44. package/dist/providers/azure/index.js +6 -1
  45. package/dist/providers/azure/index.mjs +6 -1
  46. package/dist/providers/edgestore/index.d.ts.map +1 -1
  47. package/dist/providers/edgestore/index.js +13 -6
  48. package/dist/providers/edgestore/index.mjs +10 -3
  49. package/dist/{shared-d27101a7.js → shared-25dbfab4.js} +17 -4
  50. package/dist/{shared-c9442cbb.mjs → shared-4b199b96.mjs} +16 -4
  51. package/dist/{shared-6f6fd0bd.js → shared-685c8a0c.js} +17 -3
  52. package/dist/{utils-5819d5e1.js → utils-0aab6e3b.js} +3 -1
  53. package/dist/{utils-f6f56d38.mjs → utils-7349adab.mjs} +3 -1
  54. package/dist/{utils-461a2e3b.js → utils-b3d35894.js} +3 -2
  55. package/package.json +20 -3
  56. package/src/adapters/astro/index.ts +222 -0
  57. package/src/adapters/hono/index.ts +195 -0
  58. package/src/adapters/remix/index.ts +201 -0
  59. package/src/adapters/shared.ts +20 -3
  60. package/src/core/client/index.ts +2 -2
  61. package/src/core/sdk/index.ts +4 -3
  62. package/src/libs/logger.ts +4 -3
  63. package/src/providers/aws/index.ts +66 -14
  64. package/src/providers/azure/index.ts +5 -4
  65. package/src/providers/edgestore/index.ts +8 -3
  66. package/adapters/index.d.ts +0 -1
  67. package/adapters/index.js +0 -1
  68. package/providers/index.d.ts +0 -1
  69. package/providers/index.js +0 -1
@@ -321,7 +321,7 @@ async function deleteFile(params) {
321
321
  return res;
322
322
  }
323
323
  async function encryptJWT(ctx) {
324
- const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
324
+ const secret = getEnv('EDGE_STORE_JWT_SECRET') ?? getEnv('EDGE_STORE_SECRET_KEY');
325
325
  if (!secret) {
326
326
  throw new shared.EdgeStoreError({
327
327
  message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
@@ -335,7 +335,7 @@ async function encryptJWT(ctx) {
335
335
  }).setIssuedAt().setExpirationTime(Date.now() / 1000 + DEFAULT_MAX_AGE).setJti(uuid.v4()).encrypt(encryptionSecret);
336
336
  }
337
337
  async function decryptJWT(token) {
338
- const secret = process.env.EDGE_STORE_JWT_SECRET ?? process.env.EDGE_STORE_SECRET_KEY;
338
+ const secret = getEnv('EDGE_STORE_JWT_SECRET') ?? getEnv('EDGE_STORE_SECRET_KEY');
339
339
  if (!secret) {
340
340
  throw new shared.EdgeStoreError({
341
341
  message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
@@ -401,7 +401,7 @@ async function getContext(token) {
401
401
  * This function is used to get the original URL,
402
402
  * so that we can delete or confirm the upload.
403
403
  */ function unproxyUrl(url) {
404
- if (process.env.NODE_ENV === 'development' && url.startsWith('http://')) {
404
+ if (isDev() && url.startsWith('http://')) {
405
405
  // get the url param from the query string
406
406
  const urlParam = new URL(url).searchParams.get('url');
407
407
  if (urlParam) {
@@ -410,12 +410,26 @@ async function getContext(token) {
410
410
  }
411
411
  return url;
412
412
  }
413
+ function getEnv(key) {
414
+ if (typeof process !== 'undefined' && process.env) {
415
+ // @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
416
+ return process.env[key] ?? undefined?.[key];
417
+ }
418
+ // @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
419
+ return undefined?.[key];
420
+ }
421
+ function isDev() {
422
+ return process?.env?.NODE_ENV === 'development' || // @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
423
+ undefined?.DEV;
424
+ }
413
425
 
414
426
  exports.buildPath = buildPath;
415
427
  exports.completeMultipartUpload = completeMultipartUpload;
416
428
  exports.confirmUpload = confirmUpload;
417
429
  exports.deleteFile = deleteFile;
430
+ exports.getEnv = getEnv;
418
431
  exports.init = init;
432
+ exports.isDev = isDev;
419
433
  exports.parsePath = parsePath;
420
434
  exports.requestUpload = requestUpload;
421
435
  exports.requestUploadParts = requestUploadParts;
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var shared = require('./shared-685c8a0c.js');
4
+
3
5
  /* eslint-disable no-console */ function _define_property(obj, key, value) {
4
6
  if (key in obj) {
5
7
  Object.defineProperty(obj, key, {
@@ -46,7 +48,7 @@ class Logger {
46
48
  }
47
49
  constructor(logLevel){
48
50
  _define_property(this, "logLevel", void 0);
49
- this.logLevel = logLevel ?? (process.env.NODE_ENV === 'production' ? 'error' : 'info');
51
+ this.logLevel = logLevel ?? (shared.isDev() ? 'info' : 'error');
50
52
  }
51
53
  }
52
54
 
@@ -1,3 +1,5 @@
1
+ import { i as isDev } from './shared-4b199b96.mjs';
2
+
1
3
  /* eslint-disable no-console */ function _define_property(obj, key, value) {
2
4
  if (key in obj) {
3
5
  Object.defineProperty(obj, key, {
@@ -44,7 +46,7 @@ class Logger {
44
46
  }
45
47
  constructor(logLevel){
46
48
  _define_property(this, "logLevel", void 0);
47
- this.logLevel = logLevel ?? (process.env.NODE_ENV === 'production' ? 'error' : 'info');
49
+ this.logLevel = logLevel ?? (isDev() ? 'info' : 'error');
48
50
  }
49
51
  }
50
52
 
@@ -1,9 +1,10 @@
1
+ import { i as isDev } from './shared-25dbfab4.js';
2
+
1
3
  /* eslint-disable no-console */
2
4
  const logLevel = ['debug', 'info', 'warn', 'error', 'none'];
3
5
  class Logger {
4
6
  constructor(logLevel) {
5
- this.logLevel =
6
- logLevel ?? (process.env.NODE_ENV === 'production' ? 'error' : 'info');
7
+ this.logLevel = logLevel ?? (isDev() ? 'info' : 'error');
7
8
  }
8
9
  shouldLog(level) {
9
10
  return logLevel.indexOf(level) >= logLevel.indexOf(this.logLevel);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edgestore/server",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
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",
@@ -37,6 +37,11 @@
37
37
  "require": "./dist/core/index.js",
38
38
  "default": "./dist/core/index.js"
39
39
  },
40
+ "./adapters/astro": {
41
+ "import": "./dist/adapters/astro/index.mjs",
42
+ "require": "./dist/adapters/astro/index.js",
43
+ "default": "./dist/adapters/astro/index.js"
44
+ },
40
45
  "./adapters/express": {
41
46
  "import": "./dist/adapters/express/index.mjs",
42
47
  "require": "./dist/adapters/express/index.js",
@@ -47,6 +52,11 @@
47
52
  "require": "./dist/adapters/fastify/index.js",
48
53
  "default": "./dist/adapters/fastify/index.js"
49
54
  },
55
+ "./adapters/hono": {
56
+ "import": "./dist/adapters/hono/index.mjs",
57
+ "require": "./dist/adapters/hono/index.js",
58
+ "default": "./dist/adapters/hono/index.js"
59
+ },
50
60
  "./adapters/next/pages": {
51
61
  "import": "./dist/adapters/next/pages/index.mjs",
52
62
  "require": "./dist/adapters/next/pages/index.js",
@@ -57,6 +67,11 @@
57
67
  "require": "./dist/adapters/next/app/index.js",
58
68
  "default": "./dist/adapters/next/app/index.js"
59
69
  },
70
+ "./adapters/remix": {
71
+ "import": "./dist/adapters/remix/index.mjs",
72
+ "require": "./dist/adapters/remix/index.js",
73
+ "default": "./dist/adapters/remix/index.js"
74
+ },
60
75
  "./adapters/start": {
61
76
  "import": "./dist/adapters/start/index.mjs",
62
77
  "require": "./dist/adapters/start/index.js",
@@ -94,7 +109,7 @@
94
109
  },
95
110
  "license": "MIT",
96
111
  "dependencies": {
97
- "@edgestore/shared": "0.4.0",
112
+ "@edgestore/shared": "0.5.1",
98
113
  "@panva/hkdf": "^1.0.4",
99
114
  "cookie": "^0.5.0",
100
115
  "jose": "^4.13.1",
@@ -127,12 +142,14 @@
127
142
  "@types/cookie": "^0.5.1",
128
143
  "@types/node": "^20",
129
144
  "@types/uuid": "^9.0.1",
145
+ "astro": "^5.7.12",
130
146
  "fastify": "^5.3.2",
147
+ "hono": "^4.7.9",
131
148
  "next": "^15.2.4",
132
149
  "react": "^19.0.0",
133
150
  "react-dom": "^19.0.0",
134
151
  "typescript": "^5",
135
152
  "zod": "3.21.4"
136
153
  },
137
- "gitHead": "63d6ba86e038a61bfbf506385183482c91e80842"
154
+ "gitHead": "0a04ff24dfb62f749cc970794b3d239c75f48fed"
138
155
  }
@@ -0,0 +1,222 @@
1
+ import {
2
+ EDGE_STORE_ERROR_CODES,
3
+ EdgeStoreError,
4
+ type EdgeStoreErrorCodeKey,
5
+ type EdgeStoreRouter,
6
+ type MaybePromise,
7
+ type Provider,
8
+ } from '@edgestore/shared';
9
+ import type { APIContext } from 'astro';
10
+ import Logger, { type LogLevel } from '../../libs/logger';
11
+ import { matchPath } from '../../libs/utils';
12
+ import { EdgeStoreProvider } from '../../providers/edgestore';
13
+ import {
14
+ completeMultipartUpload,
15
+ confirmUpload,
16
+ deleteFile,
17
+ init,
18
+ requestUpload,
19
+ requestUploadParts,
20
+ type CompleteMultipartUploadBody,
21
+ type ConfirmUploadBody,
22
+ type DeleteFileBody,
23
+ type RequestUploadBody,
24
+ type RequestUploadPartsParams,
25
+ } from '../shared';
26
+
27
+ export type Config<TCtx> = {
28
+ provider?: Provider;
29
+ router: EdgeStoreRouter<TCtx>;
30
+ logLevel?: LogLevel;
31
+ } & (TCtx extends Record<string, never>
32
+ ? object
33
+ : {
34
+ provider?: Provider;
35
+ router: EdgeStoreRouter<TCtx>;
36
+ createContext: (opts: APIContext) => MaybePromise<TCtx>;
37
+ });
38
+
39
+ declare const globalThis: {
40
+ _EDGE_STORE_LOGGER: Logger;
41
+ };
42
+
43
+ // Helper to safely get cookies from Astro request
44
+ function getCookie(request: Request, name: string): string | undefined {
45
+ const cookieHeader = request.headers.get('cookie');
46
+ if (!cookieHeader) return undefined;
47
+
48
+ const cookies = cookieHeader
49
+ .split(';')
50
+ .reduce<Record<string, string>>((acc, cookie) => {
51
+ const [key, value] = cookie.trim().split('=');
52
+ if (key && value) acc[key] = value;
53
+ return acc;
54
+ }, {});
55
+
56
+ return cookies[name];
57
+ }
58
+
59
+ export function createEdgeStoreAstroHandler<TCtx>(config: Config<TCtx>) {
60
+ const { provider = EdgeStoreProvider() } = config;
61
+ const log = new Logger(config.logLevel);
62
+ globalThis._EDGE_STORE_LOGGER = log;
63
+ log.debug('Creating EdgeStore Astro handler');
64
+
65
+ return async (context: APIContext) => {
66
+ try {
67
+ const { request } = context;
68
+ const url = new URL(request.url);
69
+
70
+ if (matchPath(url.pathname, 'health')) {
71
+ return new Response('OK');
72
+ } else if (matchPath(url.pathname, 'init')) {
73
+ let ctx = {} as TCtx;
74
+ try {
75
+ ctx =
76
+ 'createContext' in config
77
+ ? await config.createContext(context)
78
+ : ({} as TCtx);
79
+ } catch (err) {
80
+ throw new EdgeStoreError({
81
+ message: 'Error creating context',
82
+ code: 'CREATE_CONTEXT_ERROR',
83
+ cause: err instanceof Error ? err : undefined,
84
+ });
85
+ }
86
+ const { newCookies, token, baseUrl } = await init({
87
+ ctx,
88
+ provider,
89
+ router: config.router,
90
+ });
91
+
92
+ const headers = new Headers();
93
+ headers.set('Content-Type', 'application/json');
94
+
95
+ // Set cookies
96
+ if (Array.isArray(newCookies)) {
97
+ for (const cookie of newCookies) {
98
+ headers.append('Set-Cookie', cookie);
99
+ }
100
+ } else if (newCookies) {
101
+ headers.append('Set-Cookie', newCookies);
102
+ }
103
+
104
+ return new Response(
105
+ JSON.stringify({
106
+ token,
107
+ baseUrl,
108
+ }),
109
+ { headers },
110
+ );
111
+ } else if (matchPath(url.pathname, 'request-upload')) {
112
+ const body = (await request.json()) as RequestUploadBody;
113
+ const result = await requestUpload({
114
+ provider,
115
+ router: config.router,
116
+ body,
117
+ ctxToken: getCookie(request, 'edgestore-ctx'),
118
+ });
119
+
120
+ return new Response(JSON.stringify(result), {
121
+ headers: { 'Content-Type': 'application/json' },
122
+ });
123
+ } else if (matchPath(url.pathname, 'request-upload-parts')) {
124
+ const body = (await request.json()) as RequestUploadPartsParams;
125
+ const result = await requestUploadParts({
126
+ provider,
127
+ router: config.router,
128
+ body,
129
+ ctxToken: getCookie(request, 'edgestore-ctx'),
130
+ });
131
+
132
+ return new Response(JSON.stringify(result), {
133
+ headers: { 'Content-Type': 'application/json' },
134
+ });
135
+ } else if (matchPath(url.pathname, 'complete-multipart-upload')) {
136
+ const body = (await request.json()) as CompleteMultipartUploadBody;
137
+ await completeMultipartUpload({
138
+ provider,
139
+ router: config.router,
140
+ body,
141
+ ctxToken: getCookie(request, 'edgestore-ctx'),
142
+ });
143
+
144
+ return new Response(null, { status: 200 });
145
+ } else if (matchPath(url.pathname, 'confirm-upload')) {
146
+ const body = (await request.json()) as ConfirmUploadBody;
147
+ const result = await confirmUpload({
148
+ provider,
149
+ router: config.router,
150
+ body,
151
+ ctxToken: getCookie(request, 'edgestore-ctx'),
152
+ });
153
+
154
+ return new Response(JSON.stringify(result), {
155
+ headers: { 'Content-Type': 'application/json' },
156
+ });
157
+ } else if (matchPath(url.pathname, 'delete-file')) {
158
+ const body = (await request.json()) as DeleteFileBody;
159
+ const result = await deleteFile({
160
+ provider,
161
+ router: config.router,
162
+ body,
163
+ ctxToken: getCookie(request, 'edgestore-ctx'),
164
+ });
165
+
166
+ return new Response(JSON.stringify(result), {
167
+ headers: { 'Content-Type': 'application/json' },
168
+ });
169
+ } else if (matchPath(url.pathname, 'proxy-file')) {
170
+ const url = new URL(request.url).searchParams.get('url');
171
+
172
+ if (typeof url === 'string') {
173
+ const cookieHeader = request.headers.get('cookie') ?? '';
174
+
175
+ const proxyRes = await fetch(url, {
176
+ headers: {
177
+ cookie: cookieHeader,
178
+ },
179
+ });
180
+
181
+ const data = await proxyRes.arrayBuffer();
182
+ const headers = new Headers();
183
+ headers.set(
184
+ 'Content-Type',
185
+ proxyRes.headers.get('Content-Type') ?? 'application/octet-stream',
186
+ );
187
+
188
+ return new Response(data, { headers });
189
+ } else {
190
+ return new Response(null, { status: 400 });
191
+ }
192
+ } else {
193
+ return new Response(null, { status: 404 });
194
+ }
195
+ } catch (err) {
196
+ if (err instanceof EdgeStoreError) {
197
+ log[err.level](err.formattedMessage());
198
+ if (err.cause) log[err.level](err.cause);
199
+
200
+ return new Response(JSON.stringify(err.formattedJson()), {
201
+ status: EDGE_STORE_ERROR_CODES[err.code as EdgeStoreErrorCodeKey],
202
+ headers: { 'Content-Type': 'application/json' },
203
+ });
204
+ } else {
205
+ log.error(err);
206
+
207
+ return new Response(
208
+ JSON.stringify(
209
+ new EdgeStoreError({
210
+ message: 'Internal Server Error',
211
+ code: 'SERVER_ERROR',
212
+ }).formattedJson(),
213
+ ),
214
+ {
215
+ status: 500,
216
+ headers: { 'Content-Type': 'application/json' },
217
+ },
218
+ );
219
+ }
220
+ }
221
+ };
222
+ }
@@ -0,0 +1,195 @@
1
+ import {
2
+ EDGE_STORE_ERROR_CODES,
3
+ EdgeStoreError,
4
+ type EdgeStoreErrorCodeKey,
5
+ type EdgeStoreRouter,
6
+ type MaybePromise,
7
+ type Provider,
8
+ } from '@edgestore/shared';
9
+ import { type Context } from 'hono';
10
+ import Logger, { type LogLevel } from '../../libs/logger';
11
+ import { matchPath } from '../../libs/utils';
12
+ import { EdgeStoreProvider } from '../../providers/edgestore';
13
+ import {
14
+ completeMultipartUpload,
15
+ confirmUpload,
16
+ deleteFile,
17
+ init,
18
+ requestUpload,
19
+ requestUploadParts,
20
+ type CompleteMultipartUploadBody,
21
+ type ConfirmUploadBody,
22
+ type DeleteFileBody,
23
+ type RequestUploadBody,
24
+ type RequestUploadPartsParams,
25
+ } from '../shared';
26
+
27
+ export type CreateContextOptions = {
28
+ c: Context;
29
+ };
30
+
31
+ export type Config<TCtx> = {
32
+ provider?: Provider;
33
+ router: EdgeStoreRouter<TCtx>;
34
+ logLevel?: LogLevel;
35
+ } & (TCtx extends Record<string, never>
36
+ ? object
37
+ : {
38
+ provider?: Provider;
39
+ router: EdgeStoreRouter<TCtx>;
40
+ createContext: (opts: CreateContextOptions) => MaybePromise<TCtx>;
41
+ });
42
+
43
+ declare const globalThis: {
44
+ _EDGE_STORE_LOGGER: Logger;
45
+ };
46
+
47
+ // Helper to get a cookie value from Hono Context
48
+ function getCookie(c: Context, name: string): string | undefined {
49
+ const cookies = c.req.header('cookie');
50
+ if (!cookies) return undefined;
51
+
52
+ const match = new RegExp(`${name}=([^;]+)`).exec(cookies);
53
+ return match ? match[1] : undefined;
54
+ }
55
+
56
+ export function createEdgeStoreHonoHandler<TCtx>(config: Config<TCtx>) {
57
+ const { provider = EdgeStoreProvider() } = config;
58
+ const log = new Logger(config.logLevel);
59
+ globalThis._EDGE_STORE_LOGGER = log;
60
+ log.debug('Creating EdgeStore Hono handler');
61
+
62
+ return async (c: Context) => {
63
+ try {
64
+ const pathname = new URL(c.req.url).pathname;
65
+
66
+ if (matchPath(pathname, '/health')) {
67
+ return c.text('OK');
68
+ } else if (matchPath(pathname, '/init')) {
69
+ let ctx = {} as TCtx;
70
+ try {
71
+ ctx =
72
+ 'createContext' in config
73
+ ? await config.createContext({ c })
74
+ : ({} as TCtx);
75
+ } catch (err) {
76
+ throw new EdgeStoreError({
77
+ message: 'Error creating context',
78
+ code: 'CREATE_CONTEXT_ERROR',
79
+ cause: err instanceof Error ? err : undefined,
80
+ });
81
+ }
82
+ const { newCookies, token, baseUrl } = await init({
83
+ ctx,
84
+ provider,
85
+ router: config.router,
86
+ });
87
+
88
+ // Set cookies
89
+ if (Array.isArray(newCookies)) {
90
+ for (const cookie of newCookies) {
91
+ c.header('Set-Cookie', cookie);
92
+ }
93
+ } else if (newCookies) {
94
+ c.header('Set-Cookie', newCookies);
95
+ }
96
+
97
+ return c.json({
98
+ token,
99
+ baseUrl,
100
+ });
101
+ } else if (matchPath(pathname, '/request-upload')) {
102
+ const body = await c.req.json<RequestUploadBody>();
103
+ return c.json(
104
+ await requestUpload({
105
+ provider,
106
+ router: config.router,
107
+ body,
108
+ ctxToken: getCookie(c, 'edgestore-ctx'),
109
+ }),
110
+ );
111
+ } else if (matchPath(pathname, '/request-upload-parts')) {
112
+ const body = await c.req.json<RequestUploadPartsParams>();
113
+ return c.json(
114
+ await requestUploadParts({
115
+ provider,
116
+ router: config.router,
117
+ body,
118
+ ctxToken: getCookie(c, 'edgestore-ctx'),
119
+ }),
120
+ );
121
+ } else if (matchPath(pathname, '/complete-multipart-upload')) {
122
+ const body = await c.req.json<CompleteMultipartUploadBody>();
123
+ await completeMultipartUpload({
124
+ provider,
125
+ router: config.router,
126
+ body,
127
+ ctxToken: getCookie(c, 'edgestore-ctx'),
128
+ });
129
+ return c.body(null, 200);
130
+ } else if (matchPath(pathname, '/confirm-upload')) {
131
+ const body = await c.req.json<ConfirmUploadBody>();
132
+ return c.json(
133
+ await confirmUpload({
134
+ provider,
135
+ router: config.router,
136
+ body,
137
+ ctxToken: getCookie(c, 'edgestore-ctx'),
138
+ }),
139
+ );
140
+ } else if (matchPath(pathname, '/delete-file')) {
141
+ const body = await c.req.json<DeleteFileBody>();
142
+ return c.json(
143
+ await deleteFile({
144
+ provider,
145
+ router: config.router,
146
+ body,
147
+ ctxToken: getCookie(c, 'edgestore-ctx'),
148
+ }),
149
+ );
150
+ } else if (matchPath(pathname, '/proxy-file')) {
151
+ const url = c.req.query('url');
152
+
153
+ if (typeof url === 'string') {
154
+ const cookieHeader = c.req.header('cookie') ?? '';
155
+
156
+ const proxyRes = await fetch(url, {
157
+ headers: {
158
+ cookie: cookieHeader,
159
+ },
160
+ });
161
+
162
+ const data = await proxyRes.arrayBuffer();
163
+ c.header(
164
+ 'Content-Type',
165
+ proxyRes.headers.get('Content-Type') ?? 'application/octet-stream',
166
+ );
167
+
168
+ return c.body(Buffer.from(data));
169
+ } else {
170
+ return c.body(null, 400);
171
+ }
172
+ } else {
173
+ return c.body(null, 404);
174
+ }
175
+ } catch (err) {
176
+ if (err instanceof EdgeStoreError) {
177
+ log[err.level](err.formattedMessage());
178
+ if (err.cause) log[err.level](err.cause);
179
+ return c.json(
180
+ err.formattedJson(),
181
+ EDGE_STORE_ERROR_CODES[err.code as EdgeStoreErrorCodeKey],
182
+ );
183
+ } else {
184
+ log.error(err);
185
+ return c.json(
186
+ new EdgeStoreError({
187
+ message: 'Internal Server Error',
188
+ code: 'SERVER_ERROR',
189
+ }).formattedJson(),
190
+ 500,
191
+ );
192
+ }
193
+ }
194
+ };
195
+ }