r2-explorer 1.1.10 → 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.
- package/README.md +1 -0
- package/dashboard/assets/{AuthLayout.44d95d02.js → AuthLayout.0d7701f7.js} +1 -1
- package/dashboard/assets/EmailFilePage.12cbd72f.js +2 -0
- package/dashboard/assets/ErrorNotFound.edf4fcea.js +1 -0
- package/dashboard/{spa/assets/LoginPage.ca226917.js → assets/LoginPage.55d653ae.js} +1 -1
- package/dashboard/assets/{auth-store.c1556190.js → auth-store.a55ef8b1.js} +1 -1
- package/dashboard/assets/{auth.e242b7eb.js → auth.7340ecd2.js} +1 -1
- package/dashboard/assets/{bus.4a606b2f.js → bus.88084376.js} +1 -1
- package/dashboard/assets/{index.a1f775a6.css → index.4aacbd79.css} +1 -1
- package/dashboard/assets/{index.706c4d3e.js → index.a267d362.js} +28 -28
- package/dashboard/index.html +2 -2
- package/dashboard/spa/assets/{AuthLayout.44d95d02.js → AuthLayout.0d7701f7.js} +1 -1
- package/dashboard/spa/assets/EmailFilePage.12cbd72f.js +2 -0
- package/dashboard/spa/assets/ErrorNotFound.edf4fcea.js +1 -0
- package/dashboard/{assets/LoginPage.ca226917.js → spa/assets/LoginPage.55d653ae.js} +1 -1
- package/dashboard/spa/assets/{auth-store.c1556190.js → auth-store.a55ef8b1.js} +1 -1
- package/dashboard/spa/assets/{auth.e242b7eb.js → auth.7340ecd2.js} +1 -1
- package/dashboard/spa/assets/{bus.4a606b2f.js → bus.88084376.js} +1 -1
- package/dashboard/spa/assets/{index.a1f775a6.css → index.4aacbd79.css} +1 -1
- package/dashboard/spa/assets/{index.706c4d3e.js → index.a267d362.js} +28 -28
- package/dashboard/spa/index.html +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +792 -454
- package/dist/index.mjs +782 -444
- package/package.json +15 -15
- package/dashboard/assets/EmailFilePage.ccbeefd3.js +0 -2
- package/dashboard/assets/ErrorNotFound.19a254c5.js +0 -1
- package/dashboard/spa/assets/EmailFilePage.ccbeefd3.js +0 -2
- package/dashboard/spa/assets/ErrorNotFound.19a254c5.js +0 -1
package/dist/index.js
CHANGED
|
@@ -28,15 +28,85 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
33
|
R2Explorer: () => R2Explorer
|
|
34
34
|
});
|
|
35
|
-
module.exports = __toCommonJS(
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
var import_cloudflare_access = require("@hono/cloudflare-access");
|
|
37
|
-
var
|
|
37
|
+
var import_chanfana18 = require("chanfana");
|
|
38
|
+
|
|
39
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/compose.js
|
|
40
|
+
var compose = (middleware, onError, onNotFound) => {
|
|
41
|
+
return (context, next) => {
|
|
42
|
+
let index = -1;
|
|
43
|
+
return dispatch(0);
|
|
44
|
+
async function dispatch(i) {
|
|
45
|
+
if (i <= index) {
|
|
46
|
+
throw new Error("next() called multiple times");
|
|
47
|
+
}
|
|
48
|
+
index = i;
|
|
49
|
+
let res;
|
|
50
|
+
let isError = false;
|
|
51
|
+
let handler;
|
|
52
|
+
if (middleware[i]) {
|
|
53
|
+
handler = middleware[i][0][0];
|
|
54
|
+
context.req.routeIndex = i;
|
|
55
|
+
} else {
|
|
56
|
+
handler = i === middleware.length && next || void 0;
|
|
57
|
+
}
|
|
58
|
+
if (handler) {
|
|
59
|
+
try {
|
|
60
|
+
res = await handler(context, () => dispatch(i + 1));
|
|
61
|
+
} catch (err) {
|
|
62
|
+
if (err instanceof Error && onError) {
|
|
63
|
+
context.error = err;
|
|
64
|
+
res = await onError(err, context);
|
|
65
|
+
isError = true;
|
|
66
|
+
} else {
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
if (context.finalized === false && onNotFound) {
|
|
72
|
+
res = await onNotFound(context);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (res && (context.finalized === false || isError)) {
|
|
76
|
+
context.res = res;
|
|
77
|
+
}
|
|
78
|
+
return context;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/http-exception.js
|
|
84
|
+
var HTTPException = class extends Error {
|
|
85
|
+
res;
|
|
86
|
+
status;
|
|
87
|
+
constructor(status = 500, options) {
|
|
88
|
+
super(options?.message, { cause: options?.cause });
|
|
89
|
+
this.res = options?.res;
|
|
90
|
+
this.status = status;
|
|
91
|
+
}
|
|
92
|
+
getResponse() {
|
|
93
|
+
if (this.res) {
|
|
94
|
+
const newResponse = new Response(this.res.body, {
|
|
95
|
+
status: this.status,
|
|
96
|
+
headers: this.res.headers
|
|
97
|
+
});
|
|
98
|
+
return newResponse;
|
|
99
|
+
}
|
|
100
|
+
return new Response(this.message, {
|
|
101
|
+
status: this.status
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
};
|
|
38
105
|
|
|
39
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
106
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/request/constants.js
|
|
107
|
+
var GET_MATCH_RESULT = Symbol();
|
|
108
|
+
|
|
109
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/body.js
|
|
40
110
|
var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
|
|
41
111
|
const { all = false, dot = false } = options;
|
|
42
112
|
const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
|
|
@@ -83,7 +153,11 @@ var handleParsingAllValues = (form, key, value) => {
|
|
|
83
153
|
form[key] = [form[key], value];
|
|
84
154
|
}
|
|
85
155
|
} else {
|
|
86
|
-
|
|
156
|
+
if (!key.endsWith("[]")) {
|
|
157
|
+
form[key] = value;
|
|
158
|
+
} else {
|
|
159
|
+
form[key] = [value];
|
|
160
|
+
}
|
|
87
161
|
}
|
|
88
162
|
};
|
|
89
163
|
var handleParsingNestedValues = (form, key, value) => {
|
|
@@ -101,7 +175,7 @@ var handleParsingNestedValues = (form, key, value) => {
|
|
|
101
175
|
});
|
|
102
176
|
};
|
|
103
177
|
|
|
104
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
178
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/url.js
|
|
105
179
|
var splitPath = (path) => {
|
|
106
180
|
const paths = path.split("/");
|
|
107
181
|
if (paths[0] === "") {
|
|
@@ -116,9 +190,9 @@ var splitRoutingPath = (routePath) => {
|
|
|
116
190
|
};
|
|
117
191
|
var extractGroupsFromPath = (path) => {
|
|
118
192
|
const groups = [];
|
|
119
|
-
path = path.replace(/\{[^}]+\}/g, (
|
|
193
|
+
path = path.replace(/\{[^}]+\}/g, (match2, index) => {
|
|
120
194
|
const mark = `@${index}`;
|
|
121
|
-
groups.push([mark,
|
|
195
|
+
groups.push([mark, match2]);
|
|
122
196
|
return mark;
|
|
123
197
|
});
|
|
124
198
|
return { groups, path };
|
|
@@ -136,20 +210,21 @@ var replaceGroupMarks = (paths, groups) => {
|
|
|
136
210
|
return paths;
|
|
137
211
|
};
|
|
138
212
|
var patternCache = {};
|
|
139
|
-
var getPattern = (label) => {
|
|
213
|
+
var getPattern = (label, next) => {
|
|
140
214
|
if (label === "*") {
|
|
141
215
|
return "*";
|
|
142
216
|
}
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
217
|
+
const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
|
218
|
+
if (match2) {
|
|
219
|
+
const cacheKey = `${label}#${next}`;
|
|
220
|
+
if (!patternCache[cacheKey]) {
|
|
221
|
+
if (match2[2]) {
|
|
222
|
+
patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)];
|
|
148
223
|
} else {
|
|
149
|
-
patternCache[
|
|
224
|
+
patternCache[cacheKey] = [label, match2[1], true];
|
|
150
225
|
}
|
|
151
226
|
}
|
|
152
|
-
return patternCache[
|
|
227
|
+
return patternCache[cacheKey];
|
|
153
228
|
}
|
|
154
229
|
return null;
|
|
155
230
|
};
|
|
@@ -157,11 +232,11 @@ var tryDecode = (str, decoder) => {
|
|
|
157
232
|
try {
|
|
158
233
|
return decoder(str);
|
|
159
234
|
} catch {
|
|
160
|
-
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (
|
|
235
|
+
return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
|
|
161
236
|
try {
|
|
162
|
-
return decoder(
|
|
237
|
+
return decoder(match2);
|
|
163
238
|
} catch {
|
|
164
|
-
return
|
|
239
|
+
return match2;
|
|
165
240
|
}
|
|
166
241
|
});
|
|
167
242
|
}
|
|
@@ -169,7 +244,7 @@ var tryDecode = (str, decoder) => {
|
|
|
169
244
|
var tryDecodeURI = (str) => tryDecode(str, decodeURI);
|
|
170
245
|
var getPath = (request) => {
|
|
171
246
|
const url = request.url;
|
|
172
|
-
const start = url.indexOf("/",
|
|
247
|
+
const start = url.indexOf("/", url.indexOf(":") + 4);
|
|
173
248
|
let i = start;
|
|
174
249
|
for (; i < url.length; i++) {
|
|
175
250
|
const charCode = url.charCodeAt(i);
|
|
@@ -187,30 +262,14 @@ var getPathNoStrict = (request) => {
|
|
|
187
262
|
const result = getPath(request);
|
|
188
263
|
return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
|
|
189
264
|
};
|
|
190
|
-
var mergePath = (...
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
for (let path of paths) {
|
|
194
|
-
if (p.at(-1) === "/") {
|
|
195
|
-
p = p.slice(0, -1);
|
|
196
|
-
endsWithSlash = true;
|
|
197
|
-
}
|
|
198
|
-
if (path[0] !== "/") {
|
|
199
|
-
path = `/${path}`;
|
|
200
|
-
}
|
|
201
|
-
if (path === "/" && endsWithSlash) {
|
|
202
|
-
p = `${p}/`;
|
|
203
|
-
} else if (path !== "/") {
|
|
204
|
-
p = `${p}${path}`;
|
|
205
|
-
}
|
|
206
|
-
if (path === "/" && p === "") {
|
|
207
|
-
p = "/";
|
|
208
|
-
}
|
|
265
|
+
var mergePath = (base, sub, ...rest) => {
|
|
266
|
+
if (rest.length) {
|
|
267
|
+
sub = mergePath(sub, ...rest);
|
|
209
268
|
}
|
|
210
|
-
return
|
|
269
|
+
return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
|
|
211
270
|
};
|
|
212
271
|
var checkOptionalParameter = (path) => {
|
|
213
|
-
if (!path.
|
|
272
|
+
if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) {
|
|
214
273
|
return null;
|
|
215
274
|
}
|
|
216
275
|
const segments = path.split("/");
|
|
@@ -243,14 +302,17 @@ var _decodeURI = (value) => {
|
|
|
243
302
|
if (value.indexOf("+") !== -1) {
|
|
244
303
|
value = value.replace(/\+/g, " ");
|
|
245
304
|
}
|
|
246
|
-
return value.indexOf("%") !== -1 ?
|
|
305
|
+
return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
|
|
247
306
|
};
|
|
248
307
|
var _getQueryParam = (url, key, multiple) => {
|
|
249
308
|
let encoded;
|
|
250
309
|
if (!multiple && key && !/[%+]/.test(key)) {
|
|
251
|
-
let keyIndex2 = url.indexOf(
|
|
310
|
+
let keyIndex2 = url.indexOf("?", 8);
|
|
252
311
|
if (keyIndex2 === -1) {
|
|
253
|
-
|
|
312
|
+
return void 0;
|
|
313
|
+
}
|
|
314
|
+
if (!url.startsWith(key, keyIndex2 + 1)) {
|
|
315
|
+
keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
|
|
254
316
|
}
|
|
255
317
|
while (keyIndex2 !== -1) {
|
|
256
318
|
const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
|
|
@@ -315,7 +377,7 @@ var getQueryParams = (url, key) => {
|
|
|
315
377
|
};
|
|
316
378
|
var decodeURIComponent_ = decodeURIComponent;
|
|
317
379
|
|
|
318
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
380
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/request.js
|
|
319
381
|
var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
|
|
320
382
|
var HonoRequest = class {
|
|
321
383
|
raw;
|
|
@@ -336,14 +398,14 @@ var HonoRequest = class {
|
|
|
336
398
|
#getDecodedParam(key) {
|
|
337
399
|
const paramKey = this.#matchResult[0][this.routeIndex][1][key];
|
|
338
400
|
const param = this.#getParamValue(paramKey);
|
|
339
|
-
return param
|
|
401
|
+
return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
|
|
340
402
|
}
|
|
341
403
|
#getAllDecodedParams() {
|
|
342
404
|
const decoded = {};
|
|
343
405
|
const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
|
|
344
406
|
for (const key of keys) {
|
|
345
407
|
const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
|
|
346
|
-
if (value
|
|
408
|
+
if (value !== void 0) {
|
|
347
409
|
decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
|
|
348
410
|
}
|
|
349
411
|
}
|
|
@@ -360,7 +422,7 @@ var HonoRequest = class {
|
|
|
360
422
|
}
|
|
361
423
|
header(name) {
|
|
362
424
|
if (name) {
|
|
363
|
-
return this.raw.headers.get(name
|
|
425
|
+
return this.raw.headers.get(name) ?? void 0;
|
|
364
426
|
}
|
|
365
427
|
const headerData = {};
|
|
366
428
|
this.raw.headers.forEach((value, key) => {
|
|
@@ -389,7 +451,7 @@ var HonoRequest = class {
|
|
|
389
451
|
return bodyCache[key] = raw2[key]();
|
|
390
452
|
};
|
|
391
453
|
json() {
|
|
392
|
-
return this.#cachedBody("
|
|
454
|
+
return this.#cachedBody("text").then((text) => JSON.parse(text));
|
|
393
455
|
}
|
|
394
456
|
text() {
|
|
395
457
|
return this.#cachedBody("text");
|
|
@@ -415,6 +477,9 @@ var HonoRequest = class {
|
|
|
415
477
|
get method() {
|
|
416
478
|
return this.raw.method;
|
|
417
479
|
}
|
|
480
|
+
get [GET_MATCH_RESULT]() {
|
|
481
|
+
return this.#matchResult;
|
|
482
|
+
}
|
|
418
483
|
get matchedRoutes() {
|
|
419
484
|
return this.#matchResult[0].map(([[, route]]) => route);
|
|
420
485
|
}
|
|
@@ -423,7 +488,7 @@ var HonoRequest = class {
|
|
|
423
488
|
}
|
|
424
489
|
};
|
|
425
490
|
|
|
426
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
491
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/html.js
|
|
427
492
|
var HtmlEscapedCallbackPhase = {
|
|
428
493
|
Stringify: 1,
|
|
429
494
|
BeforeStream: 2,
|
|
@@ -465,13 +530,13 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
|
|
|
465
530
|
}
|
|
466
531
|
};
|
|
467
532
|
|
|
468
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
533
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/context.js
|
|
469
534
|
var TEXT_PLAIN = "text/plain; charset=UTF-8";
|
|
470
|
-
var
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
535
|
+
var setDefaultContentType = (contentType, headers) => {
|
|
536
|
+
return {
|
|
537
|
+
"Content-Type": contentType,
|
|
538
|
+
...headers
|
|
539
|
+
};
|
|
475
540
|
};
|
|
476
541
|
var Context = class {
|
|
477
542
|
#rawRequest;
|
|
@@ -480,15 +545,13 @@ var Context = class {
|
|
|
480
545
|
#var;
|
|
481
546
|
finalized = false;
|
|
482
547
|
error;
|
|
483
|
-
#status
|
|
548
|
+
#status;
|
|
484
549
|
#executionCtx;
|
|
485
|
-
#headers;
|
|
486
|
-
#preparedHeaders;
|
|
487
550
|
#res;
|
|
488
|
-
#isFresh = true;
|
|
489
551
|
#layout;
|
|
490
552
|
#renderer;
|
|
491
553
|
#notFoundHandler;
|
|
554
|
+
#preparedHeaders;
|
|
492
555
|
#matchResult;
|
|
493
556
|
#path;
|
|
494
557
|
constructor(req, options) {
|
|
@@ -520,36 +583,25 @@ var Context = class {
|
|
|
520
583
|
}
|
|
521
584
|
}
|
|
522
585
|
get res() {
|
|
523
|
-
this.#
|
|
524
|
-
|
|
586
|
+
return this.#res ||= new Response(null, {
|
|
587
|
+
headers: this.#preparedHeaders ??= new Headers()
|
|
588
|
+
});
|
|
525
589
|
}
|
|
526
590
|
set res(_res) {
|
|
527
|
-
this.#isFresh = false;
|
|
528
591
|
if (this.#res && _res) {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
if (k === "set-cookie") {
|
|
535
|
-
const cookies = this.#res.headers.getSetCookie();
|
|
536
|
-
_res.headers.delete("set-cookie");
|
|
537
|
-
for (const cookie of cookies) {
|
|
538
|
-
_res.headers.append("set-cookie", cookie);
|
|
539
|
-
}
|
|
540
|
-
} else {
|
|
541
|
-
_res.headers.set(k, v);
|
|
542
|
-
}
|
|
592
|
+
_res = new Response(_res.body, _res);
|
|
593
|
+
for (const [k, v] of this.#res.headers.entries()) {
|
|
594
|
+
if (k === "content-type") {
|
|
595
|
+
continue;
|
|
543
596
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
}
|
|
550
|
-
return;
|
|
597
|
+
if (k === "set-cookie") {
|
|
598
|
+
const cookies = this.#res.headers.getSetCookie();
|
|
599
|
+
_res.headers.delete("set-cookie");
|
|
600
|
+
for (const cookie of cookies) {
|
|
601
|
+
_res.headers.append("set-cookie", cookie);
|
|
602
|
+
}
|
|
551
603
|
} else {
|
|
552
|
-
|
|
604
|
+
_res.headers.set(k, v);
|
|
553
605
|
}
|
|
554
606
|
}
|
|
555
607
|
}
|
|
@@ -566,42 +618,19 @@ var Context = class {
|
|
|
566
618
|
this.#renderer = renderer;
|
|
567
619
|
};
|
|
568
620
|
header = (name, value, options) => {
|
|
569
|
-
if (
|
|
570
|
-
|
|
571
|
-
this.#headers.delete(name);
|
|
572
|
-
} else if (this.#preparedHeaders) {
|
|
573
|
-
delete this.#preparedHeaders[name.toLocaleLowerCase()];
|
|
574
|
-
}
|
|
575
|
-
if (this.finalized) {
|
|
576
|
-
this.res.headers.delete(name);
|
|
577
|
-
}
|
|
578
|
-
return;
|
|
621
|
+
if (this.finalized) {
|
|
622
|
+
this.#res = new Response(this.#res.body, this.#res);
|
|
579
623
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
}
|
|
586
|
-
this.#headers.append(name, value);
|
|
624
|
+
const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();
|
|
625
|
+
if (value === void 0) {
|
|
626
|
+
headers.delete(name);
|
|
627
|
+
} else if (options?.append) {
|
|
628
|
+
headers.append(name, value);
|
|
587
629
|
} else {
|
|
588
|
-
|
|
589
|
-
this.#headers.set(name, value);
|
|
590
|
-
} else {
|
|
591
|
-
this.#preparedHeaders ??= {};
|
|
592
|
-
this.#preparedHeaders[name.toLowerCase()] = value;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
if (this.finalized) {
|
|
596
|
-
if (options?.append) {
|
|
597
|
-
this.res.headers.append(name, value);
|
|
598
|
-
} else {
|
|
599
|
-
this.res.headers.set(name, value);
|
|
600
|
-
}
|
|
630
|
+
headers.set(name, value);
|
|
601
631
|
}
|
|
602
632
|
};
|
|
603
633
|
status = (status) => {
|
|
604
|
-
this.#isFresh = false;
|
|
605
634
|
this.#status = status;
|
|
606
635
|
};
|
|
607
636
|
set = (key, value) => {
|
|
@@ -618,94 +647,58 @@ var Context = class {
|
|
|
618
647
|
return Object.fromEntries(this.#var);
|
|
619
648
|
}
|
|
620
649
|
#newResponse(data, arg, headers) {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
const header = new Headers(arg.headers);
|
|
628
|
-
if (this.#headers) {
|
|
629
|
-
this.#headers.forEach((v, k) => {
|
|
630
|
-
if (k === "set-cookie") {
|
|
631
|
-
header.append(k, v);
|
|
632
|
-
} else {
|
|
633
|
-
header.set(k, v);
|
|
634
|
-
}
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
const headers2 = setHeaders(header, this.#preparedHeaders);
|
|
638
|
-
return new Response(data, {
|
|
639
|
-
headers: headers2,
|
|
640
|
-
status: arg.status ?? this.#status
|
|
641
|
-
});
|
|
642
|
-
}
|
|
643
|
-
const status = typeof arg === "number" ? arg : this.#status;
|
|
644
|
-
this.#preparedHeaders ??= {};
|
|
645
|
-
this.#headers ??= new Headers();
|
|
646
|
-
setHeaders(this.#headers, this.#preparedHeaders);
|
|
647
|
-
if (this.#res) {
|
|
648
|
-
this.#res.headers.forEach((v, k) => {
|
|
649
|
-
if (k === "set-cookie") {
|
|
650
|
-
this.#headers?.append(k, v);
|
|
650
|
+
const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();
|
|
651
|
+
if (typeof arg === "object" && "headers" in arg) {
|
|
652
|
+
const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
|
|
653
|
+
for (const [key, value] of argHeaders) {
|
|
654
|
+
if (key.toLowerCase() === "set-cookie") {
|
|
655
|
+
responseHeaders.append(key, value);
|
|
651
656
|
} else {
|
|
652
|
-
|
|
657
|
+
responseHeaders.set(key, value);
|
|
653
658
|
}
|
|
654
|
-
}
|
|
655
|
-
setHeaders(this.#headers, this.#preparedHeaders);
|
|
659
|
+
}
|
|
656
660
|
}
|
|
657
|
-
headers
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
661
|
+
if (headers) {
|
|
662
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
663
|
+
if (typeof v === "string") {
|
|
664
|
+
responseHeaders.set(k, v);
|
|
665
|
+
} else {
|
|
666
|
+
responseHeaders.delete(k);
|
|
667
|
+
for (const v2 of v) {
|
|
668
|
+
responseHeaders.append(k, v2);
|
|
669
|
+
}
|
|
665
670
|
}
|
|
666
671
|
}
|
|
667
672
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
headers: this.#headers
|
|
671
|
-
});
|
|
673
|
+
const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
|
|
674
|
+
return new Response(data, { status, headers: responseHeaders });
|
|
672
675
|
}
|
|
673
676
|
newResponse = (...args) => this.#newResponse(...args);
|
|
674
|
-
body = (data, arg, headers) =>
|
|
675
|
-
return typeof arg === "number" ? this.#newResponse(data, arg, headers) : this.#newResponse(data, arg);
|
|
676
|
-
};
|
|
677
|
+
body = (data, arg, headers) => this.#newResponse(data, arg, headers);
|
|
677
678
|
text = (text, arg, headers) => {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
}
|
|
684
|
-
this.#preparedHeaders["content-type"] = TEXT_PLAIN;
|
|
685
|
-
if (typeof arg === "number") {
|
|
686
|
-
return this.#newResponse(text, arg, headers);
|
|
687
|
-
}
|
|
688
|
-
return this.#newResponse(text, arg);
|
|
679
|
+
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
|
|
680
|
+
text,
|
|
681
|
+
arg,
|
|
682
|
+
setDefaultContentType(TEXT_PLAIN, headers)
|
|
683
|
+
);
|
|
689
684
|
};
|
|
690
685
|
json = (object, arg, headers) => {
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
686
|
+
return this.#newResponse(
|
|
687
|
+
JSON.stringify(object),
|
|
688
|
+
arg,
|
|
689
|
+
setDefaultContentType("application/json", headers)
|
|
690
|
+
);
|
|
695
691
|
};
|
|
696
692
|
html = (html, arg, headers) => {
|
|
697
|
-
this.#
|
|
698
|
-
|
|
699
|
-
if (typeof html === "object") {
|
|
700
|
-
return resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then((html2) => {
|
|
701
|
-
return typeof arg === "number" ? this.#newResponse(html2, arg, headers) : this.#newResponse(html2, arg);
|
|
702
|
-
});
|
|
703
|
-
}
|
|
704
|
-
return typeof arg === "number" ? this.#newResponse(html, arg, headers) : this.#newResponse(html, arg);
|
|
693
|
+
const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
|
|
694
|
+
return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
|
|
705
695
|
};
|
|
706
696
|
redirect = (location, status) => {
|
|
707
|
-
|
|
708
|
-
this
|
|
697
|
+
const locationString = String(location);
|
|
698
|
+
this.header(
|
|
699
|
+
"Location",
|
|
700
|
+
!/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
|
|
701
|
+
);
|
|
709
702
|
return this.newResponse(null, status ?? 302);
|
|
710
703
|
};
|
|
711
704
|
notFound = () => {
|
|
@@ -714,56 +707,7 @@ var Context = class {
|
|
|
714
707
|
};
|
|
715
708
|
};
|
|
716
709
|
|
|
717
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
718
|
-
var compose = (middleware, onError, onNotFound) => {
|
|
719
|
-
return (context, next) => {
|
|
720
|
-
let index = -1;
|
|
721
|
-
const isContext = context instanceof Context;
|
|
722
|
-
return dispatch(0);
|
|
723
|
-
async function dispatch(i) {
|
|
724
|
-
if (i <= index) {
|
|
725
|
-
throw new Error("next() called multiple times");
|
|
726
|
-
}
|
|
727
|
-
index = i;
|
|
728
|
-
let res;
|
|
729
|
-
let isError = false;
|
|
730
|
-
let handler;
|
|
731
|
-
if (middleware[i]) {
|
|
732
|
-
handler = middleware[i][0][0];
|
|
733
|
-
if (isContext) {
|
|
734
|
-
context.req.routeIndex = i;
|
|
735
|
-
}
|
|
736
|
-
} else {
|
|
737
|
-
handler = i === middleware.length && next || void 0;
|
|
738
|
-
}
|
|
739
|
-
if (!handler) {
|
|
740
|
-
if (isContext && context.finalized === false && onNotFound) {
|
|
741
|
-
res = await onNotFound(context);
|
|
742
|
-
}
|
|
743
|
-
} else {
|
|
744
|
-
try {
|
|
745
|
-
res = await handler(context, () => {
|
|
746
|
-
return dispatch(i + 1);
|
|
747
|
-
});
|
|
748
|
-
} catch (err) {
|
|
749
|
-
if (err instanceof Error && isContext && onError) {
|
|
750
|
-
context.error = err;
|
|
751
|
-
res = await onError(err, context);
|
|
752
|
-
isError = true;
|
|
753
|
-
} else {
|
|
754
|
-
throw err;
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
if (res && (context.finalized === false || isError)) {
|
|
759
|
-
context.res = res;
|
|
760
|
-
}
|
|
761
|
-
return context;
|
|
762
|
-
}
|
|
763
|
-
};
|
|
764
|
-
};
|
|
765
|
-
|
|
766
|
-
// ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/router.js
|
|
710
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router.js
|
|
767
711
|
var METHOD_NAME_ALL = "ALL";
|
|
768
712
|
var METHOD_NAME_ALL_LOWERCASE = "all";
|
|
769
713
|
var METHODS = ["get", "post", "put", "delete", "options", "patch"];
|
|
@@ -771,16 +715,17 @@ var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is
|
|
|
771
715
|
var UnsupportedPathError = class extends Error {
|
|
772
716
|
};
|
|
773
717
|
|
|
774
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
718
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/constants.js
|
|
775
719
|
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
|
776
720
|
|
|
777
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
721
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/hono-base.js
|
|
778
722
|
var notFoundHandler = (c) => {
|
|
779
723
|
return c.text("404 Not Found", 404);
|
|
780
724
|
};
|
|
781
725
|
var errorHandler = (err, c) => {
|
|
782
726
|
if ("getResponse" in err) {
|
|
783
|
-
|
|
727
|
+
const res = err.getResponse();
|
|
728
|
+
return c.newResponse(res.body, res);
|
|
784
729
|
}
|
|
785
730
|
console.error(err);
|
|
786
731
|
return c.text("Internal Server Error", 500);
|
|
@@ -838,16 +783,17 @@ var Hono = class {
|
|
|
838
783
|
});
|
|
839
784
|
return this;
|
|
840
785
|
};
|
|
841
|
-
const strict = options
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
this.getPath = strict ? options.getPath ?? getPath : getPathNoStrict;
|
|
786
|
+
const { strict, ...optionsWithoutStrict } = options;
|
|
787
|
+
Object.assign(this, optionsWithoutStrict);
|
|
788
|
+
this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
|
|
845
789
|
}
|
|
846
790
|
#clone() {
|
|
847
791
|
const clone = new Hono({
|
|
848
792
|
router: this.router,
|
|
849
793
|
getPath: this.getPath
|
|
850
794
|
});
|
|
795
|
+
clone.errorHandler = this.errorHandler;
|
|
796
|
+
clone.#notFoundHandler = this.#notFoundHandler;
|
|
851
797
|
clone.routes = this.routes;
|
|
852
798
|
return clone;
|
|
853
799
|
}
|
|
@@ -888,7 +834,11 @@ var Hono = class {
|
|
|
888
834
|
optionHandler = options;
|
|
889
835
|
} else {
|
|
890
836
|
optionHandler = options.optionHandler;
|
|
891
|
-
|
|
837
|
+
if (options.replaceRequest === false) {
|
|
838
|
+
replaceRequest = (request) => request;
|
|
839
|
+
} else {
|
|
840
|
+
replaceRequest = options.replaceRequest;
|
|
841
|
+
}
|
|
892
842
|
}
|
|
893
843
|
}
|
|
894
844
|
const getOptions = optionHandler ? (c) => {
|
|
@@ -924,7 +874,7 @@ var Hono = class {
|
|
|
924
874
|
#addRoute(method, path, handler) {
|
|
925
875
|
method = method.toUpperCase();
|
|
926
876
|
path = mergePath(this._basePath, path);
|
|
927
|
-
const r = { path, method, handler };
|
|
877
|
+
const r = { basePath: this._basePath, path, method, handler };
|
|
928
878
|
this.router.add(method, path, [handler, r]);
|
|
929
879
|
this.routes.push(r);
|
|
930
880
|
}
|
|
@@ -999,7 +949,28 @@ var Hono = class {
|
|
|
999
949
|
};
|
|
1000
950
|
};
|
|
1001
951
|
|
|
1002
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
952
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/matcher.js
|
|
953
|
+
var emptyParam = [];
|
|
954
|
+
function match(method, path) {
|
|
955
|
+
const matchers = this.buildAllMatchers();
|
|
956
|
+
const match2 = (method2, path2) => {
|
|
957
|
+
const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
|
|
958
|
+
const staticMatch = matcher[2][path2];
|
|
959
|
+
if (staticMatch) {
|
|
960
|
+
return staticMatch;
|
|
961
|
+
}
|
|
962
|
+
const match3 = path2.match(matcher[0]);
|
|
963
|
+
if (!match3) {
|
|
964
|
+
return [[], emptyParam];
|
|
965
|
+
}
|
|
966
|
+
const index = match3.indexOf("", 1);
|
|
967
|
+
return [matcher[1][index], match3];
|
|
968
|
+
};
|
|
969
|
+
this.match = match2;
|
|
970
|
+
return match2(method, path);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/node.js
|
|
1003
974
|
var LABEL_REG_EXP_STR = "[^/]+";
|
|
1004
975
|
var ONLY_WILDCARD_REG_EXP_STR = ".*";
|
|
1005
976
|
var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
|
|
@@ -1046,6 +1017,9 @@ var Node = class {
|
|
|
1046
1017
|
const name = pattern[1];
|
|
1047
1018
|
let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
|
|
1048
1019
|
if (name && pattern[2]) {
|
|
1020
|
+
if (regexpStr === ".*") {
|
|
1021
|
+
throw PATH_ERROR;
|
|
1022
|
+
}
|
|
1049
1023
|
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
|
1050
1024
|
if (/\((?!\?:)/.test(regexpStr)) {
|
|
1051
1025
|
throw PATH_ERROR;
|
|
@@ -1104,7 +1078,7 @@ var Node = class {
|
|
|
1104
1078
|
}
|
|
1105
1079
|
};
|
|
1106
1080
|
|
|
1107
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1081
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/trie.js
|
|
1108
1082
|
var Trie = class {
|
|
1109
1083
|
#context = { varIndex: 0 };
|
|
1110
1084
|
#root = new Node();
|
|
@@ -1160,8 +1134,7 @@ var Trie = class {
|
|
|
1160
1134
|
}
|
|
1161
1135
|
};
|
|
1162
1136
|
|
|
1163
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1164
|
-
var emptyParam = [];
|
|
1137
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/reg-exp-router/router.js
|
|
1165
1138
|
var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
|
|
1166
1139
|
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
1167
1140
|
function buildWildcardRegExp(path) {
|
|
@@ -1308,30 +1281,14 @@ var RegExpRouter = class {
|
|
|
1308
1281
|
});
|
|
1309
1282
|
}
|
|
1310
1283
|
}
|
|
1311
|
-
match
|
|
1312
|
-
|
|
1313
|
-
const matchers = this.#buildAllMatchers();
|
|
1314
|
-
this.match = (method2, path2) => {
|
|
1315
|
-
const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
|
|
1316
|
-
const staticMatch = matcher[2][path2];
|
|
1317
|
-
if (staticMatch) {
|
|
1318
|
-
return staticMatch;
|
|
1319
|
-
}
|
|
1320
|
-
const match = path2.match(matcher[0]);
|
|
1321
|
-
if (!match) {
|
|
1322
|
-
return [[], emptyParam];
|
|
1323
|
-
}
|
|
1324
|
-
const index = match.indexOf("", 1);
|
|
1325
|
-
return [matcher[1][index], match];
|
|
1326
|
-
};
|
|
1327
|
-
return this.match(method, path);
|
|
1328
|
-
}
|
|
1329
|
-
#buildAllMatchers() {
|
|
1284
|
+
match = match;
|
|
1285
|
+
buildAllMatchers() {
|
|
1330
1286
|
const matchers = /* @__PURE__ */ Object.create(null);
|
|
1331
1287
|
Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
|
|
1332
1288
|
matchers[method] ||= this.#buildMatcher(method);
|
|
1333
1289
|
});
|
|
1334
1290
|
this.#middleware = this.#routes = void 0;
|
|
1291
|
+
clearWildcardRegExpCache();
|
|
1335
1292
|
return matchers;
|
|
1336
1293
|
}
|
|
1337
1294
|
#buildMatcher(method) {
|
|
@@ -1356,7 +1313,7 @@ var RegExpRouter = class {
|
|
|
1356
1313
|
}
|
|
1357
1314
|
};
|
|
1358
1315
|
|
|
1359
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1316
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/smart-router/router.js
|
|
1360
1317
|
var SmartRouter = class {
|
|
1361
1318
|
name = "SmartRouter";
|
|
1362
1319
|
#routers = [];
|
|
@@ -1411,7 +1368,7 @@ var SmartRouter = class {
|
|
|
1411
1368
|
}
|
|
1412
1369
|
};
|
|
1413
1370
|
|
|
1414
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1371
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/trie-router/node.js
|
|
1415
1372
|
var emptyParams = /* @__PURE__ */ Object.create(null);
|
|
1416
1373
|
var Node2 = class {
|
|
1417
1374
|
#methods;
|
|
@@ -1436,30 +1393,30 @@ var Node2 = class {
|
|
|
1436
1393
|
const possibleKeys = [];
|
|
1437
1394
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
1438
1395
|
const p = parts[i];
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1396
|
+
const nextP = parts[i + 1];
|
|
1397
|
+
const pattern = getPattern(p, nextP);
|
|
1398
|
+
const key = Array.isArray(pattern) ? pattern[0] : p;
|
|
1399
|
+
if (key in curNode.#children) {
|
|
1400
|
+
curNode = curNode.#children[key];
|
|
1401
|
+
if (pattern) {
|
|
1402
|
+
possibleKeys.push(pattern[1]);
|
|
1444
1403
|
}
|
|
1445
1404
|
continue;
|
|
1446
1405
|
}
|
|
1447
|
-
curNode.#children[
|
|
1448
|
-
const pattern = getPattern(p);
|
|
1406
|
+
curNode.#children[key] = new Node2();
|
|
1449
1407
|
if (pattern) {
|
|
1450
1408
|
curNode.#patterns.push(pattern);
|
|
1451
1409
|
possibleKeys.push(pattern[1]);
|
|
1452
1410
|
}
|
|
1453
|
-
curNode = curNode.#children[
|
|
1411
|
+
curNode = curNode.#children[key];
|
|
1454
1412
|
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
curNode.#methods.push(m);
|
|
1413
|
+
curNode.#methods.push({
|
|
1414
|
+
[method]: {
|
|
1415
|
+
handler,
|
|
1416
|
+
possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
|
|
1417
|
+
score: this.#order
|
|
1418
|
+
}
|
|
1419
|
+
});
|
|
1463
1420
|
return curNode;
|
|
1464
1421
|
}
|
|
1465
1422
|
#getHandlerSets(node, method, nodeParams, params) {
|
|
@@ -1489,6 +1446,7 @@ var Node2 = class {
|
|
|
1489
1446
|
const curNode = this;
|
|
1490
1447
|
let curNodes = [curNode];
|
|
1491
1448
|
const parts = splitPath(path);
|
|
1449
|
+
const curNodesQueue = [];
|
|
1492
1450
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
1493
1451
|
const part = parts[i];
|
|
1494
1452
|
const isLast = i === len - 1;
|
|
@@ -1516,20 +1474,30 @@ var Node2 = class {
|
|
|
1516
1474
|
const astNode = node.#children["*"];
|
|
1517
1475
|
if (astNode) {
|
|
1518
1476
|
handlerSets.push(...this.#getHandlerSets(astNode, method, node.#params));
|
|
1477
|
+
astNode.#params = params;
|
|
1519
1478
|
tempNodes.push(astNode);
|
|
1520
1479
|
}
|
|
1521
1480
|
continue;
|
|
1522
1481
|
}
|
|
1523
|
-
|
|
1482
|
+
const [key, name, matcher] = pattern;
|
|
1483
|
+
if (!part && !(matcher instanceof RegExp)) {
|
|
1524
1484
|
continue;
|
|
1525
1485
|
}
|
|
1526
|
-
const [key, name, matcher] = pattern;
|
|
1527
1486
|
const child = node.#children[key];
|
|
1528
1487
|
const restPathString = parts.slice(i).join("/");
|
|
1529
|
-
if (matcher instanceof RegExp
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1488
|
+
if (matcher instanceof RegExp) {
|
|
1489
|
+
const m = matcher.exec(restPathString);
|
|
1490
|
+
if (m) {
|
|
1491
|
+
params[name] = m[0];
|
|
1492
|
+
handlerSets.push(...this.#getHandlerSets(child, method, node.#params, params));
|
|
1493
|
+
if (Object.keys(child.#children).length) {
|
|
1494
|
+
child.#params = params;
|
|
1495
|
+
const componentCount = m[0].match(/\//)?.length ?? 0;
|
|
1496
|
+
const targetCurNodes = curNodesQueue[componentCount] ||= [];
|
|
1497
|
+
targetCurNodes.push(child);
|
|
1498
|
+
}
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1533
1501
|
}
|
|
1534
1502
|
if (matcher === true || matcher.test(part)) {
|
|
1535
1503
|
params[name] = part;
|
|
@@ -1547,7 +1515,7 @@ var Node2 = class {
|
|
|
1547
1515
|
}
|
|
1548
1516
|
}
|
|
1549
1517
|
}
|
|
1550
|
-
curNodes = tempNodes;
|
|
1518
|
+
curNodes = tempNodes.concat(curNodesQueue.shift() ?? []);
|
|
1551
1519
|
}
|
|
1552
1520
|
if (handlerSets.length > 1) {
|
|
1553
1521
|
handlerSets.sort((a, b) => {
|
|
@@ -1558,7 +1526,7 @@ var Node2 = class {
|
|
|
1558
1526
|
}
|
|
1559
1527
|
};
|
|
1560
1528
|
|
|
1561
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1529
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/router/trie-router/router.js
|
|
1562
1530
|
var TrieRouter = class {
|
|
1563
1531
|
name = "TrieRouter";
|
|
1564
1532
|
#node;
|
|
@@ -1580,7 +1548,7 @@ var TrieRouter = class {
|
|
|
1580
1548
|
}
|
|
1581
1549
|
};
|
|
1582
1550
|
|
|
1583
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1551
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/hono.js
|
|
1584
1552
|
var Hono2 = class extends Hono {
|
|
1585
1553
|
constructor(options = {}) {
|
|
1586
1554
|
super(options);
|
|
@@ -1590,30 +1558,7 @@ var Hono2 = class extends Hono {
|
|
|
1590
1558
|
}
|
|
1591
1559
|
};
|
|
1592
1560
|
|
|
1593
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1594
|
-
var HTTPException = class extends Error {
|
|
1595
|
-
res;
|
|
1596
|
-
status;
|
|
1597
|
-
constructor(status = 500, options) {
|
|
1598
|
-
super(options?.message, { cause: options?.cause });
|
|
1599
|
-
this.res = options?.res;
|
|
1600
|
-
this.status = status;
|
|
1601
|
-
}
|
|
1602
|
-
getResponse() {
|
|
1603
|
-
if (this.res) {
|
|
1604
|
-
const newResponse = new Response(this.res.body, {
|
|
1605
|
-
status: this.status,
|
|
1606
|
-
headers: this.res.headers
|
|
1607
|
-
});
|
|
1608
|
-
return newResponse;
|
|
1609
|
-
}
|
|
1610
|
-
return new Response(this.message, {
|
|
1611
|
-
status: this.status
|
|
1612
|
-
});
|
|
1613
|
-
}
|
|
1614
|
-
};
|
|
1615
|
-
|
|
1616
|
-
// ../../node_modules/.pnpm/hono@4.6.15/node_modules/hono/dist/utils/encode.js
|
|
1561
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/encode.js
|
|
1617
1562
|
var decodeBase64 = (str) => {
|
|
1618
1563
|
const binary = atob(str);
|
|
1619
1564
|
const bytes = new Uint8Array(new ArrayBuffer(binary.length));
|
|
@@ -1625,18 +1570,18 @@ var decodeBase64 = (str) => {
|
|
|
1625
1570
|
return bytes;
|
|
1626
1571
|
};
|
|
1627
1572
|
|
|
1628
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1573
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/basic-auth.js
|
|
1629
1574
|
var CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/;
|
|
1630
1575
|
var USER_PASS_REGEXP = /^([^:]*):(.*)$/;
|
|
1631
1576
|
var utf8Decoder = new TextDecoder();
|
|
1632
1577
|
var auth = (req) => {
|
|
1633
|
-
const
|
|
1634
|
-
if (!
|
|
1578
|
+
const match2 = CREDENTIALS_REGEXP.exec(req.headers.get("Authorization") || "");
|
|
1579
|
+
if (!match2) {
|
|
1635
1580
|
return void 0;
|
|
1636
1581
|
}
|
|
1637
1582
|
let userPass = void 0;
|
|
1638
1583
|
try {
|
|
1639
|
-
userPass = USER_PASS_REGEXP.exec(utf8Decoder.decode(decodeBase64(
|
|
1584
|
+
userPass = USER_PASS_REGEXP.exec(utf8Decoder.decode(decodeBase64(match2[1])));
|
|
1640
1585
|
} catch {
|
|
1641
1586
|
}
|
|
1642
1587
|
if (!userPass) {
|
|
@@ -1645,7 +1590,7 @@ var auth = (req) => {
|
|
|
1645
1590
|
return { username: userPass[1], password: userPass[2] };
|
|
1646
1591
|
};
|
|
1647
1592
|
|
|
1648
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1593
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/crypto.js
|
|
1649
1594
|
var sha256 = async (data) => {
|
|
1650
1595
|
const algorithm = { name: "SHA-256", alias: "sha256" };
|
|
1651
1596
|
const hash = await createHash(data, algorithm);
|
|
@@ -1674,7 +1619,7 @@ var createHash = async (data, algorithm) => {
|
|
|
1674
1619
|
return null;
|
|
1675
1620
|
};
|
|
1676
1621
|
|
|
1677
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1622
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/utils/buffer.js
|
|
1678
1623
|
var timingSafeEqual = async (a, b, hashFunction) => {
|
|
1679
1624
|
if (!hashFunction) {
|
|
1680
1625
|
hashFunction = sha256;
|
|
@@ -1686,7 +1631,7 @@ var timingSafeEqual = async (a, b, hashFunction) => {
|
|
|
1686
1631
|
return sa === sb && a === b;
|
|
1687
1632
|
};
|
|
1688
1633
|
|
|
1689
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1634
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/middleware/basic-auth/index.js
|
|
1690
1635
|
var basicAuth = (options, ...users) => {
|
|
1691
1636
|
const usernamePasswordInOptions = "username" in options && "password" in options;
|
|
1692
1637
|
const verifyUserInOptions = "verifyUser" in options;
|
|
@@ -1741,7 +1686,7 @@ var basicAuth = (options, ...users) => {
|
|
|
1741
1686
|
};
|
|
1742
1687
|
};
|
|
1743
1688
|
|
|
1744
|
-
// ../../node_modules/.pnpm/hono@4.
|
|
1689
|
+
// ../../node_modules/.pnpm/hono@4.10.7/node_modules/hono/dist/middleware/cors/index.js
|
|
1745
1690
|
var cors = (options) => {
|
|
1746
1691
|
const defaults = {
|
|
1747
1692
|
origin: "*",
|
|
@@ -1766,22 +1711,23 @@ var cors = (options) => {
|
|
|
1766
1711
|
return (origin) => optsOrigin.includes(origin) ? origin : null;
|
|
1767
1712
|
}
|
|
1768
1713
|
})(opts.origin);
|
|
1714
|
+
const findAllowMethods = ((optsAllowMethods) => {
|
|
1715
|
+
if (typeof optsAllowMethods === "function") {
|
|
1716
|
+
return optsAllowMethods;
|
|
1717
|
+
} else if (Array.isArray(optsAllowMethods)) {
|
|
1718
|
+
return () => optsAllowMethods;
|
|
1719
|
+
} else {
|
|
1720
|
+
return () => [];
|
|
1721
|
+
}
|
|
1722
|
+
})(opts.allowMethods);
|
|
1769
1723
|
return async function cors2(c, next) {
|
|
1770
1724
|
function set(key, value) {
|
|
1771
1725
|
c.res.headers.set(key, value);
|
|
1772
1726
|
}
|
|
1773
|
-
const allowOrigin = findAllowOrigin(c.req.header("origin") || "", c);
|
|
1727
|
+
const allowOrigin = await findAllowOrigin(c.req.header("origin") || "", c);
|
|
1774
1728
|
if (allowOrigin) {
|
|
1775
1729
|
set("Access-Control-Allow-Origin", allowOrigin);
|
|
1776
1730
|
}
|
|
1777
|
-
if (opts.origin !== "*") {
|
|
1778
|
-
const existingVary = c.req.header("Vary");
|
|
1779
|
-
if (existingVary) {
|
|
1780
|
-
set("Vary", existingVary);
|
|
1781
|
-
} else {
|
|
1782
|
-
set("Vary", "Origin");
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
1731
|
if (opts.credentials) {
|
|
1786
1732
|
set("Access-Control-Allow-Credentials", "true");
|
|
1787
1733
|
}
|
|
@@ -1789,11 +1735,15 @@ var cors = (options) => {
|
|
|
1789
1735
|
set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
|
|
1790
1736
|
}
|
|
1791
1737
|
if (c.req.method === "OPTIONS") {
|
|
1738
|
+
if (opts.origin !== "*") {
|
|
1739
|
+
set("Vary", "Origin");
|
|
1740
|
+
}
|
|
1792
1741
|
if (opts.maxAge != null) {
|
|
1793
1742
|
set("Access-Control-Max-Age", opts.maxAge.toString());
|
|
1794
1743
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1744
|
+
const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
|
|
1745
|
+
if (allowMethods.length) {
|
|
1746
|
+
set("Access-Control-Allow-Methods", allowMethods.join(","));
|
|
1797
1747
|
}
|
|
1798
1748
|
let headers = opts.allowHeaders;
|
|
1799
1749
|
if (!headers?.length) {
|
|
@@ -1815,11 +1765,14 @@ var cors = (options) => {
|
|
|
1815
1765
|
});
|
|
1816
1766
|
}
|
|
1817
1767
|
await next();
|
|
1768
|
+
if (opts.origin !== "*") {
|
|
1769
|
+
c.header("Vary", "Origin", { append: true });
|
|
1770
|
+
}
|
|
1818
1771
|
};
|
|
1819
1772
|
};
|
|
1820
1773
|
|
|
1821
1774
|
// src/index.ts
|
|
1822
|
-
var
|
|
1775
|
+
var import_zod17 = require("zod");
|
|
1823
1776
|
|
|
1824
1777
|
// src/foundation/middlewares/readonly.ts
|
|
1825
1778
|
async function readOnlyMiddleware(c, next) {
|
|
@@ -1842,7 +1795,7 @@ async function readOnlyMiddleware(c, next) {
|
|
|
1842
1795
|
}
|
|
1843
1796
|
|
|
1844
1797
|
// package.json
|
|
1845
|
-
var version = "1.1.
|
|
1798
|
+
var version = "1.1.11";
|
|
1846
1799
|
|
|
1847
1800
|
// src/foundation/settings.ts
|
|
1848
1801
|
var settings = {
|
|
@@ -1887,23 +1840,135 @@ var CreateFolder = class extends import_chanfana.OpenAPIRoute {
|
|
|
1887
1840
|
}
|
|
1888
1841
|
};
|
|
1889
1842
|
|
|
1890
|
-
// src/modules/buckets/
|
|
1843
|
+
// src/modules/buckets/createShareLink.ts
|
|
1891
1844
|
var import_chanfana2 = require("chanfana");
|
|
1892
1845
|
var import_zod2 = require("zod");
|
|
1893
|
-
var
|
|
1846
|
+
var CreateShareLink = class extends import_chanfana2.OpenAPIRoute {
|
|
1894
1847
|
schema = {
|
|
1895
|
-
operationId: "post-bucket-
|
|
1848
|
+
operationId: "post-bucket-create-share-link",
|
|
1896
1849
|
tags: ["Buckets"],
|
|
1897
|
-
summary: "
|
|
1850
|
+
summary: "Create shareable link for file",
|
|
1898
1851
|
request: {
|
|
1899
1852
|
params: import_zod2.z.object({
|
|
1900
|
-
bucket: import_zod2.z.string()
|
|
1853
|
+
bucket: import_zod2.z.string(),
|
|
1854
|
+
key: import_zod2.z.string()
|
|
1901
1855
|
}),
|
|
1902
1856
|
body: {
|
|
1903
1857
|
content: {
|
|
1904
1858
|
"application/json": {
|
|
1905
1859
|
schema: import_zod2.z.object({
|
|
1906
|
-
|
|
1860
|
+
expiresIn: import_zod2.z.number().optional().describe("Expiration time in seconds"),
|
|
1861
|
+
password: import_zod2.z.string().optional().describe("Optional password"),
|
|
1862
|
+
maxDownloads: import_zod2.z.number().optional().describe("Maximum downloads")
|
|
1863
|
+
})
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
},
|
|
1868
|
+
responses: {
|
|
1869
|
+
"200": {
|
|
1870
|
+
description: "Share link created successfully",
|
|
1871
|
+
content: {
|
|
1872
|
+
"application/json": {
|
|
1873
|
+
schema: import_zod2.z.object({
|
|
1874
|
+
shareId: import_zod2.z.string(),
|
|
1875
|
+
shareUrl: import_zod2.z.string(),
|
|
1876
|
+
expiresAt: import_zod2.z.number().optional()
|
|
1877
|
+
})
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1883
|
+
async handle(c) {
|
|
1884
|
+
const data = await this.getValidatedData();
|
|
1885
|
+
const bucketName = data.params.bucket;
|
|
1886
|
+
const bucket = c.env[bucketName];
|
|
1887
|
+
if (!bucket) {
|
|
1888
|
+
throw new HTTPException(500, {
|
|
1889
|
+
message: `Bucket binding not found: ${bucketName}`
|
|
1890
|
+
});
|
|
1891
|
+
}
|
|
1892
|
+
const key = decodeURIComponent(escape(atob(data.params.key)));
|
|
1893
|
+
const fileExists = await bucket.head(key);
|
|
1894
|
+
if (!fileExists) {
|
|
1895
|
+
throw new HTTPException(404, {
|
|
1896
|
+
message: `File not found: ${key}`
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
let shareId = "";
|
|
1900
|
+
let attempts = 0;
|
|
1901
|
+
const maxAttempts = 5;
|
|
1902
|
+
while (attempts < maxAttempts) {
|
|
1903
|
+
shareId = crypto.randomUUID().replace(/-/g, "").substring(0, 10);
|
|
1904
|
+
const existingShare = await bucket.head(
|
|
1905
|
+
`.r2-explorer/sharable-links/${shareId}.json`
|
|
1906
|
+
);
|
|
1907
|
+
if (!existingShare) {
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1910
|
+
attempts++;
|
|
1911
|
+
}
|
|
1912
|
+
if (attempts === maxAttempts) {
|
|
1913
|
+
throw new HTTPException(500, {
|
|
1914
|
+
message: "Failed to generate unique share ID"
|
|
1915
|
+
});
|
|
1916
|
+
}
|
|
1917
|
+
let passwordHash;
|
|
1918
|
+
if (data.body.password) {
|
|
1919
|
+
const encoder = new TextEncoder();
|
|
1920
|
+
const passwordData = encoder.encode(data.body.password);
|
|
1921
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", passwordData);
|
|
1922
|
+
passwordHash = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1923
|
+
}
|
|
1924
|
+
const expiresAt = data.body.expiresIn ? Date.now() + data.body.expiresIn * 1e3 : void 0;
|
|
1925
|
+
const shareMetadata = {
|
|
1926
|
+
bucket: bucketName,
|
|
1927
|
+
key,
|
|
1928
|
+
expiresAt,
|
|
1929
|
+
passwordHash,
|
|
1930
|
+
maxDownloads: data.body.maxDownloads,
|
|
1931
|
+
currentDownloads: 0,
|
|
1932
|
+
createdBy: c.get("authentication_username") || "anonymous",
|
|
1933
|
+
createdAt: Date.now()
|
|
1934
|
+
};
|
|
1935
|
+
await bucket.put(
|
|
1936
|
+
`.r2-explorer/sharable-links/${shareId}.json`,
|
|
1937
|
+
JSON.stringify(shareMetadata),
|
|
1938
|
+
{
|
|
1939
|
+
httpMetadata: { contentType: "application/json" },
|
|
1940
|
+
customMetadata: {
|
|
1941
|
+
targetBucket: bucketName,
|
|
1942
|
+
targetKey: key
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
);
|
|
1946
|
+
const shareUrl = `${new URL(c.req.url).origin}/share/${shareId}`;
|
|
1947
|
+
return c.json({
|
|
1948
|
+
shareId,
|
|
1949
|
+
shareUrl,
|
|
1950
|
+
expiresAt
|
|
1951
|
+
});
|
|
1952
|
+
}
|
|
1953
|
+
};
|
|
1954
|
+
|
|
1955
|
+
// src/modules/buckets/deleteObject.ts
|
|
1956
|
+
var import_chanfana3 = require("chanfana");
|
|
1957
|
+
var import_zod3 = require("zod");
|
|
1958
|
+
var DeleteObject = class extends import_chanfana3.OpenAPIRoute {
|
|
1959
|
+
schema = {
|
|
1960
|
+
operationId: "post-bucket-delete-object",
|
|
1961
|
+
tags: ["Buckets"],
|
|
1962
|
+
summary: "Delete object",
|
|
1963
|
+
request: {
|
|
1964
|
+
params: import_zod3.z.object({
|
|
1965
|
+
bucket: import_zod3.z.string()
|
|
1966
|
+
}),
|
|
1967
|
+
body: {
|
|
1968
|
+
content: {
|
|
1969
|
+
"application/json": {
|
|
1970
|
+
schema: import_zod3.z.object({
|
|
1971
|
+
key: import_zod3.z.string().describe("base64 encoded file key")
|
|
1907
1972
|
})
|
|
1908
1973
|
}
|
|
1909
1974
|
}
|
|
@@ -1925,24 +1990,73 @@ var DeleteObject = class extends import_chanfana2.OpenAPIRoute {
|
|
|
1925
1990
|
}
|
|
1926
1991
|
};
|
|
1927
1992
|
|
|
1993
|
+
// src/modules/buckets/deleteShareLink.ts
|
|
1994
|
+
var import_chanfana4 = require("chanfana");
|
|
1995
|
+
var import_zod4 = require("zod");
|
|
1996
|
+
var DeleteShareLink = class extends import_chanfana4.OpenAPIRoute {
|
|
1997
|
+
schema = {
|
|
1998
|
+
operationId: "delete-bucket-share-link",
|
|
1999
|
+
tags: ["Buckets"],
|
|
2000
|
+
summary: "Revoke/delete a share link",
|
|
2001
|
+
request: {
|
|
2002
|
+
params: import_zod4.z.object({
|
|
2003
|
+
bucket: import_zod4.z.string(),
|
|
2004
|
+
shareId: import_zod4.z.string().describe("10-character share ID")
|
|
2005
|
+
})
|
|
2006
|
+
},
|
|
2007
|
+
responses: {
|
|
2008
|
+
"200": {
|
|
2009
|
+
description: "Share link deleted successfully",
|
|
2010
|
+
content: {
|
|
2011
|
+
"application/json": {
|
|
2012
|
+
schema: import_zod4.z.object({
|
|
2013
|
+
success: import_zod4.z.boolean()
|
|
2014
|
+
})
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
};
|
|
2020
|
+
async handle(c) {
|
|
2021
|
+
const data = await this.getValidatedData();
|
|
2022
|
+
const bucketName = data.params.bucket;
|
|
2023
|
+
const bucket = c.env[bucketName];
|
|
2024
|
+
if (!bucket) {
|
|
2025
|
+
throw new HTTPException(500, {
|
|
2026
|
+
message: `Bucket binding not found: ${bucketName}`
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
const shareId = data.params.shareId;
|
|
2030
|
+
const shareKey = `.r2-explorer/sharable-links/${shareId}.json`;
|
|
2031
|
+
const shareExists = await bucket.head(shareKey);
|
|
2032
|
+
if (!shareExists) {
|
|
2033
|
+
throw new HTTPException(404, {
|
|
2034
|
+
message: `Share link not found: ${shareId}`
|
|
2035
|
+
});
|
|
2036
|
+
}
|
|
2037
|
+
await bucket.delete(shareKey);
|
|
2038
|
+
return c.json({ success: true });
|
|
2039
|
+
}
|
|
2040
|
+
};
|
|
2041
|
+
|
|
1928
2042
|
// src/modules/buckets/getObject.ts
|
|
1929
|
-
var
|
|
1930
|
-
var
|
|
1931
|
-
var GetObject = class extends
|
|
2043
|
+
var import_chanfana5 = require("chanfana");
|
|
2044
|
+
var import_zod5 = require("zod");
|
|
2045
|
+
var GetObject = class extends import_chanfana5.OpenAPIRoute {
|
|
1932
2046
|
schema = {
|
|
1933
2047
|
operationId: "get-bucket-object",
|
|
1934
2048
|
tags: ["Buckets"],
|
|
1935
2049
|
summary: "Get Object",
|
|
1936
2050
|
request: {
|
|
1937
|
-
params:
|
|
1938
|
-
bucket:
|
|
1939
|
-
key:
|
|
2051
|
+
params: import_zod5.z.object({
|
|
2052
|
+
bucket: import_zod5.z.string(),
|
|
2053
|
+
key: import_zod5.z.string().describe("base64 encoded file key")
|
|
1940
2054
|
})
|
|
1941
2055
|
},
|
|
1942
2056
|
responses: {
|
|
1943
2057
|
"200": {
|
|
1944
2058
|
description: "File binary",
|
|
1945
|
-
schema:
|
|
2059
|
+
schema: import_zod5.z.string().openapi({ format: "binary" })
|
|
1946
2060
|
}
|
|
1947
2061
|
}
|
|
1948
2062
|
};
|
|
@@ -1958,10 +2072,14 @@ var GetObject = class extends import_chanfana3.OpenAPIRoute {
|
|
|
1958
2072
|
let filePath;
|
|
1959
2073
|
try {
|
|
1960
2074
|
filePath = decodeURIComponent(escape(atob(data.params.key)));
|
|
1961
|
-
} catch
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
2075
|
+
} catch {
|
|
2076
|
+
try {
|
|
2077
|
+
filePath = decodeURIComponent(
|
|
2078
|
+
escape(atob(decodeURIComponent(data.params.key)))
|
|
2079
|
+
);
|
|
2080
|
+
} catch {
|
|
2081
|
+
filePath = escape(atob(decodeURIComponent(data.params.key)));
|
|
2082
|
+
}
|
|
1965
2083
|
}
|
|
1966
2084
|
const object = await bucket.get(filePath);
|
|
1967
2085
|
if (object === null) {
|
|
@@ -1970,6 +2088,7 @@ var GetObject = class extends import_chanfana3.OpenAPIRoute {
|
|
|
1970
2088
|
const headers = new Headers();
|
|
1971
2089
|
object.writeHttpMetadata(headers);
|
|
1972
2090
|
headers.set("etag", object.httpEtag);
|
|
2091
|
+
headers.set("content-length", object.size.toString());
|
|
1973
2092
|
headers.set(
|
|
1974
2093
|
"Content-Disposition",
|
|
1975
2094
|
`attachment; filename="${filePath.split("/").pop()}"`
|
|
@@ -1980,18 +2099,137 @@ var GetObject = class extends import_chanfana3.OpenAPIRoute {
|
|
|
1980
2099
|
}
|
|
1981
2100
|
};
|
|
1982
2101
|
|
|
2102
|
+
// src/modules/buckets/getShareLink.ts
|
|
2103
|
+
var import_chanfana6 = require("chanfana");
|
|
2104
|
+
var import_zod6 = require("zod");
|
|
2105
|
+
var GetShareLink = class extends import_chanfana6.OpenAPIRoute {
|
|
2106
|
+
schema = {
|
|
2107
|
+
operationId: "get-share-link",
|
|
2108
|
+
tags: ["Sharing"],
|
|
2109
|
+
summary: "Access shared file",
|
|
2110
|
+
security: [],
|
|
2111
|
+
// Public endpoint - no auth required
|
|
2112
|
+
request: {
|
|
2113
|
+
params: import_zod6.z.object({
|
|
2114
|
+
shareId: import_zod6.z.string().describe("10-character share ID")
|
|
2115
|
+
}),
|
|
2116
|
+
query: import_zod6.z.object({
|
|
2117
|
+
password: import_zod6.z.string().optional().describe("Password for protected shares")
|
|
2118
|
+
})
|
|
2119
|
+
},
|
|
2120
|
+
responses: {
|
|
2121
|
+
"200": {
|
|
2122
|
+
description: "File retrieved successfully"
|
|
2123
|
+
},
|
|
2124
|
+
"401": {
|
|
2125
|
+
description: "Password required or incorrect"
|
|
2126
|
+
},
|
|
2127
|
+
"404": {
|
|
2128
|
+
description: "Share link not found"
|
|
2129
|
+
},
|
|
2130
|
+
"410": {
|
|
2131
|
+
description: "Share link expired"
|
|
2132
|
+
},
|
|
2133
|
+
"403": {
|
|
2134
|
+
description: "Download limit reached"
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
};
|
|
2138
|
+
async handle(c) {
|
|
2139
|
+
const data = await this.getValidatedData();
|
|
2140
|
+
const shareId = data.params.shareId;
|
|
2141
|
+
let shareMetadata = null;
|
|
2142
|
+
let bucket = null;
|
|
2143
|
+
for (const key in c.env) {
|
|
2144
|
+
if (key === "ASSETS") continue;
|
|
2145
|
+
const currentBucket = c.env[key];
|
|
2146
|
+
if (!currentBucket.get || typeof currentBucket.get !== "function") {
|
|
2147
|
+
continue;
|
|
2148
|
+
}
|
|
2149
|
+
const shareObject = await currentBucket.get(
|
|
2150
|
+
`.r2-explorer/sharable-links/${shareId}.json`
|
|
2151
|
+
);
|
|
2152
|
+
if (shareObject) {
|
|
2153
|
+
shareMetadata = JSON.parse(await shareObject.text());
|
|
2154
|
+
bucket = currentBucket;
|
|
2155
|
+
break;
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
if (!shareMetadata || !bucket) {
|
|
2159
|
+
throw new HTTPException(404, {
|
|
2160
|
+
message: "Share link not found"
|
|
2161
|
+
});
|
|
2162
|
+
}
|
|
2163
|
+
if (shareMetadata.expiresAt && Date.now() > shareMetadata.expiresAt) {
|
|
2164
|
+
throw new HTTPException(410, {
|
|
2165
|
+
message: "Share link expired"
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
if (shareMetadata.maxDownloads && shareMetadata.currentDownloads >= shareMetadata.maxDownloads) {
|
|
2169
|
+
throw new HTTPException(403, {
|
|
2170
|
+
message: "Download limit reached"
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2173
|
+
if (shareMetadata.passwordHash) {
|
|
2174
|
+
if (!data.query.password) {
|
|
2175
|
+
throw new HTTPException(401, {
|
|
2176
|
+
message: "Password required"
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
const encoder = new TextEncoder();
|
|
2180
|
+
const passwordData = encoder.encode(data.query.password);
|
|
2181
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", passwordData);
|
|
2182
|
+
const providedHash = Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
2183
|
+
if (providedHash !== shareMetadata.passwordHash) {
|
|
2184
|
+
throw new HTTPException(401, {
|
|
2185
|
+
message: "Incorrect password"
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
shareMetadata.currentDownloads++;
|
|
2190
|
+
await bucket.put(
|
|
2191
|
+
`.r2-explorer/sharable-links/${shareId}.json`,
|
|
2192
|
+
JSON.stringify(shareMetadata),
|
|
2193
|
+
{
|
|
2194
|
+
httpMetadata: { contentType: "application/json" },
|
|
2195
|
+
customMetadata: {
|
|
2196
|
+
targetBucket: shareMetadata.bucket,
|
|
2197
|
+
targetKey: shareMetadata.key
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
);
|
|
2201
|
+
const file = await bucket.get(shareMetadata.key);
|
|
2202
|
+
if (!file) {
|
|
2203
|
+
throw new HTTPException(404, {
|
|
2204
|
+
message: "Shared file not found"
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
const headers = new Headers();
|
|
2208
|
+
file.writeHttpMetadata(headers);
|
|
2209
|
+
headers.set("etag", file.httpEtag);
|
|
2210
|
+
const fileName = shareMetadata.key.split("/").pop() || "download";
|
|
2211
|
+
headers.set(
|
|
2212
|
+
"Content-Disposition",
|
|
2213
|
+
`attachment; filename="${encodeURIComponent(fileName)}"`
|
|
2214
|
+
);
|
|
2215
|
+
return new Response(file.body, {
|
|
2216
|
+
headers
|
|
2217
|
+
});
|
|
2218
|
+
}
|
|
2219
|
+
};
|
|
2220
|
+
|
|
1983
2221
|
// src/modules/buckets/headObject.ts
|
|
1984
|
-
var
|
|
1985
|
-
var
|
|
1986
|
-
var HeadObject = class extends
|
|
2222
|
+
var import_chanfana7 = require("chanfana");
|
|
2223
|
+
var import_zod7 = require("zod");
|
|
2224
|
+
var HeadObject = class extends import_chanfana7.OpenAPIRoute {
|
|
1987
2225
|
schema = {
|
|
1988
2226
|
operationId: "Head-bucket-object",
|
|
1989
2227
|
tags: ["Buckets"],
|
|
1990
2228
|
summary: "Get Object",
|
|
1991
2229
|
request: {
|
|
1992
|
-
params:
|
|
1993
|
-
bucket:
|
|
1994
|
-
key:
|
|
2230
|
+
params: import_zod7.z.object({
|
|
2231
|
+
bucket: import_zod7.z.string(),
|
|
2232
|
+
key: import_zod7.z.string().describe("base64 encoded file key")
|
|
1995
2233
|
})
|
|
1996
2234
|
}
|
|
1997
2235
|
};
|
|
@@ -2021,24 +2259,24 @@ var HeadObject = class extends import_chanfana4.OpenAPIRoute {
|
|
|
2021
2259
|
};
|
|
2022
2260
|
|
|
2023
2261
|
// src/modules/buckets/listObjects.ts
|
|
2024
|
-
var
|
|
2025
|
-
var
|
|
2026
|
-
var ListObjects = class extends
|
|
2262
|
+
var import_chanfana8 = require("chanfana");
|
|
2263
|
+
var import_zod8 = require("zod");
|
|
2264
|
+
var ListObjects = class extends import_chanfana8.OpenAPIRoute {
|
|
2027
2265
|
schema = {
|
|
2028
2266
|
operationId: "get-bucket-list-objects",
|
|
2029
2267
|
tags: ["Buckets"],
|
|
2030
2268
|
summary: "List objects",
|
|
2031
2269
|
request: {
|
|
2032
|
-
params:
|
|
2033
|
-
bucket:
|
|
2270
|
+
params: import_zod8.z.object({
|
|
2271
|
+
bucket: import_zod8.z.string()
|
|
2034
2272
|
}),
|
|
2035
|
-
query:
|
|
2036
|
-
limit:
|
|
2037
|
-
prefix:
|
|
2038
|
-
cursor:
|
|
2039
|
-
delimiter:
|
|
2040
|
-
startAfter:
|
|
2041
|
-
include:
|
|
2273
|
+
query: import_zod8.z.object({
|
|
2274
|
+
limit: import_zod8.z.number().optional(),
|
|
2275
|
+
prefix: import_zod8.z.string().nullable().optional().describe("base64 encoded prefix"),
|
|
2276
|
+
cursor: import_zod8.z.string().nullable().optional(),
|
|
2277
|
+
delimiter: import_zod8.z.string().nullable().optional(),
|
|
2278
|
+
startAfter: import_zod8.z.string().nullable().optional(),
|
|
2279
|
+
include: import_zod8.z.enum(["httpMetadata", "customMetadata"]).array().optional()
|
|
2042
2280
|
})
|
|
2043
2281
|
}
|
|
2044
2282
|
};
|
|
@@ -2064,24 +2302,102 @@ var ListObjects = class extends import_chanfana5.OpenAPIRoute {
|
|
|
2064
2302
|
}
|
|
2065
2303
|
};
|
|
2066
2304
|
|
|
2305
|
+
// src/modules/buckets/listShares.ts
|
|
2306
|
+
var import_chanfana9 = require("chanfana");
|
|
2307
|
+
var import_zod9 = require("zod");
|
|
2308
|
+
var ListShares = class extends import_chanfana9.OpenAPIRoute {
|
|
2309
|
+
schema = {
|
|
2310
|
+
operationId: "get-bucket-shares",
|
|
2311
|
+
tags: ["Buckets"],
|
|
2312
|
+
summary: "List all active shares in bucket",
|
|
2313
|
+
request: {
|
|
2314
|
+
params: import_zod9.z.object({
|
|
2315
|
+
bucket: import_zod9.z.string()
|
|
2316
|
+
})
|
|
2317
|
+
},
|
|
2318
|
+
responses: {
|
|
2319
|
+
"200": {
|
|
2320
|
+
description: "List of active shares",
|
|
2321
|
+
content: {
|
|
2322
|
+
"application/json": {
|
|
2323
|
+
schema: import_zod9.z.object({
|
|
2324
|
+
shares: import_zod9.z.array(
|
|
2325
|
+
import_zod9.z.object({
|
|
2326
|
+
shareId: import_zod9.z.string(),
|
|
2327
|
+
shareUrl: import_zod9.z.string(),
|
|
2328
|
+
key: import_zod9.z.string(),
|
|
2329
|
+
expiresAt: import_zod9.z.number().optional(),
|
|
2330
|
+
maxDownloads: import_zod9.z.number().optional(),
|
|
2331
|
+
currentDownloads: import_zod9.z.number(),
|
|
2332
|
+
createdBy: import_zod9.z.string(),
|
|
2333
|
+
createdAt: import_zod9.z.number(),
|
|
2334
|
+
isExpired: import_zod9.z.boolean(),
|
|
2335
|
+
hasPassword: import_zod9.z.boolean()
|
|
2336
|
+
})
|
|
2337
|
+
)
|
|
2338
|
+
})
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
};
|
|
2344
|
+
async handle(c) {
|
|
2345
|
+
const data = await this.getValidatedData();
|
|
2346
|
+
const bucketName = data.params.bucket;
|
|
2347
|
+
const bucket = c.env[bucketName];
|
|
2348
|
+
if (!bucket) {
|
|
2349
|
+
throw new HTTPException(500, {
|
|
2350
|
+
message: `Bucket binding not found: ${bucketName}`
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
const sharesList = await bucket.list({
|
|
2354
|
+
prefix: ".r2-explorer/sharable-links/"
|
|
2355
|
+
});
|
|
2356
|
+
const shares = [];
|
|
2357
|
+
const now = Date.now();
|
|
2358
|
+
const origin = new URL(c.req.url).origin;
|
|
2359
|
+
for (const obj of sharesList.objects) {
|
|
2360
|
+
const shareId = obj.key.split("/").pop()?.replace(".json", "");
|
|
2361
|
+
if (!shareId) continue;
|
|
2362
|
+
const shareObject = await bucket.get(obj.key);
|
|
2363
|
+
if (!shareObject) continue;
|
|
2364
|
+
const metadata = JSON.parse(await shareObject.text());
|
|
2365
|
+
const isExpired = !!(metadata.expiresAt && now > metadata.expiresAt);
|
|
2366
|
+
shares.push({
|
|
2367
|
+
shareId,
|
|
2368
|
+
shareUrl: `${origin}/share/${shareId}`,
|
|
2369
|
+
key: metadata.key,
|
|
2370
|
+
expiresAt: metadata.expiresAt,
|
|
2371
|
+
maxDownloads: metadata.maxDownloads,
|
|
2372
|
+
currentDownloads: metadata.currentDownloads || 0,
|
|
2373
|
+
createdBy: metadata.createdBy,
|
|
2374
|
+
createdAt: metadata.createdAt,
|
|
2375
|
+
isExpired,
|
|
2376
|
+
hasPassword: !!metadata.passwordHash
|
|
2377
|
+
});
|
|
2378
|
+
}
|
|
2379
|
+
return c.json({ shares });
|
|
2380
|
+
}
|
|
2381
|
+
};
|
|
2382
|
+
|
|
2067
2383
|
// src/modules/buckets/moveObject.ts
|
|
2068
|
-
var
|
|
2069
|
-
var
|
|
2070
|
-
var MoveObject = class extends
|
|
2384
|
+
var import_chanfana10 = require("chanfana");
|
|
2385
|
+
var import_zod10 = require("zod");
|
|
2386
|
+
var MoveObject = class extends import_chanfana10.OpenAPIRoute {
|
|
2071
2387
|
schema = {
|
|
2072
2388
|
operationId: "post-bucket-move-object",
|
|
2073
2389
|
tags: ["Buckets"],
|
|
2074
2390
|
summary: "Move object",
|
|
2075
2391
|
request: {
|
|
2076
|
-
params:
|
|
2077
|
-
bucket:
|
|
2392
|
+
params: import_zod10.z.object({
|
|
2393
|
+
bucket: import_zod10.z.string()
|
|
2078
2394
|
}),
|
|
2079
2395
|
body: {
|
|
2080
2396
|
content: {
|
|
2081
2397
|
"application/json": {
|
|
2082
|
-
schema:
|
|
2083
|
-
oldKey:
|
|
2084
|
-
newKey:
|
|
2398
|
+
schema: import_zod10.z.object({
|
|
2399
|
+
oldKey: import_zod10.z.string().describe("base64 encoded file key"),
|
|
2400
|
+
newKey: import_zod10.z.string().describe("base64 encoded file key")
|
|
2085
2401
|
})
|
|
2086
2402
|
}
|
|
2087
2403
|
}
|
|
@@ -2115,27 +2431,27 @@ var MoveObject = class extends import_chanfana6.OpenAPIRoute {
|
|
|
2115
2431
|
};
|
|
2116
2432
|
|
|
2117
2433
|
// src/modules/buckets/multipart/completeUpload.ts
|
|
2118
|
-
var
|
|
2119
|
-
var
|
|
2120
|
-
var CompleteUpload = class extends
|
|
2434
|
+
var import_chanfana11 = require("chanfana");
|
|
2435
|
+
var import_zod11 = require("zod");
|
|
2436
|
+
var CompleteUpload = class extends import_chanfana11.OpenAPIRoute {
|
|
2121
2437
|
schema = {
|
|
2122
2438
|
operationId: "post-multipart-complete-upload",
|
|
2123
2439
|
tags: ["Multipart"],
|
|
2124
2440
|
summary: "Complete upload",
|
|
2125
2441
|
request: {
|
|
2126
|
-
params:
|
|
2127
|
-
bucket:
|
|
2442
|
+
params: import_zod11.z.object({
|
|
2443
|
+
bucket: import_zod11.z.string()
|
|
2128
2444
|
}),
|
|
2129
2445
|
body: {
|
|
2130
2446
|
content: {
|
|
2131
2447
|
"application/json": {
|
|
2132
|
-
schema:
|
|
2133
|
-
uploadId:
|
|
2134
|
-
parts:
|
|
2135
|
-
etag:
|
|
2136
|
-
partNumber:
|
|
2448
|
+
schema: import_zod11.z.object({
|
|
2449
|
+
uploadId: import_zod11.z.string(),
|
|
2450
|
+
parts: import_zod11.z.object({
|
|
2451
|
+
etag: import_zod11.z.string(),
|
|
2452
|
+
partNumber: import_zod11.z.number().int()
|
|
2137
2453
|
}).array(),
|
|
2138
|
-
key:
|
|
2454
|
+
key: import_zod11.z.string().describe("base64 encoded file key")
|
|
2139
2455
|
})
|
|
2140
2456
|
}
|
|
2141
2457
|
}
|
|
@@ -2145,6 +2461,12 @@ var CompleteUpload = class extends import_chanfana7.OpenAPIRoute {
|
|
|
2145
2461
|
async handle(c) {
|
|
2146
2462
|
const data = await this.getValidatedData();
|
|
2147
2463
|
const bucket = c.env[data.params.bucket];
|
|
2464
|
+
if (!bucket || typeof bucket !== "object" || !("resumeMultipartUpload" in bucket)) {
|
|
2465
|
+
return Response.json(
|
|
2466
|
+
{ error: `Bucket binding not found: ${data.params.bucket}` },
|
|
2467
|
+
{ status: 500 }
|
|
2468
|
+
);
|
|
2469
|
+
}
|
|
2148
2470
|
const uploadId = data.body.uploadId;
|
|
2149
2471
|
const key = decodeURIComponent(escape(atob(data.body.key)));
|
|
2150
2472
|
const parts = data.body.parts;
|
|
@@ -2162,27 +2484,33 @@ var CompleteUpload = class extends import_chanfana7.OpenAPIRoute {
|
|
|
2162
2484
|
};
|
|
2163
2485
|
|
|
2164
2486
|
// src/modules/buckets/multipart/createUpload.ts
|
|
2165
|
-
var
|
|
2166
|
-
var
|
|
2167
|
-
var CreateUpload = class extends
|
|
2487
|
+
var import_chanfana12 = require("chanfana");
|
|
2488
|
+
var import_zod12 = require("zod");
|
|
2489
|
+
var CreateUpload = class extends import_chanfana12.OpenAPIRoute {
|
|
2168
2490
|
schema = {
|
|
2169
2491
|
operationId: "post-multipart-create-upload",
|
|
2170
2492
|
tags: ["Multipart"],
|
|
2171
2493
|
summary: "Create upload",
|
|
2172
2494
|
request: {
|
|
2173
|
-
params:
|
|
2174
|
-
bucket:
|
|
2495
|
+
params: import_zod12.z.object({
|
|
2496
|
+
bucket: import_zod12.z.string()
|
|
2175
2497
|
}),
|
|
2176
|
-
query:
|
|
2177
|
-
key:
|
|
2178
|
-
customMetadata:
|
|
2179
|
-
httpMetadata:
|
|
2498
|
+
query: import_zod12.z.object({
|
|
2499
|
+
key: import_zod12.z.string().describe("base64 encoded file key"),
|
|
2500
|
+
customMetadata: import_zod12.z.string().nullable().optional().describe("base64 encoded json string"),
|
|
2501
|
+
httpMetadata: import_zod12.z.string().nullable().optional().describe("base64 encoded json string")
|
|
2180
2502
|
})
|
|
2181
2503
|
}
|
|
2182
2504
|
};
|
|
2183
2505
|
async handle(c) {
|
|
2184
2506
|
const data = await this.getValidatedData();
|
|
2185
2507
|
const bucket = c.env[data.params.bucket];
|
|
2508
|
+
if (!bucket || typeof bucket !== "object" || !("createMultipartUpload" in bucket)) {
|
|
2509
|
+
return Response.json(
|
|
2510
|
+
{ error: `Bucket binding not found: ${data.params.bucket}` },
|
|
2511
|
+
{ status: 500 }
|
|
2512
|
+
);
|
|
2513
|
+
}
|
|
2186
2514
|
const key = decodeURIComponent(escape(atob(data.query.key)));
|
|
2187
2515
|
let customMetadata = void 0;
|
|
2188
2516
|
if (data.query.customMetadata) {
|
|
@@ -2204,9 +2532,9 @@ var CreateUpload = class extends import_chanfana8.OpenAPIRoute {
|
|
|
2204
2532
|
};
|
|
2205
2533
|
|
|
2206
2534
|
// src/modules/buckets/multipart/partUpload.ts
|
|
2207
|
-
var
|
|
2208
|
-
var
|
|
2209
|
-
var PartUpload = class extends
|
|
2535
|
+
var import_chanfana13 = require("chanfana");
|
|
2536
|
+
var import_zod13 = require("zod");
|
|
2537
|
+
var PartUpload = class extends import_chanfana13.OpenAPIRoute {
|
|
2210
2538
|
schema = {
|
|
2211
2539
|
operationId: "post-multipart-part-upload",
|
|
2212
2540
|
tags: ["Multipart"],
|
|
@@ -2215,26 +2543,32 @@ var PartUpload = class extends import_chanfana9.OpenAPIRoute {
|
|
|
2215
2543
|
body: {
|
|
2216
2544
|
content: {
|
|
2217
2545
|
"application/octet-stream": {
|
|
2218
|
-
schema:
|
|
2546
|
+
schema: import_zod13.z.object({}).openapi({
|
|
2219
2547
|
type: "string",
|
|
2220
2548
|
format: "binary"
|
|
2221
2549
|
})
|
|
2222
2550
|
}
|
|
2223
2551
|
}
|
|
2224
2552
|
},
|
|
2225
|
-
params:
|
|
2226
|
-
bucket:
|
|
2553
|
+
params: import_zod13.z.object({
|
|
2554
|
+
bucket: import_zod13.z.string()
|
|
2227
2555
|
}),
|
|
2228
|
-
query:
|
|
2229
|
-
key:
|
|
2230
|
-
uploadId:
|
|
2231
|
-
partNumber:
|
|
2556
|
+
query: import_zod13.z.object({
|
|
2557
|
+
key: import_zod13.z.string().describe("base64 encoded file key"),
|
|
2558
|
+
uploadId: import_zod13.z.string(),
|
|
2559
|
+
partNumber: import_zod13.z.number().int()
|
|
2232
2560
|
})
|
|
2233
2561
|
}
|
|
2234
2562
|
};
|
|
2235
2563
|
async handle(c) {
|
|
2236
2564
|
const data = await this.getValidatedData();
|
|
2237
2565
|
const bucket = c.env[data.params.bucket];
|
|
2566
|
+
if (!bucket || typeof bucket !== "object" || !("resumeMultipartUpload" in bucket)) {
|
|
2567
|
+
return Response.json(
|
|
2568
|
+
{ error: `Bucket binding not found: ${data.params.bucket}` },
|
|
2569
|
+
{ status: 500 }
|
|
2570
|
+
);
|
|
2571
|
+
}
|
|
2238
2572
|
const key = decodeURIComponent(escape(atob(data.query.key)));
|
|
2239
2573
|
const multipartUpload = bucket.resumeMultipartUpload(
|
|
2240
2574
|
key,
|
|
@@ -2252,24 +2586,24 @@ var PartUpload = class extends import_chanfana9.OpenAPIRoute {
|
|
|
2252
2586
|
};
|
|
2253
2587
|
|
|
2254
2588
|
// src/modules/buckets/putMetadata.ts
|
|
2255
|
-
var
|
|
2256
|
-
var
|
|
2257
|
-
var PutMetadata = class extends
|
|
2589
|
+
var import_chanfana14 = require("chanfana");
|
|
2590
|
+
var import_zod14 = require("zod");
|
|
2591
|
+
var PutMetadata = class extends import_chanfana14.OpenAPIRoute {
|
|
2258
2592
|
schema = {
|
|
2259
2593
|
operationId: "post-bucket-put-object-metadata",
|
|
2260
2594
|
tags: ["Buckets"],
|
|
2261
2595
|
summary: "Update object metadata",
|
|
2262
2596
|
request: {
|
|
2263
|
-
params:
|
|
2264
|
-
bucket:
|
|
2265
|
-
key:
|
|
2597
|
+
params: import_zod14.z.object({
|
|
2598
|
+
bucket: import_zod14.z.string(),
|
|
2599
|
+
key: import_zod14.z.string().describe("base64 encoded file key")
|
|
2266
2600
|
}),
|
|
2267
2601
|
body: {
|
|
2268
2602
|
content: {
|
|
2269
2603
|
"application/json": {
|
|
2270
|
-
schema:
|
|
2271
|
-
customMetadata:
|
|
2272
|
-
httpMetadata:
|
|
2604
|
+
schema: import_zod14.z.object({
|
|
2605
|
+
customMetadata: import_zod14.z.record(import_zod14.z.string(), import_zod14.z.any()),
|
|
2606
|
+
httpMetadata: import_zod14.z.record(import_zod14.z.string(), import_zod14.z.any())
|
|
2273
2607
|
}).openapi("Object metadata")
|
|
2274
2608
|
}
|
|
2275
2609
|
}
|
|
@@ -2305,9 +2639,9 @@ var PutMetadata = class extends import_chanfana10.OpenAPIRoute {
|
|
|
2305
2639
|
};
|
|
2306
2640
|
|
|
2307
2641
|
// src/modules/buckets/putObject.ts
|
|
2308
|
-
var
|
|
2309
|
-
var
|
|
2310
|
-
var PutObject = class extends
|
|
2642
|
+
var import_chanfana15 = require("chanfana");
|
|
2643
|
+
var import_zod15 = require("zod");
|
|
2644
|
+
var PutObject = class extends import_chanfana15.OpenAPIRoute {
|
|
2311
2645
|
schema = {
|
|
2312
2646
|
operationId: "post-bucket-upload-object",
|
|
2313
2647
|
tags: ["Buckets"],
|
|
@@ -2316,20 +2650,20 @@ var PutObject = class extends import_chanfana11.OpenAPIRoute {
|
|
|
2316
2650
|
body: {
|
|
2317
2651
|
content: {
|
|
2318
2652
|
"application/octet-stream": {
|
|
2319
|
-
schema:
|
|
2653
|
+
schema: import_zod15.z.object({}).openapi({
|
|
2320
2654
|
type: "string",
|
|
2321
2655
|
format: "binary"
|
|
2322
2656
|
})
|
|
2323
2657
|
}
|
|
2324
2658
|
}
|
|
2325
2659
|
},
|
|
2326
|
-
params:
|
|
2327
|
-
bucket:
|
|
2660
|
+
params: import_zod15.z.object({
|
|
2661
|
+
bucket: import_zod15.z.string()
|
|
2328
2662
|
}),
|
|
2329
|
-
query:
|
|
2330
|
-
key:
|
|
2331
|
-
customMetadata:
|
|
2332
|
-
httpMetadata:
|
|
2663
|
+
query: import_zod15.z.object({
|
|
2664
|
+
key: import_zod15.z.string().describe("base64 encoded file key"),
|
|
2665
|
+
customMetadata: import_zod15.z.string().nullable().optional().describe("base64 encoded json string"),
|
|
2666
|
+
httpMetadata: import_zod15.z.string().nullable().optional().describe("base64 encoded json string")
|
|
2333
2667
|
})
|
|
2334
2668
|
}
|
|
2335
2669
|
};
|
|
@@ -2414,7 +2748,7 @@ async function streamToArrayBuffer(stream, streamSize) {
|
|
|
2414
2748
|
}
|
|
2415
2749
|
async function receiveEmail(event, env, ctx, config) {
|
|
2416
2750
|
let bucket;
|
|
2417
|
-
if (config?.emailRouting
|
|
2751
|
+
if (config?.emailRouting && typeof config.emailRouting === "object" && config.emailRouting.targetBucket && env[config.emailRouting.targetBucket]) {
|
|
2418
2752
|
bucket = env[config.emailRouting.targetBucket];
|
|
2419
2753
|
}
|
|
2420
2754
|
if (!bucket) {
|
|
@@ -2454,9 +2788,9 @@ async function receiveEmail(event, env, ctx, config) {
|
|
|
2454
2788
|
}
|
|
2455
2789
|
|
|
2456
2790
|
// src/modules/emails/sendEmail.ts
|
|
2457
|
-
var
|
|
2458
|
-
var
|
|
2459
|
-
var SendEmail = class extends
|
|
2791
|
+
var import_chanfana16 = require("chanfana");
|
|
2792
|
+
var import_zod16 = require("zod");
|
|
2793
|
+
var SendEmail = class extends import_chanfana16.OpenAPIRoute {
|
|
2460
2794
|
schema = {
|
|
2461
2795
|
operationId: "post-email-send",
|
|
2462
2796
|
tags: ["Emails"],
|
|
@@ -2465,17 +2799,17 @@ var SendEmail = class extends import_chanfana12.OpenAPIRoute {
|
|
|
2465
2799
|
body: {
|
|
2466
2800
|
content: {
|
|
2467
2801
|
"application/json": {
|
|
2468
|
-
schema:
|
|
2469
|
-
subject: (0,
|
|
2470
|
-
from:
|
|
2471
|
-
email: (0,
|
|
2472
|
-
name: (0,
|
|
2802
|
+
schema: import_zod16.z.object({
|
|
2803
|
+
subject: (0, import_chanfana16.Str)({ example: "Look! No servers" }),
|
|
2804
|
+
from: import_zod16.z.object({
|
|
2805
|
+
email: (0, import_chanfana16.Str)({ example: "sender@example.com" }),
|
|
2806
|
+
name: (0, import_chanfana16.Str)({ example: "Workers - MailChannels integration" })
|
|
2473
2807
|
}),
|
|
2474
|
-
to:
|
|
2475
|
-
email: (0,
|
|
2476
|
-
name: (0,
|
|
2808
|
+
to: import_zod16.z.object({
|
|
2809
|
+
email: (0, import_chanfana16.Str)({ example: "test@example.com" }),
|
|
2810
|
+
name: (0, import_chanfana16.Str)({ example: "Test Recipient" })
|
|
2477
2811
|
}).array(),
|
|
2478
|
-
content:
|
|
2812
|
+
content: import_zod16.z.object({}).catchall(import_zod16.z.string())
|
|
2479
2813
|
})
|
|
2480
2814
|
}
|
|
2481
2815
|
}
|
|
@@ -2493,8 +2827,8 @@ var SendEmail = class extends import_chanfana12.OpenAPIRoute {
|
|
|
2493
2827
|
};
|
|
2494
2828
|
|
|
2495
2829
|
// src/modules/server/getInfo.ts
|
|
2496
|
-
var
|
|
2497
|
-
var GetInfo = class extends
|
|
2830
|
+
var import_chanfana17 = require("chanfana");
|
|
2831
|
+
var GetInfo = class extends import_chanfana17.OpenAPIRoute {
|
|
2498
2832
|
schema = {
|
|
2499
2833
|
operationId: "get-server-info",
|
|
2500
2834
|
tags: ["Server"],
|
|
@@ -2504,7 +2838,7 @@ var GetInfo = class extends import_chanfana13.OpenAPIRoute {
|
|
|
2504
2838
|
const { basicAuth: basicAuth2, ...config } = c.get("config");
|
|
2505
2839
|
const buckets = [];
|
|
2506
2840
|
for (const [key, value] of Object.entries(c.env)) {
|
|
2507
|
-
if (value
|
|
2841
|
+
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") {
|
|
2508
2842
|
buckets.push({ name: key });
|
|
2509
2843
|
}
|
|
2510
2844
|
}
|
|
@@ -2522,7 +2856,7 @@ var GetInfo = class extends import_chanfana13.OpenAPIRoute {
|
|
|
2522
2856
|
|
|
2523
2857
|
// src/index.ts
|
|
2524
2858
|
function R2Explorer(config) {
|
|
2525
|
-
(0,
|
|
2859
|
+
(0, import_chanfana18.extendZodWithOpenApi)(import_zod17.z);
|
|
2526
2860
|
config = config || {};
|
|
2527
2861
|
if (config.readonly !== false) config.readonly = true;
|
|
2528
2862
|
const openapiSchema = {
|
|
@@ -2544,7 +2878,7 @@ function R2Explorer(config) {
|
|
|
2544
2878
|
c.set("config", config);
|
|
2545
2879
|
await next();
|
|
2546
2880
|
});
|
|
2547
|
-
const openapi = (0,
|
|
2881
|
+
const openapi = (0, import_chanfana18.fromHono)(app, {
|
|
2548
2882
|
schema: openapiSchema,
|
|
2549
2883
|
raiseUnknownParameters: true,
|
|
2550
2884
|
generateOperationIds: false
|
|
@@ -2597,9 +2931,13 @@ function R2Explorer(config) {
|
|
|
2597
2931
|
openapi.post("/api/buckets/:bucket/delete", DeleteObject);
|
|
2598
2932
|
openapi.on("head", "/api/buckets/:bucket/:key", HeadObject);
|
|
2599
2933
|
openapi.get("/api/buckets/:bucket/:key/head", HeadObject);
|
|
2934
|
+
openapi.post("/api/buckets/:bucket/:key/share", CreateShareLink);
|
|
2935
|
+
openapi.get("/api/buckets/:bucket/shares", ListShares);
|
|
2936
|
+
openapi.delete("/api/buckets/:bucket/share/:shareId", DeleteShareLink);
|
|
2600
2937
|
openapi.get("/api/buckets/:bucket/:key", GetObject);
|
|
2601
2938
|
openapi.post("/api/buckets/:bucket/:key", PutMetadata);
|
|
2602
2939
|
openapi.post("/api/emails/send", SendEmail);
|
|
2940
|
+
openapi.get("/share/:shareId", GetShareLink);
|
|
2603
2941
|
openapi.get("/", dashboardIndex);
|
|
2604
2942
|
openapi.get("*", dashboardRedirect);
|
|
2605
2943
|
app.all(
|