r2-explorer 1.1.9 → 1.1.11

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 (30) hide show
  1. package/README.md +1 -0
  2. package/dashboard/assets/{AuthLayout.d454e332.js → AuthLayout.0d7701f7.js} +1 -1
  3. package/dashboard/assets/EmailFilePage.12cbd72f.js +2 -0
  4. package/dashboard/assets/ErrorNotFound.edf4fcea.js +1 -0
  5. package/dashboard/{spa/assets/LoginPage.2c31ddaf.js → assets/LoginPage.55d653ae.js} +1 -1
  6. package/dashboard/assets/{auth-store.963af64d.js → auth-store.a55ef8b1.js} +1 -1
  7. package/dashboard/assets/{auth.e9ee4208.js → auth.7340ecd2.js} +1 -1
  8. package/dashboard/assets/{bus.c615343c.js → bus.88084376.js} +1 -1
  9. package/dashboard/assets/{index.9da34366.css → index.4aacbd79.css} +1 -1
  10. package/dashboard/assets/{index.0de893af.js → index.a267d362.js} +40 -40
  11. package/dashboard/index.html +2 -2
  12. package/dashboard/spa/assets/{AuthLayout.d454e332.js → AuthLayout.0d7701f7.js} +1 -1
  13. package/dashboard/spa/assets/EmailFilePage.12cbd72f.js +2 -0
  14. package/dashboard/spa/assets/ErrorNotFound.edf4fcea.js +1 -0
  15. package/dashboard/{assets/LoginPage.2c31ddaf.js → spa/assets/LoginPage.55d653ae.js} +1 -1
  16. package/dashboard/spa/assets/{auth-store.963af64d.js → auth-store.a55ef8b1.js} +1 -1
  17. package/dashboard/spa/assets/{auth.e9ee4208.js → auth.7340ecd2.js} +1 -1
  18. package/dashboard/spa/assets/{bus.c615343c.js → bus.88084376.js} +1 -1
  19. package/dashboard/spa/assets/{index.9da34366.css → index.4aacbd79.css} +1 -1
  20. package/dashboard/spa/assets/{index.0de893af.js → index.a267d362.js} +40 -40
  21. package/dashboard/spa/index.html +2 -2
  22. package/dist/index.d.mts +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +792 -454
  25. package/dist/index.mjs +782 -444
  26. package/package.json +15 -15
  27. package/dashboard/assets/EmailFilePage.f5aef278.js +0 -2
  28. package/dashboard/assets/ErrorNotFound.9c1a500d.js +0 -1
  29. package/dashboard/spa/assets/EmailFilePage.f5aef278.js +0 -2
  30. package/dashboard/spa/assets/ErrorNotFound.9c1a500d.js +0 -1
package/dist/index.mjs CHANGED
@@ -5,7 +5,77 @@ import {
5
5
  fromHono
6
6
  } from "chanfana";
7
7
 
8
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/body.js
8
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/compose.js
9
+ var compose = (middleware, onError, onNotFound) => {
10
+ return (context, next) => {
11
+ let index = -1;
12
+ return dispatch(0);
13
+ async function dispatch(i) {
14
+ if (i <= index) {
15
+ throw new Error("next() called multiple times");
16
+ }
17
+ index = i;
18
+ let res;
19
+ let isError = false;
20
+ let handler;
21
+ if (middleware[i]) {
22
+ handler = middleware[i][0][0];
23
+ context.req.routeIndex = i;
24
+ } else {
25
+ handler = i === middleware.length && next || void 0;
26
+ }
27
+ if (handler) {
28
+ try {
29
+ res = await handler(context, () => dispatch(i + 1));
30
+ } catch (err) {
31
+ if (err instanceof Error && onError) {
32
+ context.error = err;
33
+ res = await onError(err, context);
34
+ isError = true;
35
+ } else {
36
+ throw err;
37
+ }
38
+ }
39
+ } else {
40
+ if (context.finalized === false && onNotFound) {
41
+ res = await onNotFound(context);
42
+ }
43
+ }
44
+ if (res && (context.finalized === false || isError)) {
45
+ context.res = res;
46
+ }
47
+ return context;
48
+ }
49
+ };
50
+ };
51
+
52
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/http-exception.js
53
+ var HTTPException = class extends Error {
54
+ res;
55
+ status;
56
+ constructor(status = 500, options) {
57
+ super(options?.message, { cause: options?.cause });
58
+ this.res = options?.res;
59
+ this.status = status;
60
+ }
61
+ getResponse() {
62
+ if (this.res) {
63
+ const newResponse = new Response(this.res.body, {
64
+ status: this.status,
65
+ headers: this.res.headers
66
+ });
67
+ return newResponse;
68
+ }
69
+ return new Response(this.message, {
70
+ status: this.status
71
+ });
72
+ }
73
+ };
74
+
75
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/request/constants.js
76
+ var GET_MATCH_RESULT = Symbol();
77
+
78
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/body.js
9
79
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
10
80
  const { all = false, dot = false } = options;
11
81
  const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
@@ -52,7 +122,11 @@ var handleParsingAllValues = (form, key, value) => {
52
122
  form[key] = [form[key], value];
53
123
  }
54
124
  } else {
55
- form[key] = value;
125
+ if (!key.endsWith("[]")) {
126
+ form[key] = value;
127
+ } else {
128
+ form[key] = [value];
129
+ }
56
130
  }
57
131
  };
58
132
  var handleParsingNestedValues = (form, key, value) => {
@@ -70,7 +144,7 @@ var handleParsingNestedValues = (form, key, value) => {
70
144
  });
71
145
  };
72
146
 
73
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/url.js
147
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/url.js
74
148
  var splitPath = (path) => {
75
149
  const paths = path.split("/");
76
150
  if (paths[0] === "") {
@@ -85,9 +159,9 @@ var splitRoutingPath = (routePath) => {
85
159
  };
86
160
  var extractGroupsFromPath = (path) => {
87
161
  const groups = [];
88
- path = path.replace(/\{[^}]+\}/g, (match, index) => {
162
+ path = path.replace(/\{[^}]+\}/g, (match2, index) => {
89
163
  const mark = `@${index}`;
90
- groups.push([mark, match]);
164
+ groups.push([mark, match2]);
91
165
  return mark;
92
166
  });
93
167
  return { groups, path };
@@ -105,20 +179,21 @@ var replaceGroupMarks = (paths, groups) => {
105
179
  return paths;
106
180
  };
107
181
  var patternCache = {};
108
- var getPattern = (label) => {
182
+ var getPattern = (label, next) => {
109
183
  if (label === "*") {
110
184
  return "*";
111
185
  }
112
- const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
113
- if (match) {
114
- if (!patternCache[label]) {
115
- if (match[2]) {
116
- patternCache[label] = [label, match[1], new RegExp("^" + match[2] + "$")];
186
+ const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
187
+ if (match2) {
188
+ const cacheKey = `${label}#${next}`;
189
+ if (!patternCache[cacheKey]) {
190
+ if (match2[2]) {
191
+ patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)];
117
192
  } else {
118
- patternCache[label] = [label, match[1], true];
193
+ patternCache[cacheKey] = [label, match2[1], true];
119
194
  }
120
195
  }
121
- return patternCache[label];
196
+ return patternCache[cacheKey];
122
197
  }
123
198
  return null;
124
199
  };
@@ -126,11 +201,11 @@ var tryDecode = (str, decoder) => {
126
201
  try {
127
202
  return decoder(str);
128
203
  } catch {
129
- return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {
204
+ return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
130
205
  try {
131
- return decoder(match);
206
+ return decoder(match2);
132
207
  } catch {
133
- return match;
208
+ return match2;
134
209
  }
135
210
  });
136
211
  }
@@ -138,7 +213,7 @@ var tryDecode = (str, decoder) => {
138
213
  var tryDecodeURI = (str) => tryDecode(str, decodeURI);
139
214
  var getPath = (request) => {
140
215
  const url = request.url;
141
- const start = url.indexOf("/", 8);
216
+ const start = url.indexOf("/", url.indexOf(":") + 4);
142
217
  let i = start;
143
218
  for (; i < url.length; i++) {
144
219
  const charCode = url.charCodeAt(i);
@@ -156,30 +231,14 @@ var getPathNoStrict = (request) => {
156
231
  const result = getPath(request);
157
232
  return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
158
233
  };
159
- var mergePath = (...paths) => {
160
- let p = "";
161
- let endsWithSlash = false;
162
- for (let path of paths) {
163
- if (p.at(-1) === "/") {
164
- p = p.slice(0, -1);
165
- endsWithSlash = true;
166
- }
167
- if (path[0] !== "/") {
168
- path = `/${path}`;
169
- }
170
- if (path === "/" && endsWithSlash) {
171
- p = `${p}/`;
172
- } else if (path !== "/") {
173
- p = `${p}${path}`;
174
- }
175
- if (path === "/" && p === "") {
176
- p = "/";
177
- }
234
+ var mergePath = (base, sub, ...rest) => {
235
+ if (rest.length) {
236
+ sub = mergePath(sub, ...rest);
178
237
  }
179
- return p;
238
+ return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
180
239
  };
181
240
  var checkOptionalParameter = (path) => {
182
- if (!path.match(/\:.+\?$/)) {
241
+ if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) {
183
242
  return null;
184
243
  }
185
244
  const segments = path.split("/");
@@ -212,14 +271,17 @@ var _decodeURI = (value) => {
212
271
  if (value.indexOf("+") !== -1) {
213
272
  value = value.replace(/\+/g, " ");
214
273
  }
215
- return value.indexOf("%") !== -1 ? decodeURIComponent_(value) : value;
274
+ return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
216
275
  };
217
276
  var _getQueryParam = (url, key, multiple) => {
218
277
  let encoded;
219
278
  if (!multiple && key && !/[%+]/.test(key)) {
220
- let keyIndex2 = url.indexOf(`?${key}`, 8);
279
+ let keyIndex2 = url.indexOf("?", 8);
221
280
  if (keyIndex2 === -1) {
222
- keyIndex2 = url.indexOf(`&${key}`, 8);
281
+ return void 0;
282
+ }
283
+ if (!url.startsWith(key, keyIndex2 + 1)) {
284
+ keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
223
285
  }
224
286
  while (keyIndex2 !== -1) {
225
287
  const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
@@ -284,7 +346,7 @@ var getQueryParams = (url, key) => {
284
346
  };
285
347
  var decodeURIComponent_ = decodeURIComponent;
286
348
 
287
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/request.js
349
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/request.js
288
350
  var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
289
351
  var HonoRequest = class {
290
352
  raw;
@@ -305,14 +367,14 @@ var HonoRequest = class {
305
367
  #getDecodedParam(key) {
306
368
  const paramKey = this.#matchResult[0][this.routeIndex][1][key];
307
369
  const param = this.#getParamValue(paramKey);
308
- return param ? /\%/.test(param) ? tryDecodeURIComponent(param) : param : void 0;
370
+ return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
309
371
  }
310
372
  #getAllDecodedParams() {
311
373
  const decoded = {};
312
374
  const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
313
375
  for (const key of keys) {
314
376
  const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
315
- if (value && typeof value === "string") {
377
+ if (value !== void 0) {
316
378
  decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
317
379
  }
318
380
  }
@@ -329,7 +391,7 @@ var HonoRequest = class {
329
391
  }
330
392
  header(name) {
331
393
  if (name) {
332
- return this.raw.headers.get(name.toLowerCase()) ?? void 0;
394
+ return this.raw.headers.get(name) ?? void 0;
333
395
  }
334
396
  const headerData = {};
335
397
  this.raw.headers.forEach((value, key) => {
@@ -358,7 +420,7 @@ var HonoRequest = class {
358
420
  return bodyCache[key] = raw2[key]();
359
421
  };
360
422
  json() {
361
- return this.#cachedBody("json");
423
+ return this.#cachedBody("text").then((text) => JSON.parse(text));
362
424
  }
363
425
  text() {
364
426
  return this.#cachedBody("text");
@@ -384,6 +446,9 @@ var HonoRequest = class {
384
446
  get method() {
385
447
  return this.raw.method;
386
448
  }
449
+ get [GET_MATCH_RESULT]() {
450
+ return this.#matchResult;
451
+ }
387
452
  get matchedRoutes() {
388
453
  return this.#matchResult[0].map(([[, route]]) => route);
389
454
  }
@@ -392,7 +457,7 @@ var HonoRequest = class {
392
457
  }
393
458
  };
394
459
 
395
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/html.js
460
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/html.js
396
461
  var HtmlEscapedCallbackPhase = {
397
462
  Stringify: 1,
398
463
  BeforeStream: 2,
@@ -434,13 +499,13 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
434
499
  }
435
500
  };
436
501
 
437
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/context.js
502
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/context.js
438
503
  var TEXT_PLAIN = "text/plain; charset=UTF-8";
439
- var setHeaders = (headers, map = {}) => {
440
- for (const key of Object.keys(map)) {
441
- headers.set(key, map[key]);
442
- }
443
- return headers;
504
+ var setDefaultContentType = (contentType, headers) => {
505
+ return {
506
+ "Content-Type": contentType,
507
+ ...headers
508
+ };
444
509
  };
445
510
  var Context = class {
446
511
  #rawRequest;
@@ -449,15 +514,13 @@ var Context = class {
449
514
  #var;
450
515
  finalized = false;
451
516
  error;
452
- #status = 200;
517
+ #status;
453
518
  #executionCtx;
454
- #headers;
455
- #preparedHeaders;
456
519
  #res;
457
- #isFresh = true;
458
520
  #layout;
459
521
  #renderer;
460
522
  #notFoundHandler;
523
+ #preparedHeaders;
461
524
  #matchResult;
462
525
  #path;
463
526
  constructor(req, options) {
@@ -489,36 +552,25 @@ var Context = class {
489
552
  }
490
553
  }
491
554
  get res() {
492
- this.#isFresh = false;
493
- return this.#res ||= new Response("404 Not Found", { status: 404 });
555
+ return this.#res ||= new Response(null, {
556
+ headers: this.#preparedHeaders ??= new Headers()
557
+ });
494
558
  }
495
559
  set res(_res) {
496
- this.#isFresh = false;
497
560
  if (this.#res && _res) {
498
- try {
499
- for (const [k, v] of this.#res.headers.entries()) {
500
- if (k === "content-type") {
501
- continue;
502
- }
503
- if (k === "set-cookie") {
504
- const cookies = this.#res.headers.getSetCookie();
505
- _res.headers.delete("set-cookie");
506
- for (const cookie of cookies) {
507
- _res.headers.append("set-cookie", cookie);
508
- }
509
- } else {
510
- _res.headers.set(k, v);
511
- }
561
+ _res = new Response(_res.body, _res);
562
+ for (const [k, v] of this.#res.headers.entries()) {
563
+ if (k === "content-type") {
564
+ continue;
512
565
  }
513
- } catch (e) {
514
- if (e instanceof TypeError && e.message.includes("immutable")) {
515
- this.res = new Response(_res.body, {
516
- headers: _res.headers,
517
- status: _res.status
518
- });
519
- return;
566
+ if (k === "set-cookie") {
567
+ const cookies = this.#res.headers.getSetCookie();
568
+ _res.headers.delete("set-cookie");
569
+ for (const cookie of cookies) {
570
+ _res.headers.append("set-cookie", cookie);
571
+ }
520
572
  } else {
521
- throw e;
573
+ _res.headers.set(k, v);
522
574
  }
523
575
  }
524
576
  }
@@ -535,42 +587,19 @@ var Context = class {
535
587
  this.#renderer = renderer;
536
588
  };
537
589
  header = (name, value, options) => {
538
- if (value === void 0) {
539
- if (this.#headers) {
540
- this.#headers.delete(name);
541
- } else if (this.#preparedHeaders) {
542
- delete this.#preparedHeaders[name.toLocaleLowerCase()];
543
- }
544
- if (this.finalized) {
545
- this.res.headers.delete(name);
546
- }
547
- return;
590
+ if (this.finalized) {
591
+ this.#res = new Response(this.#res.body, this.#res);
548
592
  }
549
- if (options?.append) {
550
- if (!this.#headers) {
551
- this.#isFresh = false;
552
- this.#headers = new Headers(this.#preparedHeaders);
553
- this.#preparedHeaders = {};
554
- }
555
- this.#headers.append(name, value);
593
+ const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();
594
+ if (value === void 0) {
595
+ headers.delete(name);
596
+ } else if (options?.append) {
597
+ headers.append(name, value);
556
598
  } else {
557
- if (this.#headers) {
558
- this.#headers.set(name, value);
559
- } else {
560
- this.#preparedHeaders ??= {};
561
- this.#preparedHeaders[name.toLowerCase()] = value;
562
- }
563
- }
564
- if (this.finalized) {
565
- if (options?.append) {
566
- this.res.headers.append(name, value);
567
- } else {
568
- this.res.headers.set(name, value);
569
- }
599
+ headers.set(name, value);
570
600
  }
571
601
  };
572
602
  status = (status) => {
573
- this.#isFresh = false;
574
603
  this.#status = status;
575
604
  };
576
605
  set = (key, value) => {
@@ -587,94 +616,58 @@ var Context = class {
587
616
  return Object.fromEntries(this.#var);
588
617
  }
589
618
  #newResponse(data, arg, headers) {
590
- if (this.#isFresh && !headers && !arg && this.#status === 200) {
591
- return new Response(data, {
592
- headers: this.#preparedHeaders
593
- });
594
- }
595
- if (arg && typeof arg !== "number") {
596
- const header = new Headers(arg.headers);
597
- if (this.#headers) {
598
- this.#headers.forEach((v, k) => {
599
- if (k === "set-cookie") {
600
- header.append(k, v);
601
- } else {
602
- header.set(k, v);
603
- }
604
- });
605
- }
606
- const headers2 = setHeaders(header, this.#preparedHeaders);
607
- return new Response(data, {
608
- headers: headers2,
609
- status: arg.status ?? this.#status
610
- });
611
- }
612
- const status = typeof arg === "number" ? arg : this.#status;
613
- this.#preparedHeaders ??= {};
614
- this.#headers ??= new Headers();
615
- setHeaders(this.#headers, this.#preparedHeaders);
616
- if (this.#res) {
617
- this.#res.headers.forEach((v, k) => {
618
- if (k === "set-cookie") {
619
- this.#headers?.append(k, v);
619
+ const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();
620
+ if (typeof arg === "object" && "headers" in arg) {
621
+ const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
622
+ for (const [key, value] of argHeaders) {
623
+ if (key.toLowerCase() === "set-cookie") {
624
+ responseHeaders.append(key, value);
620
625
  } else {
621
- this.#headers?.set(k, v);
626
+ responseHeaders.set(key, value);
622
627
  }
623
- });
624
- setHeaders(this.#headers, this.#preparedHeaders);
628
+ }
625
629
  }
626
- headers ??= {};
627
- for (const [k, v] of Object.entries(headers)) {
628
- if (typeof v === "string") {
629
- this.#headers.set(k, v);
630
- } else {
631
- this.#headers.delete(k);
632
- for (const v2 of v) {
633
- this.#headers.append(k, v2);
630
+ if (headers) {
631
+ for (const [k, v] of Object.entries(headers)) {
632
+ if (typeof v === "string") {
633
+ responseHeaders.set(k, v);
634
+ } else {
635
+ responseHeaders.delete(k);
636
+ for (const v2 of v) {
637
+ responseHeaders.append(k, v2);
638
+ }
634
639
  }
635
640
  }
636
641
  }
637
- return new Response(data, {
638
- status,
639
- headers: this.#headers
640
- });
642
+ const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
643
+ return new Response(data, { status, headers: responseHeaders });
641
644
  }
642
645
  newResponse = (...args) => this.#newResponse(...args);
643
- body = (data, arg, headers) => {
644
- return typeof arg === "number" ? this.#newResponse(data, arg, headers) : this.#newResponse(data, arg);
645
- };
646
+ body = (data, arg, headers) => this.#newResponse(data, arg, headers);
646
647
  text = (text, arg, headers) => {
647
- if (!this.#preparedHeaders) {
648
- if (this.#isFresh && !headers && !arg) {
649
- return new Response(text);
650
- }
651
- this.#preparedHeaders = {};
652
- }
653
- this.#preparedHeaders["content-type"] = TEXT_PLAIN;
654
- if (typeof arg === "number") {
655
- return this.#newResponse(text, arg, headers);
656
- }
657
- return this.#newResponse(text, arg);
648
+ return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
649
+ text,
650
+ arg,
651
+ setDefaultContentType(TEXT_PLAIN, headers)
652
+ );
658
653
  };
659
654
  json = (object, arg, headers) => {
660
- const body = JSON.stringify(object);
661
- this.#preparedHeaders ??= {};
662
- this.#preparedHeaders["content-type"] = "application/json";
663
- return typeof arg === "number" ? this.#newResponse(body, arg, headers) : this.#newResponse(body, arg);
655
+ return this.#newResponse(
656
+ JSON.stringify(object),
657
+ arg,
658
+ setDefaultContentType("application/json", headers)
659
+ );
664
660
  };
665
661
  html = (html, arg, headers) => {
666
- this.#preparedHeaders ??= {};
667
- this.#preparedHeaders["content-type"] = "text/html; charset=UTF-8";
668
- if (typeof html === "object") {
669
- return resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then((html2) => {
670
- return typeof arg === "number" ? this.#newResponse(html2, arg, headers) : this.#newResponse(html2, arg);
671
- });
672
- }
673
- return typeof arg === "number" ? this.#newResponse(html, arg, headers) : this.#newResponse(html, arg);
662
+ const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
663
+ return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
674
664
  };
675
665
  redirect = (location, status) => {
676
- this.#headers ??= new Headers();
677
- this.#headers.set("Location", String(location));
666
+ const locationString = String(location);
667
+ this.header(
668
+ "Location",
669
+ !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
670
+ );
678
671
  return this.newResponse(null, status ?? 302);
679
672
  };
680
673
  notFound = () => {
@@ -683,56 +676,7 @@ var Context = class {
683
676
  };
684
677
  };
685
678
 
686
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/compose.js
687
- var compose = (middleware, onError, onNotFound) => {
688
- return (context, next) => {
689
- let index = -1;
690
- const isContext = context instanceof Context;
691
- return dispatch(0);
692
- async function dispatch(i) {
693
- if (i <= index) {
694
- throw new Error("next() called multiple times");
695
- }
696
- index = i;
697
- let res;
698
- let isError = false;
699
- let handler;
700
- if (middleware[i]) {
701
- handler = middleware[i][0][0];
702
- if (isContext) {
703
- context.req.routeIndex = i;
704
- }
705
- } else {
706
- handler = i === middleware.length && next || void 0;
707
- }
708
- if (!handler) {
709
- if (isContext && context.finalized === false && onNotFound) {
710
- res = await onNotFound(context);
711
- }
712
- } else {
713
- try {
714
- res = await handler(context, () => {
715
- return dispatch(i + 1);
716
- });
717
- } catch (err) {
718
- if (err instanceof Error && isContext && onError) {
719
- context.error = err;
720
- res = await onError(err, context);
721
- isError = true;
722
- } else {
723
- throw err;
724
- }
725
- }
726
- }
727
- if (res && (context.finalized === false || isError)) {
728
- context.res = res;
729
- }
730
- return context;
731
- }
732
- };
733
- };
734
-
735
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router.js
679
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router.js
736
680
  var METHOD_NAME_ALL = "ALL";
737
681
  var METHOD_NAME_ALL_LOWERCASE = "all";
738
682
  var METHODS = ["get", "post", "put", "delete", "options", "patch"];
@@ -740,16 +684,17 @@ var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is
740
684
  var UnsupportedPathError = class extends Error {
741
685
  };
742
686
 
743
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/constants.js
687
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/constants.js
744
688
  var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
745
689
 
746
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/hono-base.js
690
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/hono-base.js
747
691
  var notFoundHandler = (c) => {
748
692
  return c.text("404 Not Found", 404);
749
693
  };
750
694
  var errorHandler = (err, c) => {
751
695
  if ("getResponse" in err) {
752
- return err.getResponse();
696
+ const res = err.getResponse();
697
+ return c.newResponse(res.body, res);
753
698
  }
754
699
  console.error(err);
755
700
  return c.text("Internal Server Error", 500);
@@ -807,16 +752,17 @@ var Hono = class {
807
752
  });
808
753
  return this;
809
754
  };
810
- const strict = options.strict ?? true;
811
- delete options.strict;
812
- Object.assign(this, options);
813
- this.getPath = strict ? options.getPath ?? getPath : getPathNoStrict;
755
+ const { strict, ...optionsWithoutStrict } = options;
756
+ Object.assign(this, optionsWithoutStrict);
757
+ this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
814
758
  }
815
759
  #clone() {
816
760
  const clone = new Hono({
817
761
  router: this.router,
818
762
  getPath: this.getPath
819
763
  });
764
+ clone.errorHandler = this.errorHandler;
765
+ clone.#notFoundHandler = this.#notFoundHandler;
820
766
  clone.routes = this.routes;
821
767
  return clone;
822
768
  }
@@ -857,7 +803,11 @@ var Hono = class {
857
803
  optionHandler = options;
858
804
  } else {
859
805
  optionHandler = options.optionHandler;
860
- replaceRequest = options.replaceRequest;
806
+ if (options.replaceRequest === false) {
807
+ replaceRequest = (request) => request;
808
+ } else {
809
+ replaceRequest = options.replaceRequest;
810
+ }
861
811
  }
862
812
  }
863
813
  const getOptions = optionHandler ? (c) => {
@@ -893,7 +843,7 @@ var Hono = class {
893
843
  #addRoute(method, path, handler) {
894
844
  method = method.toUpperCase();
895
845
  path = mergePath(this._basePath, path);
896
- const r = { path, method, handler };
846
+ const r = { basePath: this._basePath, path, method, handler };
897
847
  this.router.add(method, path, [handler, r]);
898
848
  this.routes.push(r);
899
849
  }
@@ -968,7 +918,28 @@ var Hono = class {
968
918
  };
969
919
  };
970
920
 
971
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router/reg-exp-router/node.js
921
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/matcher.js
922
+ var emptyParam = [];
923
+ function match(method, path) {
924
+ const matchers = this.buildAllMatchers();
925
+ const match2 = (method2, path2) => {
926
+ const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
927
+ const staticMatch = matcher[2][path2];
928
+ if (staticMatch) {
929
+ return staticMatch;
930
+ }
931
+ const match3 = path2.match(matcher[0]);
932
+ if (!match3) {
933
+ return [[], emptyParam];
934
+ }
935
+ const index = match3.indexOf("", 1);
936
+ return [matcher[1][index], match3];
937
+ };
938
+ this.match = match2;
939
+ return match2(method, path);
940
+ }
941
+
942
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/node.js
972
943
  var LABEL_REG_EXP_STR = "[^/]+";
973
944
  var ONLY_WILDCARD_REG_EXP_STR = ".*";
974
945
  var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
@@ -1015,6 +986,9 @@ var Node = class {
1015
986
  const name = pattern[1];
1016
987
  let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
1017
988
  if (name && pattern[2]) {
989
+ if (regexpStr === ".*") {
990
+ throw PATH_ERROR;
991
+ }
1018
992
  regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
1019
993
  if (/\((?!\?:)/.test(regexpStr)) {
1020
994
  throw PATH_ERROR;
@@ -1073,7 +1047,7 @@ var Node = class {
1073
1047
  }
1074
1048
  };
1075
1049
 
1076
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router/reg-exp-router/trie.js
1050
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/trie.js
1077
1051
  var Trie = class {
1078
1052
  #context = { varIndex: 0 };
1079
1053
  #root = new Node();
@@ -1129,8 +1103,7 @@ var Trie = class {
1129
1103
  }
1130
1104
  };
1131
1105
 
1132
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router/reg-exp-router/router.js
1133
- var emptyParam = [];
1106
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/router.js
1134
1107
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
1135
1108
  var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
1136
1109
  function buildWildcardRegExp(path) {
@@ -1277,30 +1250,14 @@ var RegExpRouter = class {
1277
1250
  });
1278
1251
  }
1279
1252
  }
1280
- match(method, path) {
1281
- clearWildcardRegExpCache();
1282
- const matchers = this.#buildAllMatchers();
1283
- this.match = (method2, path2) => {
1284
- const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
1285
- const staticMatch = matcher[2][path2];
1286
- if (staticMatch) {
1287
- return staticMatch;
1288
- }
1289
- const match = path2.match(matcher[0]);
1290
- if (!match) {
1291
- return [[], emptyParam];
1292
- }
1293
- const index = match.indexOf("", 1);
1294
- return [matcher[1][index], match];
1295
- };
1296
- return this.match(method, path);
1297
- }
1298
- #buildAllMatchers() {
1253
+ match = match;
1254
+ buildAllMatchers() {
1299
1255
  const matchers = /* @__PURE__ */ Object.create(null);
1300
1256
  Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
1301
1257
  matchers[method] ||= this.#buildMatcher(method);
1302
1258
  });
1303
1259
  this.#middleware = this.#routes = void 0;
1260
+ clearWildcardRegExpCache();
1304
1261
  return matchers;
1305
1262
  }
1306
1263
  #buildMatcher(method) {
@@ -1325,7 +1282,7 @@ var RegExpRouter = class {
1325
1282
  }
1326
1283
  };
1327
1284
 
1328
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router/smart-router/router.js
1285
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/smart-router/router.js
1329
1286
  var SmartRouter = class {
1330
1287
  name = "SmartRouter";
1331
1288
  #routers = [];
@@ -1380,7 +1337,7 @@ var SmartRouter = class {
1380
1337
  }
1381
1338
  };
1382
1339
 
1383
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router/trie-router/node.js
1340
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/trie-router/node.js
1384
1341
  var emptyParams = /* @__PURE__ */ Object.create(null);
1385
1342
  var Node2 = class {
1386
1343
  #methods;
@@ -1405,30 +1362,30 @@ var Node2 = class {
1405
1362
  const possibleKeys = [];
1406
1363
  for (let i = 0, len = parts.length; i < len; i++) {
1407
1364
  const p = parts[i];
1408
- if (Object.keys(curNode.#children).includes(p)) {
1409
- curNode = curNode.#children[p];
1410
- const pattern2 = getPattern(p);
1411
- if (pattern2) {
1412
- possibleKeys.push(pattern2[1]);
1365
+ const nextP = parts[i + 1];
1366
+ const pattern = getPattern(p, nextP);
1367
+ const key = Array.isArray(pattern) ? pattern[0] : p;
1368
+ if (key in curNode.#children) {
1369
+ curNode = curNode.#children[key];
1370
+ if (pattern) {
1371
+ possibleKeys.push(pattern[1]);
1413
1372
  }
1414
1373
  continue;
1415
1374
  }
1416
- curNode.#children[p] = new Node2();
1417
- const pattern = getPattern(p);
1375
+ curNode.#children[key] = new Node2();
1418
1376
  if (pattern) {
1419
1377
  curNode.#patterns.push(pattern);
1420
1378
  possibleKeys.push(pattern[1]);
1421
1379
  }
1422
- curNode = curNode.#children[p];
1380
+ curNode = curNode.#children[key];
1423
1381
  }
1424
- const m = /* @__PURE__ */ Object.create(null);
1425
- const handlerSet = {
1426
- handler,
1427
- possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
1428
- score: this.#order
1429
- };
1430
- m[method] = handlerSet;
1431
- curNode.#methods.push(m);
1382
+ curNode.#methods.push({
1383
+ [method]: {
1384
+ handler,
1385
+ possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
1386
+ score: this.#order
1387
+ }
1388
+ });
1432
1389
  return curNode;
1433
1390
  }
1434
1391
  #getHandlerSets(node, method, nodeParams, params) {
@@ -1458,6 +1415,7 @@ var Node2 = class {
1458
1415
  const curNode = this;
1459
1416
  let curNodes = [curNode];
1460
1417
  const parts = splitPath(path);
1418
+ const curNodesQueue = [];
1461
1419
  for (let i = 0, len = parts.length; i < len; i++) {
1462
1420
  const part = parts[i];
1463
1421
  const isLast = i === len - 1;
@@ -1485,20 +1443,30 @@ var Node2 = class {
1485
1443
  const astNode = node.#children["*"];
1486
1444
  if (astNode) {
1487
1445
  handlerSets.push(...this.#getHandlerSets(astNode, method, node.#params));
1446
+ astNode.#params = params;
1488
1447
  tempNodes.push(astNode);
1489
1448
  }
1490
1449
  continue;
1491
1450
  }
1492
- if (part === "") {
1451
+ const [key, name, matcher] = pattern;
1452
+ if (!part && !(matcher instanceof RegExp)) {
1493
1453
  continue;
1494
1454
  }
1495
- const [key, name, matcher] = pattern;
1496
1455
  const child = node.#children[key];
1497
1456
  const restPathString = parts.slice(i).join("/");
1498
- if (matcher instanceof RegExp && matcher.test(restPathString)) {
1499
- params[name] = restPathString;
1500
- handlerSets.push(...this.#getHandlerSets(child, method, node.#params, params));
1501
- continue;
1457
+ if (matcher instanceof RegExp) {
1458
+ const m = matcher.exec(restPathString);
1459
+ if (m) {
1460
+ params[name] = m[0];
1461
+ handlerSets.push(...this.#getHandlerSets(child, method, node.#params, params));
1462
+ if (Object.keys(child.#children).length) {
1463
+ child.#params = params;
1464
+ const componentCount = m[0].match(/\//)?.length ?? 0;
1465
+ const targetCurNodes = curNodesQueue[componentCount] ||= [];
1466
+ targetCurNodes.push(child);
1467
+ }
1468
+ continue;
1469
+ }
1502
1470
  }
1503
1471
  if (matcher === true || matcher.test(part)) {
1504
1472
  params[name] = part;
@@ -1516,7 +1484,7 @@ var Node2 = class {
1516
1484
  }
1517
1485
  }
1518
1486
  }
1519
- curNodes = tempNodes;
1487
+ curNodes = tempNodes.concat(curNodesQueue.shift() ?? []);
1520
1488
  }
1521
1489
  if (handlerSets.length > 1) {
1522
1490
  handlerSets.sort((a, b) => {
@@ -1527,7 +1495,7 @@ var Node2 = class {
1527
1495
  }
1528
1496
  };
1529
1497
 
1530
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router/trie-router/router.js
1498
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/trie-router/router.js
1531
1499
  var TrieRouter = class {
1532
1500
  name = "TrieRouter";
1533
1501
  #node;
@@ -1549,7 +1517,7 @@ var TrieRouter = class {
1549
1517
  }
1550
1518
  };
1551
1519
 
1552
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/hono.js
1520
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/hono.js
1553
1521
  var Hono2 = class extends Hono {
1554
1522
  constructor(options = {}) {
1555
1523
  super(options);
@@ -1559,30 +1527,7 @@ var Hono2 = class extends Hono {
1559
1527
  }
1560
1528
  };
1561
1529
 
1562
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/http-exception.js
1563
- var HTTPException = class extends Error {
1564
- res;
1565
- status;
1566
- constructor(status = 500, options) {
1567
- super(options?.message, { cause: options?.cause });
1568
- this.res = options?.res;
1569
- this.status = status;
1570
- }
1571
- getResponse() {
1572
- if (this.res) {
1573
- const newResponse = new Response(this.res.body, {
1574
- status: this.status,
1575
- headers: this.res.headers
1576
- });
1577
- return newResponse;
1578
- }
1579
- return new Response(this.message, {
1580
- status: this.status
1581
- });
1582
- }
1583
- };
1584
-
1585
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/encode.js
1530
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/encode.js
1586
1531
  var decodeBase64 = (str) => {
1587
1532
  const binary = atob(str);
1588
1533
  const bytes = new Uint8Array(new ArrayBuffer(binary.length));
@@ -1594,18 +1539,18 @@ var decodeBase64 = (str) => {
1594
1539
  return bytes;
1595
1540
  };
1596
1541
 
1597
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/basic-auth.js
1542
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/basic-auth.js
1598
1543
  var CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/;
1599
1544
  var USER_PASS_REGEXP = /^([^:]*):(.*)$/;
1600
1545
  var utf8Decoder = new TextDecoder();
1601
1546
  var auth = (req) => {
1602
- const match = CREDENTIALS_REGEXP.exec(req.headers.get("Authorization") || "");
1603
- if (!match) {
1547
+ const match2 = CREDENTIALS_REGEXP.exec(req.headers.get("Authorization") || "");
1548
+ if (!match2) {
1604
1549
  return void 0;
1605
1550
  }
1606
1551
  let userPass = void 0;
1607
1552
  try {
1608
- userPass = USER_PASS_REGEXP.exec(utf8Decoder.decode(decodeBase64(match[1])));
1553
+ userPass = USER_PASS_REGEXP.exec(utf8Decoder.decode(decodeBase64(match2[1])));
1609
1554
  } catch {
1610
1555
  }
1611
1556
  if (!userPass) {
@@ -1614,7 +1559,7 @@ var auth = (req) => {
1614
1559
  return { username: userPass[1], password: userPass[2] };
1615
1560
  };
1616
1561
 
1617
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/crypto.js
1562
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/crypto.js
1618
1563
  var sha256 = async (data) => {
1619
1564
  const algorithm = { name: "SHA-256", alias: "sha256" };
1620
1565
  const hash = await createHash(data, algorithm);
@@ -1643,7 +1588,7 @@ var createHash = async (data, algorithm) => {
1643
1588
  return null;
1644
1589
  };
1645
1590
 
1646
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/buffer.js
1591
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/buffer.js
1647
1592
  var timingSafeEqual = async (a, b, hashFunction) => {
1648
1593
  if (!hashFunction) {
1649
1594
  hashFunction = sha256;
@@ -1655,7 +1600,7 @@ var timingSafeEqual = async (a, b, hashFunction) => {
1655
1600
  return sa === sb && a === b;
1656
1601
  };
1657
1602
 
1658
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/middleware/basic-auth/index.js
1603
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/middleware/basic-auth/index.js
1659
1604
  var basicAuth = (options, ...users) => {
1660
1605
  const usernamePasswordInOptions = "username" in options && "password" in options;
1661
1606
  const verifyUserInOptions = "verifyUser" in options;
@@ -1710,7 +1655,7 @@ var basicAuth = (options, ...users) => {
1710
1655
  };
1711
1656
  };
1712
1657
 
1713
- // ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/middleware/cors/index.js
1658
+ // ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/middleware/cors/index.js
1714
1659
  var cors = (options) => {
1715
1660
  const defaults = {
1716
1661
  origin: "*",
@@ -1735,22 +1680,23 @@ var cors = (options) => {
1735
1680
  return (origin) => optsOrigin.includes(origin) ? origin : null;
1736
1681
  }
1737
1682
  })(opts.origin);
1683
+ const findAllowMethods = ((optsAllowMethods) => {
1684
+ if (typeof optsAllowMethods === "function") {
1685
+ return optsAllowMethods;
1686
+ } else if (Array.isArray(optsAllowMethods)) {
1687
+ return () => optsAllowMethods;
1688
+ } else {
1689
+ return () => [];
1690
+ }
1691
+ })(opts.allowMethods);
1738
1692
  return async function cors2(c, next) {
1739
1693
  function set(key, value) {
1740
1694
  c.res.headers.set(key, value);
1741
1695
  }
1742
- const allowOrigin = findAllowOrigin(c.req.header("origin") || "", c);
1696
+ const allowOrigin = await findAllowOrigin(c.req.header("origin") || "", c);
1743
1697
  if (allowOrigin) {
1744
1698
  set("Access-Control-Allow-Origin", allowOrigin);
1745
1699
  }
1746
- if (opts.origin !== "*") {
1747
- const existingVary = c.req.header("Vary");
1748
- if (existingVary) {
1749
- set("Vary", existingVary);
1750
- } else {
1751
- set("Vary", "Origin");
1752
- }
1753
- }
1754
1700
  if (opts.credentials) {
1755
1701
  set("Access-Control-Allow-Credentials", "true");
1756
1702
  }
@@ -1758,11 +1704,15 @@ var cors = (options) => {
1758
1704
  set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
1759
1705
  }
1760
1706
  if (c.req.method === "OPTIONS") {
1707
+ if (opts.origin !== "*") {
1708
+ set("Vary", "Origin");
1709
+ }
1761
1710
  if (opts.maxAge != null) {
1762
1711
  set("Access-Control-Max-Age", opts.maxAge.toString());
1763
1712
  }
1764
- if (opts.allowMethods?.length) {
1765
- set("Access-Control-Allow-Methods", opts.allowMethods.join(","));
1713
+ const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
1714
+ if (allowMethods.length) {
1715
+ set("Access-Control-Allow-Methods", allowMethods.join(","));
1766
1716
  }
1767
1717
  let headers = opts.allowHeaders;
1768
1718
  if (!headers?.length) {
@@ -1784,11 +1734,14 @@ var cors = (options) => {
1784
1734
  });
1785
1735
  }
1786
1736
  await next();
1737
+ if (opts.origin !== "*") {
1738
+ c.header("Vary", "Origin", { append: true });
1739
+ }
1787
1740
  };
1788
1741
  };
1789
1742
 
1790
1743
  // src/index.ts
1791
- import { z as z13 } from "zod";
1744
+ import { z as z17 } from "zod";
1792
1745
 
1793
1746
  // src/foundation/middlewares/readonly.ts
1794
1747
  async function readOnlyMiddleware(c, next) {
@@ -1811,7 +1764,7 @@ async function readOnlyMiddleware(c, next) {
1811
1764
  }
1812
1765
 
1813
1766
  // package.json
1814
- var version = "1.1.9";
1767
+ var version = "1.1.11";
1815
1768
 
1816
1769
  // src/foundation/settings.ts
1817
1770
  var settings = {
@@ -1856,23 +1809,135 @@ var CreateFolder = class extends OpenAPIRoute {
1856
1809
  }
1857
1810
  };
1858
1811
 
1859
- // src/modules/buckets/deleteObject.ts
1812
+ // src/modules/buckets/createShareLink.ts
1860
1813
  import { OpenAPIRoute as OpenAPIRoute2 } from "chanfana";
1861
1814
  import { z as z2 } from "zod";
1862
- var DeleteObject = class extends OpenAPIRoute2 {
1815
+ var CreateShareLink = class extends OpenAPIRoute2 {
1863
1816
  schema = {
1864
- operationId: "post-bucket-delete-object",
1817
+ operationId: "post-bucket-create-share-link",
1865
1818
  tags: ["Buckets"],
1866
- summary: "Delete object",
1819
+ summary: "Create shareable link for file",
1867
1820
  request: {
1868
1821
  params: z2.object({
1869
- bucket: z2.string()
1822
+ bucket: z2.string(),
1823
+ key: z2.string()
1870
1824
  }),
1871
1825
  body: {
1872
1826
  content: {
1873
1827
  "application/json": {
1874
1828
  schema: z2.object({
1875
- key: z2.string().describe("base64 encoded file key")
1829
+ expiresIn: z2.number().optional().describe("Expiration time in seconds"),
1830
+ password: z2.string().optional().describe("Optional password"),
1831
+ maxDownloads: z2.number().optional().describe("Maximum downloads")
1832
+ })
1833
+ }
1834
+ }
1835
+ }
1836
+ },
1837
+ responses: {
1838
+ "200": {
1839
+ description: "Share link created successfully",
1840
+ content: {
1841
+ "application/json": {
1842
+ schema: z2.object({
1843
+ shareId: z2.string(),
1844
+ shareUrl: z2.string(),
1845
+ expiresAt: z2.number().optional()
1846
+ })
1847
+ }
1848
+ }
1849
+ }
1850
+ }
1851
+ };
1852
+ async handle(c) {
1853
+ const data = await this.getValidatedData();
1854
+ const bucketName = data.params.bucket;
1855
+ const bucket = c.env[bucketName];
1856
+ if (!bucket) {
1857
+ throw new HTTPException(500, {
1858
+ message: `Bucket binding not found: ${bucketName}`
1859
+ });
1860
+ }
1861
+ const key = decodeURIComponent(escape(atob(data.params.key)));
1862
+ const fileExists = await bucket.head(key);
1863
+ if (!fileExists) {
1864
+ throw new HTTPException(404, {
1865
+ message: `File not found: ${key}`
1866
+ });
1867
+ }
1868
+ let shareId = "";
1869
+ let attempts = 0;
1870
+ const maxAttempts = 5;
1871
+ while (attempts < maxAttempts) {
1872
+ shareId = crypto.randomUUID().replace(/-/g, "").substring(0, 10);
1873
+ const existingShare = await bucket.head(
1874
+ `.r2-explorer/sharable-links/${shareId}.json`
1875
+ );
1876
+ if (!existingShare) {
1877
+ break;
1878
+ }
1879
+ attempts++;
1880
+ }
1881
+ if (attempts === maxAttempts) {
1882
+ throw new HTTPException(500, {
1883
+ message: "Failed to generate unique share ID"
1884
+ });
1885
+ }
1886
+ let passwordHash;
1887
+ if (data.body.password) {
1888
+ const encoder = new TextEncoder();
1889
+ const passwordData = encoder.encode(data.body.password);
1890
+ const hashBuffer = await crypto.subtle.digest("SHA-256", passwordData);
1891
+ passwordHash = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
1892
+ }
1893
+ const expiresAt = data.body.expiresIn ? Date.now() + data.body.expiresIn * 1e3 : void 0;
1894
+ const shareMetadata = {
1895
+ bucket: bucketName,
1896
+ key,
1897
+ expiresAt,
1898
+ passwordHash,
1899
+ maxDownloads: data.body.maxDownloads,
1900
+ currentDownloads: 0,
1901
+ createdBy: c.get("authentication_username") || "anonymous",
1902
+ createdAt: Date.now()
1903
+ };
1904
+ await bucket.put(
1905
+ `.r2-explorer/sharable-links/${shareId}.json`,
1906
+ JSON.stringify(shareMetadata),
1907
+ {
1908
+ httpMetadata: { contentType: "application/json" },
1909
+ customMetadata: {
1910
+ targetBucket: bucketName,
1911
+ targetKey: key
1912
+ }
1913
+ }
1914
+ );
1915
+ const shareUrl = `${new URL(c.req.url).origin}/share/${shareId}`;
1916
+ return c.json({
1917
+ shareId,
1918
+ shareUrl,
1919
+ expiresAt
1920
+ });
1921
+ }
1922
+ };
1923
+
1924
+ // src/modules/buckets/deleteObject.ts
1925
+ import { OpenAPIRoute as OpenAPIRoute3 } from "chanfana";
1926
+ import { z as z3 } from "zod";
1927
+ var DeleteObject = class extends OpenAPIRoute3 {
1928
+ schema = {
1929
+ operationId: "post-bucket-delete-object",
1930
+ tags: ["Buckets"],
1931
+ summary: "Delete object",
1932
+ request: {
1933
+ params: z3.object({
1934
+ bucket: z3.string()
1935
+ }),
1936
+ body: {
1937
+ content: {
1938
+ "application/json": {
1939
+ schema: z3.object({
1940
+ key: z3.string().describe("base64 encoded file key")
1876
1941
  })
1877
1942
  }
1878
1943
  }
@@ -1894,24 +1959,73 @@ var DeleteObject = class extends OpenAPIRoute2 {
1894
1959
  }
1895
1960
  };
1896
1961
 
1962
+ // src/modules/buckets/deleteShareLink.ts
1963
+ import { OpenAPIRoute as OpenAPIRoute4 } from "chanfana";
1964
+ import { z as z4 } from "zod";
1965
+ var DeleteShareLink = class extends OpenAPIRoute4 {
1966
+ schema = {
1967
+ operationId: "delete-bucket-share-link",
1968
+ tags: ["Buckets"],
1969
+ summary: "Revoke/delete a share link",
1970
+ request: {
1971
+ params: z4.object({
1972
+ bucket: z4.string(),
1973
+ shareId: z4.string().describe("10-character share ID")
1974
+ })
1975
+ },
1976
+ responses: {
1977
+ "200": {
1978
+ description: "Share link deleted successfully",
1979
+ content: {
1980
+ "application/json": {
1981
+ schema: z4.object({
1982
+ success: z4.boolean()
1983
+ })
1984
+ }
1985
+ }
1986
+ }
1987
+ }
1988
+ };
1989
+ async handle(c) {
1990
+ const data = await this.getValidatedData();
1991
+ const bucketName = data.params.bucket;
1992
+ const bucket = c.env[bucketName];
1993
+ if (!bucket) {
1994
+ throw new HTTPException(500, {
1995
+ message: `Bucket binding not found: ${bucketName}`
1996
+ });
1997
+ }
1998
+ const shareId = data.params.shareId;
1999
+ const shareKey = `.r2-explorer/sharable-links/${shareId}.json`;
2000
+ const shareExists = await bucket.head(shareKey);
2001
+ if (!shareExists) {
2002
+ throw new HTTPException(404, {
2003
+ message: `Share link not found: ${shareId}`
2004
+ });
2005
+ }
2006
+ await bucket.delete(shareKey);
2007
+ return c.json({ success: true });
2008
+ }
2009
+ };
2010
+
1897
2011
  // src/modules/buckets/getObject.ts
1898
- import { OpenAPIRoute as OpenAPIRoute3 } from "chanfana";
1899
- import { z as z3 } from "zod";
1900
- var GetObject = class extends OpenAPIRoute3 {
2012
+ import { OpenAPIRoute as OpenAPIRoute5 } from "chanfana";
2013
+ import { z as z5 } from "zod";
2014
+ var GetObject = class extends OpenAPIRoute5 {
1901
2015
  schema = {
1902
2016
  operationId: "get-bucket-object",
1903
2017
  tags: ["Buckets"],
1904
2018
  summary: "Get Object",
1905
2019
  request: {
1906
- params: z3.object({
1907
- bucket: z3.string(),
1908
- key: z3.string().describe("base64 encoded file key")
2020
+ params: z5.object({
2021
+ bucket: z5.string(),
2022
+ key: z5.string().describe("base64 encoded file key")
1909
2023
  })
1910
2024
  },
1911
2025
  responses: {
1912
2026
  "200": {
1913
2027
  description: "File binary",
1914
- schema: z3.string().openapi({ format: "binary" })
2028
+ schema: z5.string().openapi({ format: "binary" })
1915
2029
  }
1916
2030
  }
1917
2031
  };
@@ -1927,10 +2041,14 @@ var GetObject = class extends OpenAPIRoute3 {
1927
2041
  let filePath;
1928
2042
  try {
1929
2043
  filePath = decodeURIComponent(escape(atob(data.params.key)));
1930
- } catch (e) {
1931
- filePath = decodeURIComponent(
1932
- escape(atob(decodeURIComponent(data.params.key)))
1933
- );
2044
+ } catch {
2045
+ try {
2046
+ filePath = decodeURIComponent(
2047
+ escape(atob(decodeURIComponent(data.params.key)))
2048
+ );
2049
+ } catch {
2050
+ filePath = escape(atob(decodeURIComponent(data.params.key)));
2051
+ }
1934
2052
  }
1935
2053
  const object = await bucket.get(filePath);
1936
2054
  if (object === null) {
@@ -1939,6 +2057,7 @@ var GetObject = class extends OpenAPIRoute3 {
1939
2057
  const headers = new Headers();
1940
2058
  object.writeHttpMetadata(headers);
1941
2059
  headers.set("etag", object.httpEtag);
2060
+ headers.set("content-length", object.size.toString());
1942
2061
  headers.set(
1943
2062
  "Content-Disposition",
1944
2063
  `attachment; filename="${filePath.split("/").pop()}"`
@@ -1949,18 +2068,137 @@ var GetObject = class extends OpenAPIRoute3 {
1949
2068
  }
1950
2069
  };
1951
2070
 
2071
+ // src/modules/buckets/getShareLink.ts
2072
+ import { OpenAPIRoute as OpenAPIRoute6 } from "chanfana";
2073
+ import { z as z6 } from "zod";
2074
+ var GetShareLink = class extends OpenAPIRoute6 {
2075
+ schema = {
2076
+ operationId: "get-share-link",
2077
+ tags: ["Sharing"],
2078
+ summary: "Access shared file",
2079
+ security: [],
2080
+ // Public endpoint - no auth required
2081
+ request: {
2082
+ params: z6.object({
2083
+ shareId: z6.string().describe("10-character share ID")
2084
+ }),
2085
+ query: z6.object({
2086
+ password: z6.string().optional().describe("Password for protected shares")
2087
+ })
2088
+ },
2089
+ responses: {
2090
+ "200": {
2091
+ description: "File retrieved successfully"
2092
+ },
2093
+ "401": {
2094
+ description: "Password required or incorrect"
2095
+ },
2096
+ "404": {
2097
+ description: "Share link not found"
2098
+ },
2099
+ "410": {
2100
+ description: "Share link expired"
2101
+ },
2102
+ "403": {
2103
+ description: "Download limit reached"
2104
+ }
2105
+ }
2106
+ };
2107
+ async handle(c) {
2108
+ const data = await this.getValidatedData();
2109
+ const shareId = data.params.shareId;
2110
+ let shareMetadata = null;
2111
+ let bucket = null;
2112
+ for (const key in c.env) {
2113
+ if (key === "ASSETS") continue;
2114
+ const currentBucket = c.env[key];
2115
+ if (!currentBucket.get || typeof currentBucket.get !== "function") {
2116
+ continue;
2117
+ }
2118
+ const shareObject = await currentBucket.get(
2119
+ `.r2-explorer/sharable-links/${shareId}.json`
2120
+ );
2121
+ if (shareObject) {
2122
+ shareMetadata = JSON.parse(await shareObject.text());
2123
+ bucket = currentBucket;
2124
+ break;
2125
+ }
2126
+ }
2127
+ if (!shareMetadata || !bucket) {
2128
+ throw new HTTPException(404, {
2129
+ message: "Share link not found"
2130
+ });
2131
+ }
2132
+ if (shareMetadata.expiresAt && Date.now() > shareMetadata.expiresAt) {
2133
+ throw new HTTPException(410, {
2134
+ message: "Share link expired"
2135
+ });
2136
+ }
2137
+ if (shareMetadata.maxDownloads && shareMetadata.currentDownloads >= shareMetadata.maxDownloads) {
2138
+ throw new HTTPException(403, {
2139
+ message: "Download limit reached"
2140
+ });
2141
+ }
2142
+ if (shareMetadata.passwordHash) {
2143
+ if (!data.query.password) {
2144
+ throw new HTTPException(401, {
2145
+ message: "Password required"
2146
+ });
2147
+ }
2148
+ const encoder = new TextEncoder();
2149
+ const passwordData = encoder.encode(data.query.password);
2150
+ const hashBuffer = await crypto.subtle.digest("SHA-256", passwordData);
2151
+ const providedHash = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
2152
+ if (providedHash !== shareMetadata.passwordHash) {
2153
+ throw new HTTPException(401, {
2154
+ message: "Incorrect password"
2155
+ });
2156
+ }
2157
+ }
2158
+ shareMetadata.currentDownloads++;
2159
+ await bucket.put(
2160
+ `.r2-explorer/sharable-links/${shareId}.json`,
2161
+ JSON.stringify(shareMetadata),
2162
+ {
2163
+ httpMetadata: { contentType: "application/json" },
2164
+ customMetadata: {
2165
+ targetBucket: shareMetadata.bucket,
2166
+ targetKey: shareMetadata.key
2167
+ }
2168
+ }
2169
+ );
2170
+ const file = await bucket.get(shareMetadata.key);
2171
+ if (!file) {
2172
+ throw new HTTPException(404, {
2173
+ message: "Shared file not found"
2174
+ });
2175
+ }
2176
+ const headers = new Headers();
2177
+ file.writeHttpMetadata(headers);
2178
+ headers.set("etag", file.httpEtag);
2179
+ const fileName = shareMetadata.key.split("/").pop() || "download";
2180
+ headers.set(
2181
+ "Content-Disposition",
2182
+ `attachment; filename="${encodeURIComponent(fileName)}"`
2183
+ );
2184
+ return new Response(file.body, {
2185
+ headers
2186
+ });
2187
+ }
2188
+ };
2189
+
1952
2190
  // src/modules/buckets/headObject.ts
1953
- import { OpenAPIRoute as OpenAPIRoute4 } from "chanfana";
1954
- import { z as z4 } from "zod";
1955
- var HeadObject = class extends OpenAPIRoute4 {
2191
+ import { OpenAPIRoute as OpenAPIRoute7 } from "chanfana";
2192
+ import { z as z7 } from "zod";
2193
+ var HeadObject = class extends OpenAPIRoute7 {
1956
2194
  schema = {
1957
2195
  operationId: "Head-bucket-object",
1958
2196
  tags: ["Buckets"],
1959
2197
  summary: "Get Object",
1960
2198
  request: {
1961
- params: z4.object({
1962
- bucket: z4.string(),
1963
- key: z4.string().describe("base64 encoded file key")
2199
+ params: z7.object({
2200
+ bucket: z7.string(),
2201
+ key: z7.string().describe("base64 encoded file key")
1964
2202
  })
1965
2203
  }
1966
2204
  };
@@ -1990,24 +2228,24 @@ var HeadObject = class extends OpenAPIRoute4 {
1990
2228
  };
1991
2229
 
1992
2230
  // src/modules/buckets/listObjects.ts
1993
- import { OpenAPIRoute as OpenAPIRoute5 } from "chanfana";
1994
- import { z as z5 } from "zod";
1995
- var ListObjects = class extends OpenAPIRoute5 {
2231
+ import { OpenAPIRoute as OpenAPIRoute8 } from "chanfana";
2232
+ import { z as z8 } from "zod";
2233
+ var ListObjects = class extends OpenAPIRoute8 {
1996
2234
  schema = {
1997
2235
  operationId: "get-bucket-list-objects",
1998
2236
  tags: ["Buckets"],
1999
2237
  summary: "List objects",
2000
2238
  request: {
2001
- params: z5.object({
2002
- bucket: z5.string()
2239
+ params: z8.object({
2240
+ bucket: z8.string()
2003
2241
  }),
2004
- query: z5.object({
2005
- limit: z5.number().optional(),
2006
- prefix: z5.string().nullable().optional().describe("base64 encoded prefix"),
2007
- cursor: z5.string().nullable().optional(),
2008
- delimiter: z5.string().nullable().optional(),
2009
- startAfter: z5.string().nullable().optional(),
2010
- include: z5.enum(["httpMetadata", "customMetadata"]).array().optional()
2242
+ query: z8.object({
2243
+ limit: z8.number().optional(),
2244
+ prefix: z8.string().nullable().optional().describe("base64 encoded prefix"),
2245
+ cursor: z8.string().nullable().optional(),
2246
+ delimiter: z8.string().nullable().optional(),
2247
+ startAfter: z8.string().nullable().optional(),
2248
+ include: z8.enum(["httpMetadata", "customMetadata"]).array().optional()
2011
2249
  })
2012
2250
  }
2013
2251
  };
@@ -2033,24 +2271,102 @@ var ListObjects = class extends OpenAPIRoute5 {
2033
2271
  }
2034
2272
  };
2035
2273
 
2274
+ // src/modules/buckets/listShares.ts
2275
+ import { OpenAPIRoute as OpenAPIRoute9 } from "chanfana";
2276
+ import { z as z9 } from "zod";
2277
+ var ListShares = class extends OpenAPIRoute9 {
2278
+ schema = {
2279
+ operationId: "get-bucket-shares",
2280
+ tags: ["Buckets"],
2281
+ summary: "List all active shares in bucket",
2282
+ request: {
2283
+ params: z9.object({
2284
+ bucket: z9.string()
2285
+ })
2286
+ },
2287
+ responses: {
2288
+ "200": {
2289
+ description: "List of active shares",
2290
+ content: {
2291
+ "application/json": {
2292
+ schema: z9.object({
2293
+ shares: z9.array(
2294
+ z9.object({
2295
+ shareId: z9.string(),
2296
+ shareUrl: z9.string(),
2297
+ key: z9.string(),
2298
+ expiresAt: z9.number().optional(),
2299
+ maxDownloads: z9.number().optional(),
2300
+ currentDownloads: z9.number(),
2301
+ createdBy: z9.string(),
2302
+ createdAt: z9.number(),
2303
+ isExpired: z9.boolean(),
2304
+ hasPassword: z9.boolean()
2305
+ })
2306
+ )
2307
+ })
2308
+ }
2309
+ }
2310
+ }
2311
+ }
2312
+ };
2313
+ async handle(c) {
2314
+ const data = await this.getValidatedData();
2315
+ const bucketName = data.params.bucket;
2316
+ const bucket = c.env[bucketName];
2317
+ if (!bucket) {
2318
+ throw new HTTPException(500, {
2319
+ message: `Bucket binding not found: ${bucketName}`
2320
+ });
2321
+ }
2322
+ const sharesList = await bucket.list({
2323
+ prefix: ".r2-explorer/sharable-links/"
2324
+ });
2325
+ const shares = [];
2326
+ const now = Date.now();
2327
+ const origin = new URL(c.req.url).origin;
2328
+ for (const obj of sharesList.objects) {
2329
+ const shareId = obj.key.split("/").pop()?.replace(".json", "");
2330
+ if (!shareId) continue;
2331
+ const shareObject = await bucket.get(obj.key);
2332
+ if (!shareObject) continue;
2333
+ const metadata = JSON.parse(await shareObject.text());
2334
+ const isExpired = !!(metadata.expiresAt && now > metadata.expiresAt);
2335
+ shares.push({
2336
+ shareId,
2337
+ shareUrl: `${origin}/share/${shareId}`,
2338
+ key: metadata.key,
2339
+ expiresAt: metadata.expiresAt,
2340
+ maxDownloads: metadata.maxDownloads,
2341
+ currentDownloads: metadata.currentDownloads || 0,
2342
+ createdBy: metadata.createdBy,
2343
+ createdAt: metadata.createdAt,
2344
+ isExpired,
2345
+ hasPassword: !!metadata.passwordHash
2346
+ });
2347
+ }
2348
+ return c.json({ shares });
2349
+ }
2350
+ };
2351
+
2036
2352
  // src/modules/buckets/moveObject.ts
2037
- import { OpenAPIRoute as OpenAPIRoute6 } from "chanfana";
2038
- import { z as z6 } from "zod";
2039
- var MoveObject = class extends OpenAPIRoute6 {
2353
+ import { OpenAPIRoute as OpenAPIRoute10 } from "chanfana";
2354
+ import { z as z10 } from "zod";
2355
+ var MoveObject = class extends OpenAPIRoute10 {
2040
2356
  schema = {
2041
2357
  operationId: "post-bucket-move-object",
2042
2358
  tags: ["Buckets"],
2043
2359
  summary: "Move object",
2044
2360
  request: {
2045
- params: z6.object({
2046
- bucket: z6.string()
2361
+ params: z10.object({
2362
+ bucket: z10.string()
2047
2363
  }),
2048
2364
  body: {
2049
2365
  content: {
2050
2366
  "application/json": {
2051
- schema: z6.object({
2052
- oldKey: z6.string().describe("base64 encoded file key"),
2053
- newKey: z6.string().describe("base64 encoded file key")
2367
+ schema: z10.object({
2368
+ oldKey: z10.string().describe("base64 encoded file key"),
2369
+ newKey: z10.string().describe("base64 encoded file key")
2054
2370
  })
2055
2371
  }
2056
2372
  }
@@ -2084,27 +2400,27 @@ var MoveObject = class extends OpenAPIRoute6 {
2084
2400
  };
2085
2401
 
2086
2402
  // src/modules/buckets/multipart/completeUpload.ts
2087
- import { OpenAPIRoute as OpenAPIRoute7 } from "chanfana";
2088
- import { z as z7 } from "zod";
2089
- var CompleteUpload = class extends OpenAPIRoute7 {
2403
+ import { OpenAPIRoute as OpenAPIRoute11 } from "chanfana";
2404
+ import { z as z11 } from "zod";
2405
+ var CompleteUpload = class extends OpenAPIRoute11 {
2090
2406
  schema = {
2091
2407
  operationId: "post-multipart-complete-upload",
2092
2408
  tags: ["Multipart"],
2093
2409
  summary: "Complete upload",
2094
2410
  request: {
2095
- params: z7.object({
2096
- bucket: z7.string()
2411
+ params: z11.object({
2412
+ bucket: z11.string()
2097
2413
  }),
2098
2414
  body: {
2099
2415
  content: {
2100
2416
  "application/json": {
2101
- schema: z7.object({
2102
- uploadId: z7.string(),
2103
- parts: z7.object({
2104
- etag: z7.string(),
2105
- partNumber: z7.number().int()
2417
+ schema: z11.object({
2418
+ uploadId: z11.string(),
2419
+ parts: z11.object({
2420
+ etag: z11.string(),
2421
+ partNumber: z11.number().int()
2106
2422
  }).array(),
2107
- key: z7.string().describe("base64 encoded file key")
2423
+ key: z11.string().describe("base64 encoded file key")
2108
2424
  })
2109
2425
  }
2110
2426
  }
@@ -2114,6 +2430,12 @@ var CompleteUpload = class extends OpenAPIRoute7 {
2114
2430
  async handle(c) {
2115
2431
  const data = await this.getValidatedData();
2116
2432
  const bucket = c.env[data.params.bucket];
2433
+ if (!bucket || typeof bucket !== "object" || !("resumeMultipartUpload" in bucket)) {
2434
+ return Response.json(
2435
+ { error: `Bucket binding not found: ${data.params.bucket}` },
2436
+ { status: 500 }
2437
+ );
2438
+ }
2117
2439
  const uploadId = data.body.uploadId;
2118
2440
  const key = decodeURIComponent(escape(atob(data.body.key)));
2119
2441
  const parts = data.body.parts;
@@ -2131,27 +2453,33 @@ var CompleteUpload = class extends OpenAPIRoute7 {
2131
2453
  };
2132
2454
 
2133
2455
  // src/modules/buckets/multipart/createUpload.ts
2134
- import { OpenAPIRoute as OpenAPIRoute8 } from "chanfana";
2135
- import { z as z8 } from "zod";
2136
- var CreateUpload = class extends OpenAPIRoute8 {
2456
+ import { OpenAPIRoute as OpenAPIRoute12 } from "chanfana";
2457
+ import { z as z12 } from "zod";
2458
+ var CreateUpload = class extends OpenAPIRoute12 {
2137
2459
  schema = {
2138
2460
  operationId: "post-multipart-create-upload",
2139
2461
  tags: ["Multipart"],
2140
2462
  summary: "Create upload",
2141
2463
  request: {
2142
- params: z8.object({
2143
- bucket: z8.string()
2464
+ params: z12.object({
2465
+ bucket: z12.string()
2144
2466
  }),
2145
- query: z8.object({
2146
- key: z8.string().describe("base64 encoded file key"),
2147
- customMetadata: z8.string().nullable().optional().describe("base64 encoded json string"),
2148
- httpMetadata: z8.string().nullable().optional().describe("base64 encoded json string")
2467
+ query: z12.object({
2468
+ key: z12.string().describe("base64 encoded file key"),
2469
+ customMetadata: z12.string().nullable().optional().describe("base64 encoded json string"),
2470
+ httpMetadata: z12.string().nullable().optional().describe("base64 encoded json string")
2149
2471
  })
2150
2472
  }
2151
2473
  };
2152
2474
  async handle(c) {
2153
2475
  const data = await this.getValidatedData();
2154
2476
  const bucket = c.env[data.params.bucket];
2477
+ if (!bucket || typeof bucket !== "object" || !("createMultipartUpload" in bucket)) {
2478
+ return Response.json(
2479
+ { error: `Bucket binding not found: ${data.params.bucket}` },
2480
+ { status: 500 }
2481
+ );
2482
+ }
2155
2483
  const key = decodeURIComponent(escape(atob(data.query.key)));
2156
2484
  let customMetadata = void 0;
2157
2485
  if (data.query.customMetadata) {
@@ -2173,9 +2501,9 @@ var CreateUpload = class extends OpenAPIRoute8 {
2173
2501
  };
2174
2502
 
2175
2503
  // src/modules/buckets/multipart/partUpload.ts
2176
- import { OpenAPIRoute as OpenAPIRoute9 } from "chanfana";
2177
- import { z as z9 } from "zod";
2178
- var PartUpload = class extends OpenAPIRoute9 {
2504
+ import { OpenAPIRoute as OpenAPIRoute13 } from "chanfana";
2505
+ import { z as z13 } from "zod";
2506
+ var PartUpload = class extends OpenAPIRoute13 {
2179
2507
  schema = {
2180
2508
  operationId: "post-multipart-part-upload",
2181
2509
  tags: ["Multipart"],
@@ -2184,26 +2512,32 @@ var PartUpload = class extends OpenAPIRoute9 {
2184
2512
  body: {
2185
2513
  content: {
2186
2514
  "application/octet-stream": {
2187
- schema: z9.object({}).openapi({
2515
+ schema: z13.object({}).openapi({
2188
2516
  type: "string",
2189
2517
  format: "binary"
2190
2518
  })
2191
2519
  }
2192
2520
  }
2193
2521
  },
2194
- params: z9.object({
2195
- bucket: z9.string()
2522
+ params: z13.object({
2523
+ bucket: z13.string()
2196
2524
  }),
2197
- query: z9.object({
2198
- key: z9.string().describe("base64 encoded file key"),
2199
- uploadId: z9.string(),
2200
- partNumber: z9.number().int()
2525
+ query: z13.object({
2526
+ key: z13.string().describe("base64 encoded file key"),
2527
+ uploadId: z13.string(),
2528
+ partNumber: z13.number().int()
2201
2529
  })
2202
2530
  }
2203
2531
  };
2204
2532
  async handle(c) {
2205
2533
  const data = await this.getValidatedData();
2206
2534
  const bucket = c.env[data.params.bucket];
2535
+ if (!bucket || typeof bucket !== "object" || !("resumeMultipartUpload" in bucket)) {
2536
+ return Response.json(
2537
+ { error: `Bucket binding not found: ${data.params.bucket}` },
2538
+ { status: 500 }
2539
+ );
2540
+ }
2207
2541
  const key = decodeURIComponent(escape(atob(data.query.key)));
2208
2542
  const multipartUpload = bucket.resumeMultipartUpload(
2209
2543
  key,
@@ -2221,24 +2555,24 @@ var PartUpload = class extends OpenAPIRoute9 {
2221
2555
  };
2222
2556
 
2223
2557
  // src/modules/buckets/putMetadata.ts
2224
- import { OpenAPIRoute as OpenAPIRoute10 } from "chanfana";
2225
- import { z as z10 } from "zod";
2226
- var PutMetadata = class extends OpenAPIRoute10 {
2558
+ import { OpenAPIRoute as OpenAPIRoute14 } from "chanfana";
2559
+ import { z as z14 } from "zod";
2560
+ var PutMetadata = class extends OpenAPIRoute14 {
2227
2561
  schema = {
2228
2562
  operationId: "post-bucket-put-object-metadata",
2229
2563
  tags: ["Buckets"],
2230
2564
  summary: "Update object metadata",
2231
2565
  request: {
2232
- params: z10.object({
2233
- bucket: z10.string(),
2234
- key: z10.string().describe("base64 encoded file key")
2566
+ params: z14.object({
2567
+ bucket: z14.string(),
2568
+ key: z14.string().describe("base64 encoded file key")
2235
2569
  }),
2236
2570
  body: {
2237
2571
  content: {
2238
2572
  "application/json": {
2239
- schema: z10.object({
2240
- customMetadata: z10.record(z10.string(), z10.any()),
2241
- httpMetadata: z10.record(z10.string(), z10.any())
2573
+ schema: z14.object({
2574
+ customMetadata: z14.record(z14.string(), z14.any()),
2575
+ httpMetadata: z14.record(z14.string(), z14.any())
2242
2576
  }).openapi("Object metadata")
2243
2577
  }
2244
2578
  }
@@ -2274,9 +2608,9 @@ var PutMetadata = class extends OpenAPIRoute10 {
2274
2608
  };
2275
2609
 
2276
2610
  // src/modules/buckets/putObject.ts
2277
- import { OpenAPIRoute as OpenAPIRoute11 } from "chanfana";
2278
- import { z as z11 } from "zod";
2279
- var PutObject = class extends OpenAPIRoute11 {
2611
+ import { OpenAPIRoute as OpenAPIRoute15 } from "chanfana";
2612
+ import { z as z15 } from "zod";
2613
+ var PutObject = class extends OpenAPIRoute15 {
2280
2614
  schema = {
2281
2615
  operationId: "post-bucket-upload-object",
2282
2616
  tags: ["Buckets"],
@@ -2285,20 +2619,20 @@ var PutObject = class extends OpenAPIRoute11 {
2285
2619
  body: {
2286
2620
  content: {
2287
2621
  "application/octet-stream": {
2288
- schema: z11.object({}).openapi({
2622
+ schema: z15.object({}).openapi({
2289
2623
  type: "string",
2290
2624
  format: "binary"
2291
2625
  })
2292
2626
  }
2293
2627
  }
2294
2628
  },
2295
- params: z11.object({
2296
- bucket: z11.string()
2629
+ params: z15.object({
2630
+ bucket: z15.string()
2297
2631
  }),
2298
- query: z11.object({
2299
- key: z11.string().describe("base64 encoded file key"),
2300
- customMetadata: z11.string().nullable().optional().describe("base64 encoded json string"),
2301
- httpMetadata: z11.string().nullable().optional().describe("base64 encoded json string")
2632
+ query: z15.object({
2633
+ key: z15.string().describe("base64 encoded file key"),
2634
+ customMetadata: z15.string().nullable().optional().describe("base64 encoded json string"),
2635
+ httpMetadata: z15.string().nullable().optional().describe("base64 encoded json string")
2302
2636
  })
2303
2637
  }
2304
2638
  };
@@ -2383,7 +2717,7 @@ async function streamToArrayBuffer(stream, streamSize) {
2383
2717
  }
2384
2718
  async function receiveEmail(event, env, ctx, config) {
2385
2719
  let bucket;
2386
- if (config?.emailRouting?.targetBucket && env[config.emailRouting.targetBucket]) {
2720
+ if (config?.emailRouting && typeof config.emailRouting === "object" && config.emailRouting.targetBucket && env[config.emailRouting.targetBucket]) {
2387
2721
  bucket = env[config.emailRouting.targetBucket];
2388
2722
  }
2389
2723
  if (!bucket) {
@@ -2423,9 +2757,9 @@ async function receiveEmail(event, env, ctx, config) {
2423
2757
  }
2424
2758
 
2425
2759
  // src/modules/emails/sendEmail.ts
2426
- import { OpenAPIRoute as OpenAPIRoute12, Str } from "chanfana";
2427
- import { z as z12 } from "zod";
2428
- var SendEmail = class extends OpenAPIRoute12 {
2760
+ import { OpenAPIRoute as OpenAPIRoute16, Str } from "chanfana";
2761
+ import { z as z16 } from "zod";
2762
+ var SendEmail = class extends OpenAPIRoute16 {
2429
2763
  schema = {
2430
2764
  operationId: "post-email-send",
2431
2765
  tags: ["Emails"],
@@ -2434,17 +2768,17 @@ var SendEmail = class extends OpenAPIRoute12 {
2434
2768
  body: {
2435
2769
  content: {
2436
2770
  "application/json": {
2437
- schema: z12.object({
2771
+ schema: z16.object({
2438
2772
  subject: Str({ example: "Look! No servers" }),
2439
- from: z12.object({
2773
+ from: z16.object({
2440
2774
  email: Str({ example: "sender@example.com" }),
2441
2775
  name: Str({ example: "Workers - MailChannels integration" })
2442
2776
  }),
2443
- to: z12.object({
2777
+ to: z16.object({
2444
2778
  email: Str({ example: "test@example.com" }),
2445
2779
  name: Str({ example: "Test Recipient" })
2446
2780
  }).array(),
2447
- content: z12.object({}).catchall(z12.string())
2781
+ content: z16.object({}).catchall(z16.string())
2448
2782
  })
2449
2783
  }
2450
2784
  }
@@ -2462,8 +2796,8 @@ var SendEmail = class extends OpenAPIRoute12 {
2462
2796
  };
2463
2797
 
2464
2798
  // src/modules/server/getInfo.ts
2465
- import { OpenAPIRoute as OpenAPIRoute13 } from "chanfana";
2466
- var GetInfo = class extends OpenAPIRoute13 {
2799
+ import { OpenAPIRoute as OpenAPIRoute17 } from "chanfana";
2800
+ var GetInfo = class extends OpenAPIRoute17 {
2467
2801
  schema = {
2468
2802
  operationId: "get-server-info",
2469
2803
  tags: ["Server"],
@@ -2473,7 +2807,7 @@ var GetInfo = class extends OpenAPIRoute13 {
2473
2807
  const { basicAuth: basicAuth2, ...config } = c.get("config");
2474
2808
  const buckets = [];
2475
2809
  for (const [key, value] of Object.entries(c.env)) {
2476
- if (value.get && value.put && value.get.toString().includes("function") && value.put.toString().includes("function")) {
2810
+ if (value && typeof value === "object" && "get" in value && "put" in value && "list" in value && typeof value.get === "function" && typeof value.put === "function" && typeof value.list === "function") {
2477
2811
  buckets.push({ name: key });
2478
2812
  }
2479
2813
  }
@@ -2491,7 +2825,7 @@ var GetInfo = class extends OpenAPIRoute13 {
2491
2825
 
2492
2826
  // src/index.ts
2493
2827
  function R2Explorer(config) {
2494
- extendZodWithOpenApi(z13);
2828
+ extendZodWithOpenApi(z17);
2495
2829
  config = config || {};
2496
2830
  if (config.readonly !== false) config.readonly = true;
2497
2831
  const openapiSchema = {
@@ -2566,9 +2900,13 @@ function R2Explorer(config) {
2566
2900
  openapi.post("/api/buckets/:bucket/delete", DeleteObject);
2567
2901
  openapi.on("head", "/api/buckets/:bucket/:key", HeadObject);
2568
2902
  openapi.get("/api/buckets/:bucket/:key/head", HeadObject);
2903
+ openapi.post("/api/buckets/:bucket/:key/share", CreateShareLink);
2904
+ openapi.get("/api/buckets/:bucket/shares", ListShares);
2905
+ openapi.delete("/api/buckets/:bucket/share/:shareId", DeleteShareLink);
2569
2906
  openapi.get("/api/buckets/:bucket/:key", GetObject);
2570
2907
  openapi.post("/api/buckets/:bucket/:key", PutMetadata);
2571
2908
  openapi.post("/api/emails/send", SendEmail);
2909
+ openapi.get("/share/:shareId", GetShareLink);
2572
2910
  openapi.get("/", dashboardIndex);
2573
2911
  openapi.get("*", dashboardRedirect);
2574
2912
  app.all(