@hasna/instructions 0.4.36 → 0.4.39
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 +9 -8
- package/assets/skills/inbox/SKILL.md +86 -0
- package/dashboard/README.md +34 -70
- package/dist/cli/index.js +1839 -721
- package/dist/cli/raw-store-root.test.d.ts +2 -0
- package/dist/cli/raw-store-root.test.d.ts.map +1 -0
- package/dist/data/config-store.d.ts +4 -4
- package/dist/data/config-store.d.ts.map +1 -1
- package/dist/db/configs.d.ts.map +1 -1
- package/dist/db/database.d.ts.map +1 -1
- package/dist/generated/storage-kit/backend.d.ts +20 -0
- package/dist/generated/storage-kit/backend.d.ts.map +1 -0
- package/dist/generated/storage-kit/index.d.ts +2 -2
- package/dist/generated/storage-kit/index.d.ts.map +1 -1
- package/dist/generated/storage-kit/migrations.d.ts.map +1 -1
- package/dist/generated/storage-kit/own.d.ts +11 -0
- package/dist/generated/storage-kit/own.d.ts.map +1 -0
- package/dist/generated/storage-kit/pool.d.ts +7 -6
- package/dist/generated/storage-kit/pool.d.ts.map +1 -1
- package/dist/generated/storage-kit/tls.d.ts +30 -3
- package/dist/generated/storage-kit/tls.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1237 -704
- package/dist/lib/managed-skill-runtimes.d.ts +80 -0
- package/dist/lib/managed-skill-runtimes.d.ts.map +1 -0
- package/dist/lib/managed-skill-runtimes.test.d.ts +2 -0
- package/dist/lib/managed-skill-runtimes.test.d.ts.map +1 -0
- package/dist/lib/raw-store-root.d.ts +17 -0
- package/dist/lib/raw-store-root.d.ts.map +1 -0
- package/dist/lib/retired-storage-mode.d.ts +8 -0
- package/dist/lib/retired-storage-mode.d.ts.map +1 -0
- package/dist/lib/session-apply.d.ts.map +1 -1
- package/dist/lib/session-authority.d.ts +27 -0
- package/dist/lib/session-authority.d.ts.map +1 -0
- package/dist/lib/session-authority.test.d.ts +2 -0
- package/dist/lib/session-authority.test.d.ts.map +1 -0
- package/dist/lib/session-render.d.ts +5 -3
- package/dist/lib/session-render.d.ts.map +1 -1
- package/dist/mcp/index.js +303 -246
- package/dist/server/cloud.d.ts +2 -2
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +875 -496
- package/dist/status.d.ts +11 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/storage/cloud-store.d.ts.map +1 -1
- package/dist/storage/cloud-store.test.d.ts +2 -0
- package/dist/storage/cloud-store.test.d.ts.map +1 -0
- package/package.json +10 -7
- package/dist/generated/storage-kit/mode.d.ts +0 -48
- package/dist/generated/storage-kit/mode.d.ts.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -16,7 +16,7 @@ var __export = (target, all) => {
|
|
|
16
16
|
};
|
|
17
17
|
var __require = import.meta.require;
|
|
18
18
|
|
|
19
|
-
// node_modules/hono/dist/compose.js
|
|
19
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/compose.js
|
|
20
20
|
var compose = (middleware, onError, onNotFound) => {
|
|
21
21
|
return (context, next) => {
|
|
22
22
|
let index = -1;
|
|
@@ -60,21 +60,42 @@ var compose = (middleware, onError, onNotFound) => {
|
|
|
60
60
|
};
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
// node_modules/hono/dist/request/constants.js
|
|
63
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/request/constants.js
|
|
64
64
|
var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
|
|
65
65
|
|
|
66
|
-
// node_modules/hono/dist/utils/
|
|
66
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/utils/buffer.js
|
|
67
|
+
var bufferToFormData = (arrayBuffer, contentType) => {
|
|
68
|
+
const response = new Response(arrayBuffer, {
|
|
69
|
+
headers: {
|
|
70
|
+
"Content-Type": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return response.formData();
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/utils/body.js
|
|
77
|
+
var isRawRequest = (request) => ("headers" in request);
|
|
67
78
|
var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
|
|
68
79
|
const { all = false, dot = false } = options;
|
|
69
|
-
const headers = request
|
|
80
|
+
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
|
70
81
|
const contentType = headers.get("Content-Type");
|
|
71
|
-
|
|
82
|
+
const mediaType = contentType?.split(";")[0].trim().toLowerCase();
|
|
83
|
+
if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
|
|
72
84
|
return parseFormData(request, { all, dot });
|
|
73
85
|
}
|
|
74
86
|
return {};
|
|
75
87
|
};
|
|
76
88
|
async function parseFormData(request, options) {
|
|
77
|
-
|
|
89
|
+
if (!isRawRequest(request) && request.bodyCache.formData) {
|
|
90
|
+
return convertFormDataToBodyData(await request.bodyCache.formData, options);
|
|
91
|
+
}
|
|
92
|
+
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
|
93
|
+
const arrayBuffer = await request.arrayBuffer();
|
|
94
|
+
const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
|
|
95
|
+
if (!isRawRequest(request)) {
|
|
96
|
+
request.bodyCache.formData = formDataPromise;
|
|
97
|
+
}
|
|
98
|
+
const formData = await formDataPromise;
|
|
78
99
|
if (formData) {
|
|
79
100
|
return convertFormDataToBodyData(formData, options);
|
|
80
101
|
}
|
|
@@ -134,7 +155,7 @@ var handleParsingNestedValues = (form, key, value) => {
|
|
|
134
155
|
});
|
|
135
156
|
};
|
|
136
157
|
|
|
137
|
-
// node_modules/hono/dist/utils/url.js
|
|
158
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/utils/url.js
|
|
138
159
|
var splitPath = (path) => {
|
|
139
160
|
const paths = path.split("/");
|
|
140
161
|
if (paths[0] === "") {
|
|
@@ -256,18 +277,16 @@ var checkOptionalParameter = (path) => {
|
|
|
256
277
|
});
|
|
257
278
|
return results.filter((v, i, a) => a.indexOf(v) === i);
|
|
258
279
|
};
|
|
280
|
+
var tryDecodeURIComponent = (str) => str.indexOf("%") !== -1 ? tryDecode(str, decodeURIComponent_) : str;
|
|
259
281
|
var _decodeURI = (value) => {
|
|
260
|
-
if (!/[%+]/.test(value)) {
|
|
261
|
-
return value;
|
|
262
|
-
}
|
|
263
282
|
if (value.indexOf("+") !== -1) {
|
|
264
283
|
value = value.replace(/\+/g, " ");
|
|
265
284
|
}
|
|
266
|
-
return
|
|
285
|
+
return tryDecodeURIComponent(value);
|
|
267
286
|
};
|
|
268
287
|
var _getQueryParam = (url, key, multiple) => {
|
|
269
288
|
let encoded;
|
|
270
|
-
if (!multiple && key &&
|
|
289
|
+
if (!multiple && key && key.indexOf("%") === -1 && key.indexOf("+") === -1) {
|
|
271
290
|
let keyIndex2 = url.indexOf("?", 8);
|
|
272
291
|
if (keyIndex2 === -1) {
|
|
273
292
|
return;
|
|
@@ -291,7 +310,7 @@ var _getQueryParam = (url, key, multiple) => {
|
|
|
291
310
|
return;
|
|
292
311
|
}
|
|
293
312
|
}
|
|
294
|
-
const results =
|
|
313
|
+
const results = /* @__PURE__ */ Object.create(null);
|
|
295
314
|
encoded ??= /[%+]/.test(url);
|
|
296
315
|
let keyIndex = url.indexOf("?", 8);
|
|
297
316
|
while (keyIndex !== -1) {
|
|
@@ -334,8 +353,7 @@ var getQueryParams = (url, key) => {
|
|
|
334
353
|
};
|
|
335
354
|
var decodeURIComponent_ = decodeURIComponent;
|
|
336
355
|
|
|
337
|
-
// node_modules/hono/dist/request.js
|
|
338
|
-
var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
|
|
356
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/request.js
|
|
339
357
|
var HonoRequest = class {
|
|
340
358
|
raw;
|
|
341
359
|
#validatedData;
|
|
@@ -347,7 +365,6 @@ var HonoRequest = class {
|
|
|
347
365
|
this.raw = request;
|
|
348
366
|
this.path = path;
|
|
349
367
|
this.#matchResult = matchResult;
|
|
350
|
-
this.#validatedData = {};
|
|
351
368
|
}
|
|
352
369
|
param(key) {
|
|
353
370
|
return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
|
|
@@ -355,7 +372,7 @@ var HonoRequest = class {
|
|
|
355
372
|
#getDecodedParam(key) {
|
|
356
373
|
const paramKey = this.#matchResult[0][this.routeIndex][1][key];
|
|
357
374
|
const param = this.#getParamValue(paramKey);
|
|
358
|
-
return param &&
|
|
375
|
+
return param && tryDecodeURIComponent(param);
|
|
359
376
|
}
|
|
360
377
|
#getAllDecodedParams() {
|
|
361
378
|
const decoded = {};
|
|
@@ -363,7 +380,7 @@ var HonoRequest = class {
|
|
|
363
380
|
for (const key of keys) {
|
|
364
381
|
const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
|
|
365
382
|
if (value !== undefined) {
|
|
366
|
-
decoded[key] =
|
|
383
|
+
decoded[key] = tryDecodeURIComponent(value);
|
|
367
384
|
}
|
|
368
385
|
}
|
|
369
386
|
return decoded;
|
|
@@ -381,7 +398,7 @@ var HonoRequest = class {
|
|
|
381
398
|
if (name) {
|
|
382
399
|
return this.raw.headers.get(name) ?? undefined;
|
|
383
400
|
}
|
|
384
|
-
const headerData =
|
|
401
|
+
const headerData = /* @__PURE__ */ Object.create(null);
|
|
385
402
|
this.raw.headers.forEach((value, key) => {
|
|
386
403
|
headerData[key] = value;
|
|
387
404
|
});
|
|
@@ -396,8 +413,7 @@ var HonoRequest = class {
|
|
|
396
413
|
if (cachedBody) {
|
|
397
414
|
return cachedBody;
|
|
398
415
|
}
|
|
399
|
-
const anyCachedKey
|
|
400
|
-
if (anyCachedKey) {
|
|
416
|
+
for (const anyCachedKey in bodyCache) {
|
|
401
417
|
return bodyCache[anyCachedKey].then((body) => {
|
|
402
418
|
if (anyCachedKey === "json") {
|
|
403
419
|
body = JSON.stringify(body);
|
|
@@ -416,6 +432,9 @@ var HonoRequest = class {
|
|
|
416
432
|
arrayBuffer() {
|
|
417
433
|
return this.#cachedBody("arrayBuffer");
|
|
418
434
|
}
|
|
435
|
+
bytes() {
|
|
436
|
+
return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
|
|
437
|
+
}
|
|
419
438
|
blob() {
|
|
420
439
|
return this.#cachedBody("blob");
|
|
421
440
|
}
|
|
@@ -423,10 +442,10 @@ var HonoRequest = class {
|
|
|
423
442
|
return this.#cachedBody("formData");
|
|
424
443
|
}
|
|
425
444
|
addValidatedData(target, data) {
|
|
426
|
-
this.#validatedData[target] = data;
|
|
445
|
+
(this.#validatedData ??= {})[target] = data;
|
|
427
446
|
}
|
|
428
447
|
valid(target) {
|
|
429
|
-
return this.#validatedData[target];
|
|
448
|
+
return this.#validatedData?.[target];
|
|
430
449
|
}
|
|
431
450
|
get url() {
|
|
432
451
|
return this.raw.url;
|
|
@@ -445,7 +464,7 @@ var HonoRequest = class {
|
|
|
445
464
|
}
|
|
446
465
|
};
|
|
447
466
|
|
|
448
|
-
// node_modules/hono/dist/utils/html.js
|
|
467
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/utils/html.js
|
|
449
468
|
var HtmlEscapedCallbackPhase = {
|
|
450
469
|
Stringify: 1,
|
|
451
470
|
BeforeStream: 2,
|
|
@@ -483,7 +502,7 @@ var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) =>
|
|
|
483
502
|
}
|
|
484
503
|
};
|
|
485
504
|
|
|
486
|
-
// node_modules/hono/dist/context.js
|
|
505
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/context.js
|
|
487
506
|
var TEXT_PLAIN = "text/plain; charset=UTF-8";
|
|
488
507
|
var setDefaultContentType = (contentType, headers) => {
|
|
489
508
|
return {
|
|
@@ -601,11 +620,11 @@ var Context = class {
|
|
|
601
620
|
return Object.fromEntries(this.#var);
|
|
602
621
|
}
|
|
603
622
|
#newResponse(data, arg, headers) {
|
|
604
|
-
|
|
605
|
-
if (typeof arg === "object" &&
|
|
606
|
-
|
|
607
|
-
for (const [key, value] of
|
|
608
|
-
if (key
|
|
623
|
+
let responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders;
|
|
624
|
+
if (typeof arg === "object" && arg.headers) {
|
|
625
|
+
responseHeaders ??= new Headers;
|
|
626
|
+
for (const [key, value] of new Headers(arg.headers)) {
|
|
627
|
+
if (key === "set-cookie") {
|
|
609
628
|
responseHeaders.append(key, value);
|
|
610
629
|
} else {
|
|
611
630
|
responseHeaders.set(key, value);
|
|
@@ -613,19 +632,34 @@ var Context = class {
|
|
|
613
632
|
}
|
|
614
633
|
}
|
|
615
634
|
if (headers) {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
635
|
+
if (!responseHeaders) {
|
|
636
|
+
let count = 0;
|
|
637
|
+
for (const k in headers) {
|
|
638
|
+
if (++count > 1 || typeof headers[k] !== "string") {
|
|
639
|
+
responseHeaders = new Headers;
|
|
640
|
+
break;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (responseHeaders) {
|
|
645
|
+
for (const k in headers) {
|
|
646
|
+
const v = headers[k];
|
|
647
|
+
if (typeof v === "string") {
|
|
648
|
+
responseHeaders.set(k, v);
|
|
649
|
+
} else {
|
|
650
|
+
responseHeaders.delete(k);
|
|
651
|
+
for (const v2 of v) {
|
|
652
|
+
responseHeaders.append(k, v2);
|
|
653
|
+
}
|
|
623
654
|
}
|
|
624
655
|
}
|
|
625
656
|
}
|
|
626
657
|
}
|
|
627
658
|
const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
|
|
628
|
-
return createResponseInstance(data, {
|
|
659
|
+
return createResponseInstance(data, {
|
|
660
|
+
status,
|
|
661
|
+
headers: responseHeaders ?? headers
|
|
662
|
+
});
|
|
629
663
|
}
|
|
630
664
|
newResponse = (...args) => this.#newResponse(...args);
|
|
631
665
|
body = (data, arg, headers) => this.#newResponse(data, arg, headers);
|
|
@@ -650,18 +684,18 @@ var Context = class {
|
|
|
650
684
|
};
|
|
651
685
|
};
|
|
652
686
|
|
|
653
|
-
// node_modules/hono/dist/router.js
|
|
687
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router.js
|
|
654
688
|
var METHOD_NAME_ALL = "ALL";
|
|
655
689
|
var METHOD_NAME_ALL_LOWERCASE = "all";
|
|
656
|
-
var METHODS = ["get", "post", "put", "delete", "options", "patch"];
|
|
690
|
+
var METHODS = ["get", "post", "put", "delete", "options", "patch", "query"];
|
|
657
691
|
var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
|
|
658
692
|
var UnsupportedPathError = class extends Error {
|
|
659
693
|
};
|
|
660
694
|
|
|
661
|
-
// node_modules/hono/dist/utils/constants.js
|
|
695
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/utils/constants.js
|
|
662
696
|
var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
|
|
663
697
|
|
|
664
|
-
// node_modules/hono/dist/hono-base.js
|
|
698
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/hono-base.js
|
|
665
699
|
var notFoundHandler = (c) => {
|
|
666
700
|
return c.text("404 Not Found", 404);
|
|
667
701
|
};
|
|
@@ -680,6 +714,7 @@ var Hono = class _Hono {
|
|
|
680
714
|
delete;
|
|
681
715
|
options;
|
|
682
716
|
patch;
|
|
717
|
+
query;
|
|
683
718
|
all;
|
|
684
719
|
on;
|
|
685
720
|
use;
|
|
@@ -752,7 +787,7 @@ var Hono = class _Hono {
|
|
|
752
787
|
handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
|
|
753
788
|
handler[COMPOSED_HANDLER] = r.handler;
|
|
754
789
|
}
|
|
755
|
-
subApp.#addRoute(r.method, r.path, handler);
|
|
790
|
+
subApp.#addRoute(r.method, r.path, handler, r.basePath);
|
|
756
791
|
});
|
|
757
792
|
return this;
|
|
758
793
|
}
|
|
@@ -799,7 +834,7 @@ var Hono = class _Hono {
|
|
|
799
834
|
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
|
|
800
835
|
return (request) => {
|
|
801
836
|
const url = new URL(request.url);
|
|
802
|
-
url.pathname =
|
|
837
|
+
url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
|
|
803
838
|
return new Request(url, request);
|
|
804
839
|
};
|
|
805
840
|
})();
|
|
@@ -813,10 +848,15 @@ var Hono = class _Hono {
|
|
|
813
848
|
this.#addRoute(METHOD_NAME_ALL, mergePath(path, "*"), handler);
|
|
814
849
|
return this;
|
|
815
850
|
}
|
|
816
|
-
#addRoute(method, path, handler) {
|
|
851
|
+
#addRoute(method, path, handler, baseRoutePath) {
|
|
817
852
|
method = method.toUpperCase();
|
|
818
853
|
path = mergePath(this._basePath, path);
|
|
819
|
-
const r = {
|
|
854
|
+
const r = {
|
|
855
|
+
basePath: baseRoutePath !== undefined ? mergePath(this._basePath, baseRoutePath) : this._basePath,
|
|
856
|
+
path,
|
|
857
|
+
method,
|
|
858
|
+
handler
|
|
859
|
+
};
|
|
820
860
|
this.router.add(method, path, [handler, r]);
|
|
821
861
|
this.routes.push(r);
|
|
822
862
|
}
|
|
@@ -880,7 +920,7 @@ var Hono = class _Hono {
|
|
|
880
920
|
};
|
|
881
921
|
};
|
|
882
922
|
|
|
883
|
-
// node_modules/hono/dist/router/reg-exp-router/matcher.js
|
|
923
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router/reg-exp-router/matcher.js
|
|
884
924
|
var emptyParam = [];
|
|
885
925
|
function match(method, path) {
|
|
886
926
|
const matchers = this.buildAllMatchers();
|
|
@@ -901,7 +941,7 @@ function match(method, path) {
|
|
|
901
941
|
return match2(method, path);
|
|
902
942
|
}
|
|
903
943
|
|
|
904
|
-
// node_modules/hono/dist/router/reg-exp-router/node.js
|
|
944
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router/reg-exp-router/node.js
|
|
905
945
|
var LABEL_REG_EXP_STR = "[^/]+";
|
|
906
946
|
var ONLY_WILDCARD_REG_EXP_STR = ".*";
|
|
907
947
|
var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
|
|
@@ -915,7 +955,7 @@ function compareKey(a, b) {
|
|
|
915
955
|
return 1;
|
|
916
956
|
}
|
|
917
957
|
if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
|
|
918
|
-
return 1;
|
|
958
|
+
return b === TAIL_WILDCARD_REG_EXP_STR ? -1 : 1;
|
|
919
959
|
} else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
|
|
920
960
|
return -1;
|
|
921
961
|
}
|
|
@@ -930,69 +970,68 @@ var Node = class _Node {
|
|
|
930
970
|
#index;
|
|
931
971
|
#varIndex;
|
|
932
972
|
#children = /* @__PURE__ */ Object.create(null);
|
|
933
|
-
insert(tokens, index, paramMap, context,
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
}
|
|
954
|
-
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
|
955
|
-
if (/\((?!\?:)/.test(regexpStr)) {
|
|
956
|
-
throw PATH_ERROR;
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
node = this.#children[regexpStr];
|
|
960
|
-
if (!node) {
|
|
961
|
-
if (Object.keys(this.#children).some((k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR)) {
|
|
962
|
-
throw PATH_ERROR;
|
|
973
|
+
insert(tokens, index, paramMap, context, isStatic) {
|
|
974
|
+
let node = this;
|
|
975
|
+
for (let i = 0, len = tokens.length;i < len; i++) {
|
|
976
|
+
const token = tokens[i];
|
|
977
|
+
const pattern = token.length === 1 ? token === "*" ? i === len - 1 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : null : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
|
978
|
+
let nextNode;
|
|
979
|
+
if (pattern) {
|
|
980
|
+
const name = pattern[1];
|
|
981
|
+
let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
|
|
982
|
+
if (name && pattern[2]) {
|
|
983
|
+
if (regexpStr === ".*") {
|
|
984
|
+
throw PATH_ERROR;
|
|
985
|
+
}
|
|
986
|
+
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
|
987
|
+
if (/\((?!\?:)/.test(regexpStr)) {
|
|
988
|
+
throw PATH_ERROR;
|
|
989
|
+
}
|
|
990
|
+
if (regexpStr.length === 1 && regExpMetaChars.has(regexpStr)) {
|
|
991
|
+
throw PATH_ERROR;
|
|
992
|
+
}
|
|
963
993
|
}
|
|
964
|
-
|
|
965
|
-
|
|
994
|
+
nextNode = node.#children[regexpStr];
|
|
995
|
+
if (!nextNode) {
|
|
996
|
+
if (regexpStr !== ONLY_WILDCARD_REG_EXP_STR && regexpStr !== TAIL_WILDCARD_REG_EXP_STR) {
|
|
997
|
+
for (const k in node.#children) {
|
|
998
|
+
if ((regexpStr.length > 1 || k.length > 1) && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR) {
|
|
999
|
+
throw PATH_ERROR;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
nextNode = node.#children[regexpStr] = new _Node;
|
|
966
1004
|
}
|
|
967
|
-
node = this.#children[regexpStr] = new _Node;
|
|
968
1005
|
if (name !== "") {
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
}
|
|
972
|
-
if (!pathErrorCheckOnly && name !== "") {
|
|
973
|
-
paramMap.push([name, node.#varIndex]);
|
|
974
|
-
}
|
|
975
|
-
} else {
|
|
976
|
-
node = this.#children[token];
|
|
977
|
-
if (!node) {
|
|
978
|
-
if (Object.keys(this.#children).some((k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR)) {
|
|
979
|
-
throw PATH_ERROR;
|
|
1006
|
+
nextNode.#varIndex ??= context.varIndex++;
|
|
1007
|
+
paramMap.push([name, nextNode.#varIndex]);
|
|
980
1008
|
}
|
|
981
|
-
|
|
982
|
-
|
|
1009
|
+
} else {
|
|
1010
|
+
nextNode = node.#children[token];
|
|
1011
|
+
if (!nextNode) {
|
|
1012
|
+
for (const k in node.#children) {
|
|
1013
|
+
if (k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR) {
|
|
1014
|
+
throw PATH_ERROR;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
nextNode = node.#children[token] = new _Node;
|
|
983
1018
|
}
|
|
984
|
-
node = this.#children[token] = new _Node;
|
|
985
1019
|
}
|
|
1020
|
+
node = nextNode;
|
|
1021
|
+
}
|
|
1022
|
+
if (node.#index !== undefined) {
|
|
1023
|
+
throw PATH_ERROR;
|
|
986
1024
|
}
|
|
987
|
-
node
|
|
1025
|
+
node.#index = isStatic ? -1 : index;
|
|
988
1026
|
}
|
|
989
1027
|
buildRegExpStr() {
|
|
990
1028
|
const childKeys = Object.keys(this.#children).sort(compareKey);
|
|
991
1029
|
const strList = childKeys.map((k) => {
|
|
992
1030
|
const c = this.#children[k];
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
1031
|
+
const childStr = c.buildRegExpStr();
|
|
1032
|
+
return childStr === "" ? "" : (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + childStr;
|
|
1033
|
+
}).filter(Boolean);
|
|
1034
|
+
if (typeof this.#index === "number" && this.#index !== -1) {
|
|
996
1035
|
strList.unshift(`#${this.#index}`);
|
|
997
1036
|
}
|
|
998
1037
|
if (strList.length === 0) {
|
|
@@ -1005,16 +1044,23 @@ var Node = class _Node {
|
|
|
1005
1044
|
}
|
|
1006
1045
|
};
|
|
1007
1046
|
|
|
1008
|
-
// node_modules/hono/dist/router/reg-exp-router/trie.js
|
|
1047
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router/reg-exp-router/trie.js
|
|
1009
1048
|
var Trie = class {
|
|
1010
1049
|
#context = { varIndex: 0 };
|
|
1011
1050
|
#root = new Node;
|
|
1012
|
-
|
|
1051
|
+
#index = 0;
|
|
1052
|
+
paths = /* @__PURE__ */ Object.create(null);
|
|
1053
|
+
insert(path, isStatic) {
|
|
1054
|
+
if (isStatic) {
|
|
1055
|
+
this.#root.insert(path.split(""), 0, [], this.#context, true);
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1013
1058
|
const paramAssoc = [];
|
|
1014
1059
|
const groups = [];
|
|
1060
|
+
let markedPath = path;
|
|
1015
1061
|
for (let i = 0;; ) {
|
|
1016
1062
|
let replaced = false;
|
|
1017
|
-
|
|
1063
|
+
markedPath = markedPath.replace(/\{[^}]+\}/g, (m) => {
|
|
1018
1064
|
const mark = `@\\${i}`;
|
|
1019
1065
|
groups[i] = [mark, m];
|
|
1020
1066
|
i++;
|
|
@@ -1025,7 +1071,7 @@ var Trie = class {
|
|
|
1025
1071
|
break;
|
|
1026
1072
|
}
|
|
1027
1073
|
}
|
|
1028
|
-
const tokens =
|
|
1074
|
+
const tokens = markedPath.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
|
|
1029
1075
|
for (let i = groups.length - 1;i >= 0; i--) {
|
|
1030
1076
|
const [mark] = groups[i];
|
|
1031
1077
|
for (let j = tokens.length - 1;j >= 0; j--) {
|
|
@@ -1035,8 +1081,8 @@ var Trie = class {
|
|
|
1035
1081
|
}
|
|
1036
1082
|
}
|
|
1037
1083
|
}
|
|
1038
|
-
this.#root.insert(tokens, index, paramAssoc, this.#context,
|
|
1039
|
-
|
|
1084
|
+
this.#root.insert(tokens, this.#index, paramAssoc, this.#context, false);
|
|
1085
|
+
this.paths[path] = [this.#index++, paramAssoc];
|
|
1040
1086
|
}
|
|
1041
1087
|
buildRegExp() {
|
|
1042
1088
|
let regexp = this.#root.buildRegExpStr();
|
|
@@ -1061,8 +1107,7 @@ var Trie = class {
|
|
|
1061
1107
|
}
|
|
1062
1108
|
};
|
|
1063
1109
|
|
|
1064
|
-
// node_modules/hono/dist/router/reg-exp-router/router.js
|
|
1065
|
-
var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
|
|
1110
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router/reg-exp-router/router.js
|
|
1066
1111
|
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
1067
1112
|
function buildWildcardRegExp(path) {
|
|
1068
1113
|
return wildcardRegExpCache[path] ??= new RegExp(path === "*" ? "" : `^${path.replace(/\/\*$|([.\\+*[^\]$()])/g, (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)")}$`);
|
|
@@ -1070,59 +1115,6 @@ function buildWildcardRegExp(path) {
|
|
|
1070
1115
|
function clearWildcardRegExpCache() {
|
|
1071
1116
|
wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
1072
1117
|
}
|
|
1073
|
-
function buildMatcherFromPreprocessedRoutes(routes) {
|
|
1074
|
-
const trie = new Trie;
|
|
1075
|
-
const handlerData = [];
|
|
1076
|
-
if (routes.length === 0) {
|
|
1077
|
-
return nullMatcher;
|
|
1078
|
-
}
|
|
1079
|
-
const routesWithStaticPathFlag = routes.map((route) => [!/\*|\/:/.test(route[0]), ...route]).sort(([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length);
|
|
1080
|
-
const staticMap = /* @__PURE__ */ Object.create(null);
|
|
1081
|
-
for (let i = 0, j = -1, len = routesWithStaticPathFlag.length;i < len; i++) {
|
|
1082
|
-
const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
|
|
1083
|
-
if (pathErrorCheckOnly) {
|
|
1084
|
-
staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
|
|
1085
|
-
} else {
|
|
1086
|
-
j++;
|
|
1087
|
-
}
|
|
1088
|
-
let paramAssoc;
|
|
1089
|
-
try {
|
|
1090
|
-
paramAssoc = trie.insert(path, j, pathErrorCheckOnly);
|
|
1091
|
-
} catch (e) {
|
|
1092
|
-
throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
|
|
1093
|
-
}
|
|
1094
|
-
if (pathErrorCheckOnly) {
|
|
1095
|
-
continue;
|
|
1096
|
-
}
|
|
1097
|
-
handlerData[j] = handlers.map(([h, paramCount]) => {
|
|
1098
|
-
const paramIndexMap = /* @__PURE__ */ Object.create(null);
|
|
1099
|
-
paramCount -= 1;
|
|
1100
|
-
for (;paramCount >= 0; paramCount--) {
|
|
1101
|
-
const [key, value] = paramAssoc[paramCount];
|
|
1102
|
-
paramIndexMap[key] = value;
|
|
1103
|
-
}
|
|
1104
|
-
return [h, paramIndexMap];
|
|
1105
|
-
});
|
|
1106
|
-
}
|
|
1107
|
-
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
1108
|
-
for (let i = 0, len = handlerData.length;i < len; i++) {
|
|
1109
|
-
for (let j = 0, len2 = handlerData[i].length;j < len2; j++) {
|
|
1110
|
-
const map = handlerData[i][j]?.[1];
|
|
1111
|
-
if (!map) {
|
|
1112
|
-
continue;
|
|
1113
|
-
}
|
|
1114
|
-
const keys = Object.keys(map);
|
|
1115
|
-
for (let k = 0, len3 = keys.length;k < len3; k++) {
|
|
1116
|
-
map[keys[k]] = paramReplacementMap[map[keys[k]]];
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
const handlerMap = [];
|
|
1121
|
-
for (const i in indexReplacementMap) {
|
|
1122
|
-
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
1123
|
-
}
|
|
1124
|
-
return [regexp, handlerMap, staticMap];
|
|
1125
|
-
}
|
|
1126
1118
|
function findMiddleware(middleware, path) {
|
|
1127
1119
|
if (!middleware) {
|
|
1128
1120
|
return;
|
|
@@ -1138,9 +1130,18 @@ var RegExpRouter = class {
|
|
|
1138
1130
|
name = "RegExpRouter";
|
|
1139
1131
|
#middleware;
|
|
1140
1132
|
#routes;
|
|
1133
|
+
#tries;
|
|
1141
1134
|
constructor() {
|
|
1142
1135
|
this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
|
|
1143
1136
|
this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
|
|
1137
|
+
this.#tries = { [METHOD_NAME_ALL]: new Trie };
|
|
1138
|
+
}
|
|
1139
|
+
#insertPath(method, path) {
|
|
1140
|
+
try {
|
|
1141
|
+
this.#tries[method].insert(path, !/\*|\/:/.test(path));
|
|
1142
|
+
} catch (e) {
|
|
1143
|
+
throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;
|
|
1144
|
+
}
|
|
1144
1145
|
}
|
|
1145
1146
|
add(method, path, handler) {
|
|
1146
1147
|
const middleware = this.#middleware;
|
|
@@ -1149,10 +1150,12 @@ var RegExpRouter = class {
|
|
|
1149
1150
|
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
|
1150
1151
|
}
|
|
1151
1152
|
if (!middleware[method]) {
|
|
1153
|
+
this.#tries[method] = new Trie;
|
|
1152
1154
|
[middleware, routes].forEach((handlerMap) => {
|
|
1153
1155
|
handlerMap[method] = /* @__PURE__ */ Object.create(null);
|
|
1154
1156
|
Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
|
|
1155
1157
|
handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
|
|
1158
|
+
this.#insertPath(method, p);
|
|
1156
1159
|
});
|
|
1157
1160
|
});
|
|
1158
1161
|
}
|
|
@@ -1162,13 +1165,12 @@ var RegExpRouter = class {
|
|
|
1162
1165
|
const paramCount = (path.match(/\/:/g) || []).length;
|
|
1163
1166
|
if (/\*$/.test(path)) {
|
|
1164
1167
|
const re = buildWildcardRegExp(path);
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
}
|
|
1168
|
+
Object.keys(middleware).forEach((m) => {
|
|
1169
|
+
if ((method === METHOD_NAME_ALL || method === m) && !middleware[m][path]) {
|
|
1170
|
+
this.#insertPath(m, path);
|
|
1171
|
+
middleware[m][path] = findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1172
1174
|
Object.keys(middleware).forEach((m) => {
|
|
1173
1175
|
if (method === METHOD_NAME_ALL || method === m) {
|
|
1174
1176
|
Object.keys(middleware[m]).forEach((p) => {
|
|
@@ -1188,9 +1190,12 @@ var RegExpRouter = class {
|
|
|
1188
1190
|
const path2 = paths[i];
|
|
1189
1191
|
Object.keys(routes).forEach((m) => {
|
|
1190
1192
|
if (method === METHOD_NAME_ALL || method === m) {
|
|
1191
|
-
routes[m][path2]
|
|
1192
|
-
|
|
1193
|
-
|
|
1193
|
+
if (!routes[m][path2]) {
|
|
1194
|
+
this.#insertPath(m, path2);
|
|
1195
|
+
routes[m][path2] = [
|
|
1196
|
+
...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
|
|
1197
|
+
];
|
|
1198
|
+
}
|
|
1194
1199
|
routes[m][path2].push([handler, paramCount - len + i + 1]);
|
|
1195
1200
|
}
|
|
1196
1201
|
});
|
|
@@ -1202,103 +1207,58 @@ var RegExpRouter = class {
|
|
|
1202
1207
|
Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
|
|
1203
1208
|
matchers[method] ||= this.#buildMatcher(method);
|
|
1204
1209
|
});
|
|
1205
|
-
this.#middleware = this.#routes = undefined;
|
|
1210
|
+
this.#middleware = this.#routes = this.#tries = undefined;
|
|
1206
1211
|
clearWildcardRegExpCache();
|
|
1207
1212
|
return matchers;
|
|
1208
1213
|
}
|
|
1209
1214
|
#buildMatcher(method) {
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1215
|
+
const middleware = this.#middleware[method];
|
|
1216
|
+
const routes = this.#routes[method];
|
|
1217
|
+
const trie = this.#tries[method];
|
|
1218
|
+
const staticMap = /* @__PURE__ */ Object.create(null);
|
|
1219
|
+
const handlerData = [];
|
|
1220
|
+
[middleware, routes].forEach((r) => {
|
|
1221
|
+
for (const path in r) {
|
|
1222
|
+
const handlers = r[path];
|
|
1223
|
+
const pathData = trie.paths[path];
|
|
1224
|
+
if (!pathData) {
|
|
1225
|
+
staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
|
|
1226
|
+
continue;
|
|
1227
|
+
}
|
|
1228
|
+
const paramAssoc = pathData[1];
|
|
1229
|
+
handlerData[pathData[0]] = handlers.map(([h, paramCount]) => {
|
|
1230
|
+
const paramIndexMap = /* @__PURE__ */ Object.create(null);
|
|
1231
|
+
paramCount -= 1;
|
|
1232
|
+
for (;paramCount >= 0; paramCount--) {
|
|
1233
|
+
const [key, value] = paramAssoc[paramCount];
|
|
1234
|
+
paramIndexMap[key] = value;
|
|
1235
|
+
}
|
|
1236
|
+
return [h, paramIndexMap];
|
|
1237
|
+
});
|
|
1219
1238
|
}
|
|
1220
1239
|
});
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
};
|
|
1228
|
-
|
|
1229
|
-
// node_modules/hono/dist/router/reg-exp-router/prepared-router.js
|
|
1230
|
-
var PreparedRegExpRouter = class {
|
|
1231
|
-
name = "PreparedRegExpRouter";
|
|
1232
|
-
#matchers;
|
|
1233
|
-
#relocateMap;
|
|
1234
|
-
constructor(matchers, relocateMap) {
|
|
1235
|
-
this.#matchers = matchers;
|
|
1236
|
-
this.#relocateMap = relocateMap;
|
|
1237
|
-
}
|
|
1238
|
-
#addWildcard(method, handlerData) {
|
|
1239
|
-
const matcher = this.#matchers[method];
|
|
1240
|
-
matcher[1].forEach((list) => list && list.push(handlerData));
|
|
1241
|
-
Object.values(matcher[2]).forEach((list) => list[0].push(handlerData));
|
|
1242
|
-
}
|
|
1243
|
-
#addPath(method, path, handler, indexes, map) {
|
|
1244
|
-
const matcher = this.#matchers[method];
|
|
1245
|
-
if (!map) {
|
|
1246
|
-
matcher[2][path][0].push([handler, {}]);
|
|
1247
|
-
} else {
|
|
1248
|
-
indexes.forEach((index) => {
|
|
1249
|
-
if (typeof index === "number") {
|
|
1250
|
-
matcher[1][index].push([handler, map]);
|
|
1251
|
-
} else {
|
|
1252
|
-
matcher[2][index || path][0].push([handler, map]);
|
|
1240
|
+
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
1241
|
+
for (let i = 0, len = handlerData.length;i < len; i++) {
|
|
1242
|
+
for (let j = 0, len2 = handlerData[i].length;j < len2; j++) {
|
|
1243
|
+
const map = handlerData[i][j]?.[1];
|
|
1244
|
+
if (!map) {
|
|
1245
|
+
continue;
|
|
1253
1246
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
add(method, path, handler) {
|
|
1258
|
-
if (!this.#matchers[method]) {
|
|
1259
|
-
const all = this.#matchers[METHOD_NAME_ALL];
|
|
1260
|
-
const staticMap = {};
|
|
1261
|
-
for (const key in all[2]) {
|
|
1262
|
-
staticMap[key] = [all[2][key][0].slice(), emptyParam];
|
|
1263
|
-
}
|
|
1264
|
-
this.#matchers[method] = [
|
|
1265
|
-
all[0],
|
|
1266
|
-
all[1].map((list) => Array.isArray(list) ? list.slice() : 0),
|
|
1267
|
-
staticMap
|
|
1268
|
-
];
|
|
1269
|
-
}
|
|
1270
|
-
if (path === "/*" || path === "*") {
|
|
1271
|
-
const handlerData = [handler, {}];
|
|
1272
|
-
if (method === METHOD_NAME_ALL) {
|
|
1273
|
-
for (const m in this.#matchers) {
|
|
1274
|
-
this.#addWildcard(m, handlerData);
|
|
1247
|
+
const keys = Object.keys(map);
|
|
1248
|
+
for (let k = 0, len3 = keys.length;k < len3; k++) {
|
|
1249
|
+
map[keys[k]] = paramReplacementMap[map[keys[k]]];
|
|
1275
1250
|
}
|
|
1276
|
-
} else {
|
|
1277
|
-
this.#addWildcard(method, handlerData);
|
|
1278
1251
|
}
|
|
1279
|
-
return;
|
|
1280
|
-
}
|
|
1281
|
-
const data = this.#relocateMap[path];
|
|
1282
|
-
if (!data) {
|
|
1283
|
-
throw new Error(`Path ${path} is not registered`);
|
|
1284
1252
|
}
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
this.#addPath(m, path, handler, indexes, map);
|
|
1289
|
-
}
|
|
1290
|
-
} else {
|
|
1291
|
-
this.#addPath(method, path, handler, indexes, map);
|
|
1292
|
-
}
|
|
1253
|
+
const handlerMap = [];
|
|
1254
|
+
for (const i in indexReplacementMap) {
|
|
1255
|
+
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
1293
1256
|
}
|
|
1257
|
+
return [regexp, handlerMap, staticMap];
|
|
1294
1258
|
}
|
|
1295
|
-
buildAllMatchers() {
|
|
1296
|
-
return this.#matchers;
|
|
1297
|
-
}
|
|
1298
|
-
match = match;
|
|
1299
1259
|
};
|
|
1300
1260
|
|
|
1301
|
-
// node_modules/hono/dist/router/smart-router/router.js
|
|
1261
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router/smart-router/router.js
|
|
1302
1262
|
var SmartRouter = class {
|
|
1303
1263
|
name = "SmartRouter";
|
|
1304
1264
|
#routers = [];
|
|
@@ -1353,7 +1313,7 @@ var SmartRouter = class {
|
|
|
1353
1313
|
}
|
|
1354
1314
|
};
|
|
1355
1315
|
|
|
1356
|
-
// node_modules/hono/dist/router/trie-router/node.js
|
|
1316
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router/trie-router/node.js
|
|
1357
1317
|
var emptyParams = /* @__PURE__ */ Object.create(null);
|
|
1358
1318
|
var hasChildren = (children) => {
|
|
1359
1319
|
for (const _ in children) {
|
|
@@ -1487,9 +1447,12 @@ var Node2 = class _Node2 {
|
|
|
1487
1447
|
if (m) {
|
|
1488
1448
|
params[name] = m[0];
|
|
1489
1449
|
this.#pushHandlerSets(handlerSets, child, method, node.#params, params);
|
|
1450
|
+
if (m[0].length === restPathString.length && child.#children["*"]) {
|
|
1451
|
+
this.#pushHandlerSets(handlerSets, child.#children["*"], method, node.#params, params);
|
|
1452
|
+
}
|
|
1490
1453
|
if (hasChildren(child.#children)) {
|
|
1491
1454
|
child.#params = params;
|
|
1492
|
-
const componentCount = m[0].match(/\//)?.length ?? 0;
|
|
1455
|
+
const componentCount = m[0].match(/\//g)?.length ?? 0;
|
|
1493
1456
|
const targetCurNodes = curNodesQueue[componentCount] ||= [];
|
|
1494
1457
|
targetCurNodes.push(child);
|
|
1495
1458
|
}
|
|
@@ -1522,7 +1485,7 @@ var Node2 = class _Node2 {
|
|
|
1522
1485
|
}
|
|
1523
1486
|
};
|
|
1524
1487
|
|
|
1525
|
-
// node_modules/hono/dist/router/trie-router/router.js
|
|
1488
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/router/trie-router/router.js
|
|
1526
1489
|
var TrieRouter = class {
|
|
1527
1490
|
name = "TrieRouter";
|
|
1528
1491
|
#node;
|
|
@@ -1544,7 +1507,7 @@ var TrieRouter = class {
|
|
|
1544
1507
|
}
|
|
1545
1508
|
};
|
|
1546
1509
|
|
|
1547
|
-
// node_modules/hono/dist/hono.js
|
|
1510
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/hono.js
|
|
1548
1511
|
var Hono2 = class extends Hono {
|
|
1549
1512
|
constructor(options = {}) {
|
|
1550
1513
|
super(options);
|
|
@@ -1554,24 +1517,18 @@ var Hono2 = class extends Hono {
|
|
|
1554
1517
|
}
|
|
1555
1518
|
};
|
|
1556
1519
|
|
|
1557
|
-
// node_modules/hono/dist/middleware/cors/index.js
|
|
1520
|
+
// ../../node_modules/.bun/hono@4.13.1/node_modules/hono/dist/middleware/cors/index.js
|
|
1558
1521
|
var cors = (options) => {
|
|
1559
|
-
const
|
|
1522
|
+
const opts = {
|
|
1560
1523
|
origin: "*",
|
|
1561
|
-
allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
|
|
1524
|
+
allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH", "QUERY"],
|
|
1562
1525
|
allowHeaders: [],
|
|
1563
|
-
exposeHeaders: []
|
|
1564
|
-
};
|
|
1565
|
-
const opts = {
|
|
1566
|
-
...defaults,
|
|
1526
|
+
exposeHeaders: [],
|
|
1567
1527
|
...options
|
|
1568
1528
|
};
|
|
1569
1529
|
const findAllowOrigin = ((optsOrigin) => {
|
|
1570
1530
|
if (typeof optsOrigin === "string") {
|
|
1571
1531
|
if (optsOrigin === "*") {
|
|
1572
|
-
if (opts.credentials) {
|
|
1573
|
-
return (origin) => origin || null;
|
|
1574
|
-
}
|
|
1575
1532
|
return () => optsOrigin;
|
|
1576
1533
|
} else {
|
|
1577
1534
|
return (origin) => optsOrigin === origin ? origin : null;
|
|
@@ -1606,7 +1563,7 @@ var cors = (options) => {
|
|
|
1606
1563
|
set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
|
|
1607
1564
|
}
|
|
1608
1565
|
if (c.req.method === "OPTIONS") {
|
|
1609
|
-
if (opts.origin !== "*"
|
|
1566
|
+
if (opts.origin !== "*") {
|
|
1610
1567
|
set("Vary", "Origin");
|
|
1611
1568
|
}
|
|
1612
1569
|
if (opts.maxAge != null) {
|
|
@@ -1620,7 +1577,7 @@ var cors = (options) => {
|
|
|
1620
1577
|
if (!headers?.length) {
|
|
1621
1578
|
const requestHeaders = c.req.header("Access-Control-Request-Headers");
|
|
1622
1579
|
if (requestHeaders) {
|
|
1623
|
-
headers = requestHeaders.split(
|
|
1580
|
+
headers = requestHeaders.split(",").map((h) => h.trim());
|
|
1624
1581
|
}
|
|
1625
1582
|
}
|
|
1626
1583
|
if (headers?.length) {
|
|
@@ -1636,7 +1593,7 @@ var cors = (options) => {
|
|
|
1636
1593
|
});
|
|
1637
1594
|
}
|
|
1638
1595
|
await next();
|
|
1639
|
-
if (opts.origin !== "*"
|
|
1596
|
+
if (opts.origin !== "*") {
|
|
1640
1597
|
c.header("Vary", "Origin", { append: true });
|
|
1641
1598
|
}
|
|
1642
1599
|
};
|
|
@@ -1715,14 +1672,90 @@ class ProfileNotFoundError extends Error {
|
|
|
1715
1672
|
}
|
|
1716
1673
|
}
|
|
1717
1674
|
|
|
1718
|
-
//
|
|
1675
|
+
// ../contracts/dist/auth/index.js
|
|
1719
1676
|
import { createHash, createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
1677
|
+
var MAX_TENANT_ID_LENGTH = 64;
|
|
1678
|
+
var TENANT_ID_PATTERN = new RegExp(`^[A-Za-z0-9][A-Za-z0-9._-]{0,${MAX_TENANT_ID_LENGTH - 1}}$`);
|
|
1679
|
+
var UUID_HEX = "[0-9a-fA-F]";
|
|
1680
|
+
var UUID_PATTERN = new RegExp(`^\\{?(?:${UUID_HEX}{8}-${UUID_HEX}{4}-${UUID_HEX}{4}-${UUID_HEX}{4}-${UUID_HEX}{12}|${UUID_HEX}{32})\\}?$`);
|
|
1681
|
+
function isValidTenantId(value) {
|
|
1682
|
+
return typeof value === "string" && TENANT_ID_PATTERN.test(value);
|
|
1683
|
+
}
|
|
1684
|
+
function isUuidTenantId(value) {
|
|
1685
|
+
return typeof value === "string" && UUID_PATTERN.test(value);
|
|
1686
|
+
}
|
|
1687
|
+
function canonicalizeTenantId(value) {
|
|
1688
|
+
if (!isUuidTenantId(value))
|
|
1689
|
+
return value;
|
|
1690
|
+
const hex = value.replace(/[{}-]/g, "").toLowerCase();
|
|
1691
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
1692
|
+
}
|
|
1693
|
+
function normalizeTenantId(value) {
|
|
1694
|
+
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
1695
|
+
const canonical = canonicalizeTenantId(trimmed);
|
|
1696
|
+
if (!isValidTenantId(canonical)) {
|
|
1697
|
+
throw new Error(`Invalid tenant id '${value}'. Expected 1-${MAX_TENANT_ID_LENGTH} characters matching ${TENANT_ID_PATTERN} (a UUID, ULID, slug, or prefixed id).`);
|
|
1698
|
+
}
|
|
1699
|
+
return canonical;
|
|
1700
|
+
}
|
|
1701
|
+
function tenantIdsEqual(left, right) {
|
|
1702
|
+
const canonical = (value) => {
|
|
1703
|
+
if (typeof value !== "string")
|
|
1704
|
+
return null;
|
|
1705
|
+
const folded = canonicalizeTenantId(value.trim());
|
|
1706
|
+
return isValidTenantId(folded) ? folded : null;
|
|
1707
|
+
};
|
|
1708
|
+
const a = canonical(left);
|
|
1709
|
+
const b = canonical(right);
|
|
1710
|
+
return a !== null && b !== null && a === b;
|
|
1711
|
+
}
|
|
1712
|
+
function ownTenantId(source) {
|
|
1713
|
+
return Object.hasOwn(source, "tid") ? source.tid : undefined;
|
|
1714
|
+
}
|
|
1720
1715
|
var API_KEY_TOKEN_VERSION = 1;
|
|
1721
1716
|
var API_KEY_NAMESPACE = "hasna";
|
|
1722
|
-
var
|
|
1717
|
+
var API_KEY_TOKEN_PATTERN = /^hasna_([a-z][a-z0-9-]*)_([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)$/;
|
|
1718
|
+
var TOKEN_PATTERN = API_KEY_TOKEN_PATTERN;
|
|
1723
1719
|
var DEFAULT_API_KEY_TTL_SECONDS = 90 * 24 * 60 * 60;
|
|
1720
|
+
function ownAgentClaim(source) {
|
|
1721
|
+
return Object.hasOwn(source, "agent") && typeof source.agent === "string" ? source.agent : null;
|
|
1722
|
+
}
|
|
1723
|
+
function ownScopesClaim(source) {
|
|
1724
|
+
return Object.hasOwn(source, "scopes") && Array.isArray(source.scopes) ? source.scopes : null;
|
|
1725
|
+
}
|
|
1726
|
+
function ownOption(options, name) {
|
|
1727
|
+
return Object.hasOwn(options, name) ? options[name] : undefined;
|
|
1728
|
+
}
|
|
1729
|
+
var typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
1730
|
+
var intrinsicViewBuffer = Object.getOwnPropertyDescriptor(typedArrayPrototype, "buffer").get;
|
|
1731
|
+
var intrinsicViewByteOffset = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteOffset").get;
|
|
1732
|
+
var intrinsicViewByteLength = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength").get;
|
|
1733
|
+
var intrinsicDataViewBuffer = Object.getOwnPropertyDescriptor(DataView.prototype, "buffer").get;
|
|
1734
|
+
var intrinsicDataViewByteOffset = Object.getOwnPropertyDescriptor(DataView.prototype, "byteOffset").get;
|
|
1735
|
+
var intrinsicDataViewByteLength = Object.getOwnPropertyDescriptor(DataView.prototype, "byteLength").get;
|
|
1736
|
+
function viewWindow(view) {
|
|
1737
|
+
try {
|
|
1738
|
+
return [
|
|
1739
|
+
intrinsicViewBuffer.call(view),
|
|
1740
|
+
intrinsicViewByteOffset.call(view),
|
|
1741
|
+
intrinsicViewByteLength.call(view)
|
|
1742
|
+
];
|
|
1743
|
+
} catch {
|
|
1744
|
+
return [
|
|
1745
|
+
intrinsicDataViewBuffer.call(view),
|
|
1746
|
+
intrinsicDataViewByteOffset.call(view),
|
|
1747
|
+
intrinsicDataViewByteLength.call(view)
|
|
1748
|
+
];
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1724
1751
|
function toBuffer(secret) {
|
|
1725
|
-
|
|
1752
|
+
if (typeof secret === "string")
|
|
1753
|
+
return Buffer.from(secret, "utf8");
|
|
1754
|
+
if (ArrayBuffer.isView(secret)) {
|
|
1755
|
+
const [store, byteOffset, byteLength] = viewWindow(secret);
|
|
1756
|
+
return Buffer.from(store, byteOffset, byteLength);
|
|
1757
|
+
}
|
|
1758
|
+
return Buffer.from(secret);
|
|
1726
1759
|
}
|
|
1727
1760
|
function hmac(signingSecret, message) {
|
|
1728
1761
|
return createHmac("sha256", toBuffer(signingSecret)).update(message, "utf8").digest();
|
|
@@ -1745,12 +1778,23 @@ function parseApiKey(token) {
|
|
|
1745
1778
|
} catch {
|
|
1746
1779
|
return null;
|
|
1747
1780
|
}
|
|
1748
|
-
if (typeof claims !== "object" || claims === null || typeof claims.kid !== "string" || typeof claims.app !== "string" ||
|
|
1781
|
+
if (typeof claims !== "object" || claims === null || typeof claims.kid !== "string" || typeof claims.app !== "string" || ownScopesClaim(claims) === null) {
|
|
1782
|
+
return null;
|
|
1783
|
+
}
|
|
1784
|
+
const claimedTid = ownTenantId(claims);
|
|
1785
|
+
if (claimedTid !== undefined && !isValidTenantId(claimedTid)) {
|
|
1749
1786
|
return null;
|
|
1750
1787
|
}
|
|
1751
1788
|
return { app, body, sig, claims };
|
|
1752
1789
|
}
|
|
1753
1790
|
function verifyApiKeyToken(token, options) {
|
|
1791
|
+
const optSigningSecret = ownOption(options, "signingSecret");
|
|
1792
|
+
const optExpectedApp = ownOption(options, "expectedApp");
|
|
1793
|
+
const optNowMs = ownOption(options, "nowMs");
|
|
1794
|
+
const optLeewaySeconds = ownOption(options, "leewaySeconds");
|
|
1795
|
+
const optRequiredScopes = ownOption(options, "requiredScopes");
|
|
1796
|
+
const optRequireTenant = ownOption(options, "requireTenant");
|
|
1797
|
+
const optExpectedTid = ownOption(options, "expectedTid");
|
|
1754
1798
|
const parsed = parseApiKey(token);
|
|
1755
1799
|
if (!parsed) {
|
|
1756
1800
|
return { ok: false, reason: "malformed", message: "Token is malformed." };
|
|
@@ -1762,10 +1806,10 @@ function verifyApiKeyToken(token, options) {
|
|
|
1762
1806
|
if (claims.app !== app) {
|
|
1763
1807
|
return { ok: false, reason: "app_mismatch", message: "Token prefix app does not match claims." };
|
|
1764
1808
|
}
|
|
1765
|
-
if (
|
|
1766
|
-
return { ok: false, reason: "app_mismatch", message: `Token is for app '${app}', expected '${
|
|
1809
|
+
if (optExpectedApp !== undefined && app !== optExpectedApp) {
|
|
1810
|
+
return { ok: false, reason: "app_mismatch", message: `Token is for app '${app}', expected '${optExpectedApp}'.` };
|
|
1767
1811
|
}
|
|
1768
|
-
const expected = hmac(
|
|
1812
|
+
const expected = hmac(optSigningSecret, `${apiKeyPrefix(app)}${body}`);
|
|
1769
1813
|
let provided;
|
|
1770
1814
|
try {
|
|
1771
1815
|
provided = Buffer.from(sig, "base64url");
|
|
@@ -1775,16 +1819,41 @@ function verifyApiKeyToken(token, options) {
|
|
|
1775
1819
|
if (provided.length !== expected.length || !timingSafeEqual(provided, expected)) {
|
|
1776
1820
|
return { ok: false, reason: "bad_signature", message: "Signature verification failed." };
|
|
1777
1821
|
}
|
|
1778
|
-
const
|
|
1779
|
-
const
|
|
1822
|
+
const agent = ownAgentClaim(claims);
|
|
1823
|
+
const now = Math.floor((optNowMs ?? Date.now()) / 1000);
|
|
1824
|
+
const leeway = optLeewaySeconds ?? 0;
|
|
1780
1825
|
if (typeof claims.iat === "number" && now + leeway < claims.iat) {
|
|
1781
|
-
return { ok: false, reason: "not_yet_valid", message: "Token is not yet valid." };
|
|
1826
|
+
return { ok: false, reason: "not_yet_valid", message: "Token is not yet valid.", agent };
|
|
1782
1827
|
}
|
|
1783
1828
|
if (claims.exp !== null && typeof claims.exp === "number" && now - leeway >= claims.exp) {
|
|
1784
|
-
return { ok: false, reason: "expired", message: "Token has expired." };
|
|
1829
|
+
return { ok: false, reason: "expired", message: "Token has expired.", agent };
|
|
1830
|
+
}
|
|
1831
|
+
const verifiedTid = ownTenantId(claims);
|
|
1832
|
+
const tid = verifiedTid === undefined ? null : canonicalizeTenantId(verifiedTid);
|
|
1833
|
+
const tenantRequired = Boolean(optRequireTenant) || optExpectedTid !== undefined;
|
|
1834
|
+
if (tenantRequired && tid === null) {
|
|
1835
|
+
return {
|
|
1836
|
+
ok: false,
|
|
1837
|
+
reason: "tenant_required",
|
|
1838
|
+
message: "Token carries no tenant id ('tid') and this service requires one.",
|
|
1839
|
+
kid: claims.kid,
|
|
1840
|
+
tid: null,
|
|
1841
|
+
agent
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
if (optExpectedTid !== undefined && !tenantIdsEqual(tid, optExpectedTid)) {
|
|
1845
|
+
const expectationIsWellFormed = typeof optExpectedTid === "string" && isValidTenantId(optExpectedTid.trim());
|
|
1846
|
+
return {
|
|
1847
|
+
ok: false,
|
|
1848
|
+
reason: "tenant_mismatch",
|
|
1849
|
+
message: expectationIsWellFormed ? "Token is for a different tenant than the one this service accepts." : "Token tenant cannot be checked: the expected tenant id is not a valid tenant id.",
|
|
1850
|
+
kid: claims.kid,
|
|
1851
|
+
tid,
|
|
1852
|
+
agent
|
|
1853
|
+
};
|
|
1785
1854
|
}
|
|
1786
|
-
if (
|
|
1787
|
-
const granted = claims
|
|
1855
|
+
if (optRequiredScopes && optRequiredScopes.length > 0) {
|
|
1856
|
+
const granted = ownScopesClaim(claims) ?? [];
|
|
1788
1857
|
const satisfies = (required) => granted.some((g) => {
|
|
1789
1858
|
if (g === "*")
|
|
1790
1859
|
return true;
|
|
@@ -1798,15 +1867,16 @@ function verifyApiKeyToken(token, options) {
|
|
|
1798
1867
|
const rAction = required.slice(ri + 1);
|
|
1799
1868
|
return (gApp === "*" || gApp === rApp) && (gAction === "*" || gAction === rAction);
|
|
1800
1869
|
});
|
|
1801
|
-
for (const required of
|
|
1870
|
+
for (const required of optRequiredScopes) {
|
|
1802
1871
|
if (!satisfies(required)) {
|
|
1803
|
-
return { ok: false, reason: "insufficient_scope", message: `Missing required scope '${required}'
|
|
1872
|
+
return { ok: false, reason: "insufficient_scope", message: `Missing required scope '${required}'.`, agent };
|
|
1804
1873
|
}
|
|
1805
1874
|
}
|
|
1806
1875
|
}
|
|
1807
|
-
return { ok: true, claims, kid: claims.kid, app };
|
|
1876
|
+
return { ok: true, claims, kid: claims.kid, app, tid, agent };
|
|
1808
1877
|
}
|
|
1809
1878
|
var DEFAULT_API_KEYS_TABLE = "api_keys";
|
|
1879
|
+
var API_KEY_ISSUANCE_PENDING_REASON = "credential_delivery_pending";
|
|
1810
1880
|
function createTableSql(table) {
|
|
1811
1881
|
return `CREATE TABLE IF NOT EXISTS ${table} (
|
|
1812
1882
|
kid TEXT PRIMARY KEY,
|
|
@@ -1830,6 +1900,11 @@ function apiKeyMigrations(table = DEFAULT_API_KEYS_TABLE) {
|
|
|
1830
1900
|
id: `hasna_auth_0002_${table}_indexes`,
|
|
1831
1901
|
sql: `CREATE INDEX IF NOT EXISTS ${table}_app_idx ON ${table} (app);
|
|
1832
1902
|
CREATE INDEX IF NOT EXISTS ${table}_token_hash_idx ON ${table} (token_hash);`
|
|
1903
|
+
},
|
|
1904
|
+
{
|
|
1905
|
+
id: `hasna_auth_0003_${table}_tenant`,
|
|
1906
|
+
sql: `ALTER TABLE ${table} ADD COLUMN IF NOT EXISTS tid TEXT;
|
|
1907
|
+
CREATE INDEX IF NOT EXISTS ${table}_tid_idx ON ${table} (tid);`
|
|
1833
1908
|
}
|
|
1834
1909
|
];
|
|
1835
1910
|
}
|
|
@@ -1854,10 +1929,13 @@ function parseScopes(value) {
|
|
|
1854
1929
|
return [];
|
|
1855
1930
|
}
|
|
1856
1931
|
function rowToRecord(row) {
|
|
1932
|
+
const tid = ownTenantId(row);
|
|
1933
|
+
const agentValue = Object.hasOwn(row, "agent") ? row.agent : null;
|
|
1857
1934
|
return {
|
|
1858
1935
|
kid: String(row.kid),
|
|
1859
1936
|
app: String(row.app),
|
|
1860
|
-
agent:
|
|
1937
|
+
agent: agentValue === null || agentValue === undefined ? null : String(agentValue),
|
|
1938
|
+
tid: tid === null || tid === undefined ? null : String(tid),
|
|
1861
1939
|
scopes: parseScopes(row.scopes),
|
|
1862
1940
|
tokenHash: String(row.token_hash),
|
|
1863
1941
|
issuedAt: toIso(row.issued_at) ?? new Date(0).toISOString(),
|
|
@@ -1888,31 +1966,63 @@ class ApiKeyStore {
|
|
|
1888
1966
|
}
|
|
1889
1967
|
}
|
|
1890
1968
|
async insert(input) {
|
|
1969
|
+
await this.insertWithLifecycle(input, null, null);
|
|
1970
|
+
}
|
|
1971
|
+
async insertWithLifecycle(input, revokedAt, revokedReason) {
|
|
1972
|
+
const tid = ownTenantId(input);
|
|
1973
|
+
const agent = ownAgentClaim(input);
|
|
1891
1974
|
await this.client.execute(`INSERT INTO ${this.table}
|
|
1892
|
-
(kid, app, agent, scopes, token_hash, issued_at, expires_at, created_by)
|
|
1893
|
-
VALUES ($1, $2, $3, $4
|
|
1975
|
+
(kid, app, agent, tid, scopes, token_hash, issued_at, expires_at, created_by, revoked_at, revoked_reason)
|
|
1976
|
+
VALUES ($1, $2, $3, $4, $5::jsonb, $6, $7, $8, $9, $10, $11)`, [
|
|
1894
1977
|
input.kid,
|
|
1895
1978
|
input.app,
|
|
1896
|
-
|
|
1979
|
+
agent,
|
|
1980
|
+
tid === undefined || tid === null ? null : normalizeTenantId(tid),
|
|
1897
1981
|
JSON.stringify(input.scopes),
|
|
1898
1982
|
input.tokenHash,
|
|
1899
1983
|
input.issuedAt.toISOString(),
|
|
1900
1984
|
input.expiresAt ? input.expiresAt.toISOString() : null,
|
|
1901
|
-
input.createdBy ?? null
|
|
1985
|
+
input.createdBy ?? null,
|
|
1986
|
+
revokedAt,
|
|
1987
|
+
revokedReason
|
|
1902
1988
|
]);
|
|
1903
1989
|
}
|
|
1904
|
-
|
|
1990
|
+
mintedInput(minted, createdBy) {
|
|
1905
1991
|
const claims = minted.claims;
|
|
1906
|
-
|
|
1992
|
+
return {
|
|
1907
1993
|
kid: minted.kid,
|
|
1908
1994
|
app: claims.app,
|
|
1909
|
-
agent: claims
|
|
1995
|
+
agent: ownAgentClaim(claims),
|
|
1996
|
+
tid: ownTenantId(claims) ?? null,
|
|
1910
1997
|
scopes: claims.scopes,
|
|
1911
1998
|
tokenHash: minted.tokenHash,
|
|
1912
1999
|
issuedAt: new Date(claims.iat * 1000),
|
|
1913
2000
|
expiresAt: claims.exp === null ? null : new Date(claims.exp * 1000),
|
|
1914
2001
|
createdBy: createdBy ?? null
|
|
1915
|
-
}
|
|
2002
|
+
};
|
|
2003
|
+
}
|
|
2004
|
+
async insertMinted(minted, createdBy) {
|
|
2005
|
+
await this.insert(this.mintedInput(minted, createdBy));
|
|
2006
|
+
}
|
|
2007
|
+
async insertMintedPending(minted, createdBy, atMs = Date.now()) {
|
|
2008
|
+
await this.insertWithLifecycle(this.mintedInput(minted, createdBy), new Date(atMs).toISOString(), API_KEY_ISSUANCE_PENDING_REASON);
|
|
2009
|
+
}
|
|
2010
|
+
async activatePending(kid, tokenHash) {
|
|
2011
|
+
const row = await this.client.get(`UPDATE ${this.table}
|
|
2012
|
+
SET revoked_at = NULL, revoked_reason = NULL
|
|
2013
|
+
WHERE kid = $1
|
|
2014
|
+
AND revoked_at IS NOT NULL
|
|
2015
|
+
AND revoked_reason = $2
|
|
2016
|
+
AND token_hash = $3
|
|
2017
|
+
RETURNING kid`, [kid, API_KEY_ISSUANCE_PENDING_REASON, tokenHash]);
|
|
2018
|
+
if (row)
|
|
2019
|
+
return true;
|
|
2020
|
+
const active = await this.client.get(`SELECT kid FROM ${this.table}
|
|
2021
|
+
WHERE kid = $1
|
|
2022
|
+
AND token_hash = $2
|
|
2023
|
+
AND revoked_at IS NULL
|
|
2024
|
+
AND revoked_reason IS NULL`, [kid, tokenHash]);
|
|
2025
|
+
return active !== null;
|
|
1916
2026
|
}
|
|
1917
2027
|
async findByKid(kid) {
|
|
1918
2028
|
const row = await this.client.get(`SELECT * FROM ${this.table} WHERE kid = $1`, [kid]);
|
|
@@ -1938,6 +2048,9 @@ class ApiKeyStore {
|
|
|
1938
2048
|
return "expired";
|
|
1939
2049
|
return "active";
|
|
1940
2050
|
}
|
|
2051
|
+
keyStatus = async (kid) => {
|
|
2052
|
+
return this.status(kid);
|
|
2053
|
+
};
|
|
1941
2054
|
statusChecker() {
|
|
1942
2055
|
return async (kid) => {
|
|
1943
2056
|
const status = await this.status(kid);
|
|
@@ -1964,11 +2077,16 @@ class ApiKeyStore {
|
|
|
1964
2077
|
params.push(options.app);
|
|
1965
2078
|
clauses.push(`app = $${params.length}`);
|
|
1966
2079
|
}
|
|
2080
|
+
const tid = ownTenantId(options);
|
|
2081
|
+
if (tid !== undefined) {
|
|
2082
|
+
params.push(normalizeTenantId(tid));
|
|
2083
|
+
clauses.push(`tid = $${params.length}`);
|
|
2084
|
+
}
|
|
1967
2085
|
if (!options.includeRevoked) {
|
|
1968
2086
|
clauses.push("revoked_at IS NULL");
|
|
1969
2087
|
}
|
|
1970
2088
|
const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
1971
|
-
const rows = await this.client.many(`SELECT * FROM ${this.table} ${where} ORDER BY issued_at DESC
|
|
2089
|
+
const rows = await this.client.many(`SELECT * FROM ${this.table} ${where} ORDER BY issued_at DESC`, params);
|
|
1972
2090
|
return rows.map(rowToRecord);
|
|
1973
2091
|
}
|
|
1974
2092
|
async revokedKids() {
|
|
@@ -2005,27 +2123,65 @@ function extractToken(source, headerName = "x-api-key", scheme = "Bearer") {
|
|
|
2005
2123
|
}
|
|
2006
2124
|
return null;
|
|
2007
2125
|
}
|
|
2126
|
+
function ownOption2(bag, name) {
|
|
2127
|
+
return Object.hasOwn(bag, name) ? bag[name] : undefined;
|
|
2128
|
+
}
|
|
2008
2129
|
function verifyApiKey(options) {
|
|
2009
|
-
|
|
2130
|
+
const optionApp = ownOption2(options, "app");
|
|
2131
|
+
const optionSigningSecret = ownOption2(options, "signingSecret");
|
|
2132
|
+
const optionExpectedTid = ownOption2(options, "expectedTid");
|
|
2133
|
+
const optionRequiredScopes = ownOption2(options, "requiredScopes");
|
|
2134
|
+
const optionRequireTenant = ownOption2(options, "requireTenant");
|
|
2135
|
+
const optionLeewaySeconds = ownOption2(options, "leewaySeconds");
|
|
2136
|
+
const audit = ownOption2(options, "audit");
|
|
2137
|
+
const headerName = ownOption2(options, "headerName") ?? "x-api-key";
|
|
2138
|
+
const scheme = ownOption2(options, "scheme") ?? "Bearer";
|
|
2139
|
+
const clock = ownOption2(options, "nowMs") ?? (() => Date.now());
|
|
2140
|
+
if (!optionApp)
|
|
2010
2141
|
throw new Error("verifyApiKey requires an 'app' slug.");
|
|
2011
|
-
if (!
|
|
2142
|
+
if (!optionSigningSecret) {
|
|
2012
2143
|
throw new Error("verifyApiKey requires a 'signingSecret'. Set it from HASNA_<APP>_API_SIGNING_KEY.");
|
|
2013
2144
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2145
|
+
if (optionExpectedTid !== undefined && !isValidTenantId(optionExpectedTid)) {
|
|
2146
|
+
throw new Error(`verifyApiKey received an invalid 'expectedTid': '${optionExpectedTid}'.`);
|
|
2147
|
+
}
|
|
2148
|
+
const app = optionApp;
|
|
2149
|
+
const signingSecret = optionSigningSecret;
|
|
2150
|
+
const ownKeyStatus = ownOption2(options, "keyStatus");
|
|
2151
|
+
const ownIsRevoked = ownOption2(options, "isRevoked");
|
|
2152
|
+
const allowUnregistered = ownOption2(options, "allowUnregisteredKeys") === true;
|
|
2153
|
+
if (ownKeyStatus && ownIsRevoked) {
|
|
2154
|
+
throw new Error("verifyApiKey received both 'keyStatus' and 'isRevoked'. Supply exactly one \u2014 " + "letting one silently win would hide which check is actually guarding the service. " + "Use 'keyStatus' (store.keyStatus); drop 'isRevoked'.");
|
|
2155
|
+
}
|
|
2156
|
+
if (!ownKeyStatus && !allowUnregistered) {
|
|
2157
|
+
throw new Error(ownIsRevoked ? "verifyApiKey was given only 'isRevoked', which cannot refuse a key this service has " + "no record of: it returns false both for an active key and for one that was never " + "registered, so an unregistered key is irrevocable. Wire 'keyStatus: store.keyStatus' " + "(or 'isRevoked: store.statusChecker()'), or set 'allowUnregisteredKeys: true' to " + "accept that risk explicitly." : "verifyApiKey requires a key-status hook. Without one this service performs NO " + "revocation check and cannot turn any of its keys off. Wire " + "'keyStatus: store.keyStatus', or set 'allowUnregisteredKeys: true' to declare that " + "this service intentionally cannot revoke keys.");
|
|
2158
|
+
}
|
|
2017
2159
|
async function emit(event) {
|
|
2018
|
-
if (!
|
|
2160
|
+
if (!audit)
|
|
2019
2161
|
return;
|
|
2020
2162
|
try {
|
|
2021
|
-
await
|
|
2163
|
+
await audit(event);
|
|
2022
2164
|
} catch {}
|
|
2023
2165
|
}
|
|
2024
2166
|
async function authenticate(headers, context = {}) {
|
|
2025
|
-
const method = context
|
|
2026
|
-
const path = context
|
|
2027
|
-
const requiredScopes = [
|
|
2167
|
+
const method = ownOption2(context, "method") ?? null;
|
|
2168
|
+
const path = ownOption2(context, "path") ?? null;
|
|
2169
|
+
const requiredScopes = [
|
|
2170
|
+
...optionRequiredScopes ?? [],
|
|
2171
|
+
...ownOption2(context, "requiredScopes") ?? []
|
|
2172
|
+
];
|
|
2028
2173
|
const at = new Date(clock()).toISOString();
|
|
2174
|
+
const perCallTid = ownOption2(context, "expectedTid");
|
|
2175
|
+
const expectedTid = perCallTid !== undefined ? perCallTid : optionExpectedTid;
|
|
2176
|
+
if (perCallTid !== undefined && optionExpectedTid !== undefined && !tenantIdsEqual(perCallTid, optionExpectedTid)) {
|
|
2177
|
+
await emit({ outcome: "deny", app, kid: null, tid: null, reason: "tenant_mismatch", scopesRequired: requiredScopes, method, path, status: 403, at });
|
|
2178
|
+
return {
|
|
2179
|
+
ok: false,
|
|
2180
|
+
status: 403,
|
|
2181
|
+
reason: "tenant_mismatch",
|
|
2182
|
+
message: "This route addresses a tenant other than the one this service is pinned to."
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2029
2185
|
const token = extractToken(headers, headerName, scheme);
|
|
2030
2186
|
if (!token) {
|
|
2031
2187
|
const decision = {
|
|
@@ -2034,25 +2190,72 @@ function verifyApiKey(options) {
|
|
|
2034
2190
|
reason: "missing_token",
|
|
2035
2191
|
message: `Missing API key. Send it as '${headerName}: <key>' or 'Authorization: ${scheme} <key>'.`
|
|
2036
2192
|
};
|
|
2037
|
-
await emit({ outcome: "deny", app:
|
|
2193
|
+
await emit({ outcome: "deny", app, kid: null, tid: null, reason: "missing_token", scopesRequired: requiredScopes, method, path, status: 401, at });
|
|
2038
2194
|
return decision;
|
|
2039
2195
|
}
|
|
2040
2196
|
const verified = verifyApiKeyToken(token, {
|
|
2041
|
-
signingSecret
|
|
2042
|
-
expectedApp:
|
|
2197
|
+
signingSecret,
|
|
2198
|
+
expectedApp: app,
|
|
2043
2199
|
nowMs: clock(),
|
|
2044
|
-
...
|
|
2200
|
+
...optionLeewaySeconds !== undefined ? { leewaySeconds: optionLeewaySeconds } : {},
|
|
2201
|
+
...optionRequireTenant !== undefined ? { requireTenant: optionRequireTenant } : {},
|
|
2202
|
+
...expectedTid !== undefined ? { expectedTid } : {},
|
|
2045
2203
|
requiredScopes
|
|
2046
2204
|
});
|
|
2047
2205
|
if (!verified.ok) {
|
|
2048
|
-
const status = verified.reason === "insufficient_scope" ? 403 : 401;
|
|
2049
|
-
await emit({
|
|
2206
|
+
const status = verified.reason === "insufficient_scope" || verified.reason === "tenant_mismatch" || verified.reason === "tenant_required" ? 403 : 401;
|
|
2207
|
+
await emit({
|
|
2208
|
+
outcome: "deny",
|
|
2209
|
+
app,
|
|
2210
|
+
kid: ownOption2(verified, "kid") ?? null,
|
|
2211
|
+
tid: ownTenantId(verified) ?? null,
|
|
2212
|
+
...Object.hasOwn(verified, "agent") ? { agent: verified.agent } : {},
|
|
2213
|
+
reason: verified.reason,
|
|
2214
|
+
scopesRequired: requiredScopes,
|
|
2215
|
+
method,
|
|
2216
|
+
path,
|
|
2217
|
+
status,
|
|
2218
|
+
at
|
|
2219
|
+
});
|
|
2050
2220
|
return { ok: false, status, reason: verified.reason, message: verified.message };
|
|
2051
2221
|
}
|
|
2052
|
-
if (
|
|
2053
|
-
|
|
2222
|
+
if (ownKeyStatus) {
|
|
2223
|
+
let status;
|
|
2224
|
+
try {
|
|
2225
|
+
status = await ownKeyStatus(verified.kid);
|
|
2226
|
+
} catch {
|
|
2227
|
+
await emit({ outcome: "deny", app, kid: verified.kid, tid: verified.tid, agent: verified.agent, reason: "status_unavailable", scopesRequired: requiredScopes, method, path, status: 503, at });
|
|
2228
|
+
return {
|
|
2229
|
+
ok: false,
|
|
2230
|
+
status: 503,
|
|
2231
|
+
reason: "status_unavailable",
|
|
2232
|
+
message: "Could not verify API key status. Try again shortly."
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
if (status !== "active") {
|
|
2236
|
+
const known = status === "revoked" || status === "expired" || status === "unknown";
|
|
2237
|
+
if (!(status === "unknown" && allowUnregistered)) {
|
|
2238
|
+
const reason = status === "revoked" || status === "expired" ? status : "unknown_key";
|
|
2239
|
+
const message = reason === "unknown_key" ? known ? "API key is not registered with this service." : "API key status could not be recognized." : status === "expired" ? "API key has expired." : "API key has been revoked.";
|
|
2240
|
+
await emit({ outcome: "deny", app, kid: verified.kid, tid: verified.tid, agent: verified.agent, reason, scopesRequired: requiredScopes, method, path, status: 401, at });
|
|
2241
|
+
return { ok: false, status: 401, reason, message };
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
} else if (ownIsRevoked) {
|
|
2245
|
+
let revoked;
|
|
2246
|
+
try {
|
|
2247
|
+
revoked = await ownIsRevoked(verified.kid);
|
|
2248
|
+
} catch {
|
|
2249
|
+
await emit({ outcome: "deny", app, kid: verified.kid, tid: verified.tid, agent: verified.agent, reason: "status_unavailable", scopesRequired: requiredScopes, method, path, status: 503, at });
|
|
2250
|
+
return {
|
|
2251
|
+
ok: false,
|
|
2252
|
+
status: 503,
|
|
2253
|
+
reason: "status_unavailable",
|
|
2254
|
+
message: "Could not verify API key status. Try again shortly."
|
|
2255
|
+
};
|
|
2256
|
+
}
|
|
2054
2257
|
if (revoked) {
|
|
2055
|
-
await emit({ outcome: "deny", app:
|
|
2258
|
+
await emit({ outcome: "deny", app, kid: verified.kid, tid: verified.tid, agent: verified.agent, reason: "revoked", scopesRequired: requiredScopes, method, path, status: 401, at });
|
|
2056
2259
|
return { ok: false, status: 401, reason: "revoked", message: "API key has been revoked." };
|
|
2057
2260
|
}
|
|
2058
2261
|
}
|
|
@@ -2060,13 +2263,14 @@ function verifyApiKey(options) {
|
|
|
2060
2263
|
kid: verified.kid,
|
|
2061
2264
|
app: verified.app,
|
|
2062
2265
|
scopes: verified.claims.scopes,
|
|
2063
|
-
agent: verified.
|
|
2266
|
+
agent: verified.agent,
|
|
2267
|
+
tid: verified.tid,
|
|
2064
2268
|
claims: verified.claims
|
|
2065
2269
|
};
|
|
2066
|
-
await emit({ outcome: "allow", app:
|
|
2270
|
+
await emit({ outcome: "allow", app, kid: verified.kid, tid: verified.tid, agent: verified.agent, reason: null, scopesRequired: requiredScopes, method, path, status: 200, at });
|
|
2067
2271
|
return { ok: true, status: 200, principal };
|
|
2068
2272
|
}
|
|
2069
|
-
return { authenticate, app
|
|
2273
|
+
return { authenticate, app };
|
|
2070
2274
|
}
|
|
2071
2275
|
function honoApiKey(options) {
|
|
2072
2276
|
const verifier = verifyApiKey(options);
|
|
@@ -2082,53 +2286,153 @@ function honoApiKey(options) {
|
|
|
2082
2286
|
return c.json({ error: decision.message, reason: decision.reason }, decision.status);
|
|
2083
2287
|
};
|
|
2084
2288
|
}
|
|
2289
|
+
var MAX_FLEET_TOKEN_TTL_SECONDS = 24 * 60 * 60;
|
|
2290
|
+
|
|
2291
|
+
// src/generated/storage-kit/own.ts
|
|
2292
|
+
function ownProp(source, key) {
|
|
2293
|
+
if (source === null || source === undefined)
|
|
2294
|
+
return;
|
|
2295
|
+
const kind = typeof source;
|
|
2296
|
+
if (kind !== "object" && kind !== "function")
|
|
2297
|
+
return;
|
|
2298
|
+
if (!Object.hasOwn(source, key))
|
|
2299
|
+
return;
|
|
2300
|
+
return source[key];
|
|
2301
|
+
}
|
|
2302
|
+
function ownString(source, key) {
|
|
2303
|
+
const value = ownProp(source, key);
|
|
2304
|
+
return typeof value === "string" ? value : undefined;
|
|
2305
|
+
}
|
|
2085
2306
|
// src/generated/storage-kit/tls.ts
|
|
2086
2307
|
import { readFileSync as readFileSync2 } from "fs";
|
|
2087
|
-
|
|
2308
|
+
var PG_TLS_QUERY_PARAMETERS = new Set([
|
|
2309
|
+
"ssl",
|
|
2310
|
+
"sslmode",
|
|
2311
|
+
"sslrootcert",
|
|
2312
|
+
"sslcert",
|
|
2313
|
+
"sslkey",
|
|
2314
|
+
"sslpassword",
|
|
2315
|
+
"sslnegotiation",
|
|
2316
|
+
"uselibpqcompat"
|
|
2317
|
+
]);
|
|
2318
|
+
var EXPLICIT_SSL_ON_VALUES = new Set(["1", "true", "yes", "on", "require"]);
|
|
2319
|
+
var EXPLICIT_SSL_OFF_VALUES = new Set(["0", "false", "no", "off", "disable"]);
|
|
2320
|
+
var SSLMODE_VALUES = new Map([
|
|
2321
|
+
["disable", "disable"],
|
|
2322
|
+
["allow", "prefer"],
|
|
2323
|
+
["prefer", "prefer"],
|
|
2324
|
+
["require", "require"],
|
|
2325
|
+
["verify-ca", "verify-ca"],
|
|
2326
|
+
["verify-full", "verify-full"]
|
|
2327
|
+
]);
|
|
2328
|
+
function connectionStringParts(connectionString) {
|
|
2088
2329
|
const queryStart = connectionString.indexOf("?");
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2330
|
+
if (queryStart === -1) {
|
|
2331
|
+
return { base: connectionString, fragment: "", params: new URLSearchParams };
|
|
2332
|
+
}
|
|
2333
|
+
const base = connectionString.slice(0, queryStart);
|
|
2334
|
+
const queryAndFragment = connectionString.slice(queryStart + 1);
|
|
2335
|
+
const fragmentStart = queryAndFragment.indexOf("#");
|
|
2336
|
+
const query = fragmentStart === -1 ? queryAndFragment : queryAndFragment.slice(0, fragmentStart);
|
|
2337
|
+
const fragment = fragmentStart === -1 ? "" : queryAndFragment.slice(fragmentStart);
|
|
2338
|
+
return { base, fragment, params: new URLSearchParams(query) };
|
|
2339
|
+
}
|
|
2340
|
+
function tlsQueryValues(connectionString) {
|
|
2341
|
+
const values = new Map;
|
|
2342
|
+
for (const [key, value] of connectionStringParts(connectionString).params) {
|
|
2343
|
+
const normalized = key.toLowerCase();
|
|
2344
|
+
if (PG_TLS_QUERY_PARAMETERS.has(normalized))
|
|
2345
|
+
values.set(normalized, value);
|
|
2346
|
+
}
|
|
2347
|
+
return values;
|
|
2348
|
+
}
|
|
2349
|
+
function connectionStringWithoutTlsParameters(connectionString) {
|
|
2350
|
+
const { base, fragment, params } = connectionStringParts(connectionString);
|
|
2351
|
+
for (const key of [...params.keys()]) {
|
|
2352
|
+
if (PG_TLS_QUERY_PARAMETERS.has(key.toLowerCase()))
|
|
2353
|
+
params.delete(key);
|
|
2354
|
+
}
|
|
2355
|
+
const query = params.toString();
|
|
2356
|
+
return `${base}${query ? `?${query}` : ""}${fragment}`;
|
|
2357
|
+
}
|
|
2358
|
+
function rawSslMode(values) {
|
|
2359
|
+
const raw2 = values.get("sslmode");
|
|
2360
|
+
return raw2 === undefined ? undefined : raw2.trim().toLowerCase();
|
|
2361
|
+
}
|
|
2362
|
+
function sslNegotiationFromConnectionString(connectionString) {
|
|
2363
|
+
const value = tlsQueryValues(connectionString).get("sslnegotiation")?.trim().toLowerCase();
|
|
2364
|
+
if (!value)
|
|
2365
|
+
return;
|
|
2366
|
+
if (value === "postgres" || value === "direct")
|
|
2367
|
+
return value;
|
|
2368
|
+
throw new Error(`Unknown sslnegotiation '${value}' in connection string; expected postgres or direct.`);
|
|
2369
|
+
}
|
|
2370
|
+
function sslModeFromConnectionString(connectionString) {
|
|
2371
|
+
const values = tlsQueryValues(connectionString);
|
|
2372
|
+
const sslmode = rawSslMode(values);
|
|
2373
|
+
if (sslmode !== undefined) {
|
|
2374
|
+
const resolved = SSLMODE_VALUES.get(sslmode);
|
|
2375
|
+
if (resolved)
|
|
2376
|
+
return resolved;
|
|
2377
|
+
throw new Error(`Unknown sslmode '${sslmode}' in connection string; expected one of ` + `${[...SSLMODE_VALUES.keys()].join(", ")}. Remove the parameter entirely to defer to ` + `PGSSLMODE \u2014 an empty value is not how that is spelled.`);
|
|
2378
|
+
}
|
|
2379
|
+
if (values.has("ssl")) {
|
|
2380
|
+
const ssl = values.get("ssl")?.trim().toLowerCase() ?? "";
|
|
2381
|
+
if (EXPLICIT_SSL_ON_VALUES.has(ssl))
|
|
2382
|
+
return "require";
|
|
2383
|
+
if (!EXPLICIT_SSL_OFF_VALUES.has(ssl)) {
|
|
2384
|
+
throw new Error(`Unknown ssl value '${ssl}' in connection string.`);
|
|
2385
|
+
}
|
|
2386
|
+
return "disable";
|
|
2387
|
+
}
|
|
2388
|
+
const sslnegotiation = values.get("sslnegotiation")?.trim().toLowerCase();
|
|
2389
|
+
if (sslnegotiation === "direct")
|
|
2107
2390
|
return "require";
|
|
2108
2391
|
return "disable";
|
|
2109
2392
|
}
|
|
2110
|
-
function loadCaBundle(options) {
|
|
2111
|
-
const env = options
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2393
|
+
function loadCaBundle(connectionString, options) {
|
|
2394
|
+
const env = ownProp(options, "env") ?? process.env;
|
|
2395
|
+
const ca = ownString(options, "ca");
|
|
2396
|
+
if (ca && ca.trim())
|
|
2397
|
+
return ca;
|
|
2398
|
+
const sslRootCert = tlsQueryValues(connectionString).get("sslrootcert")?.trim();
|
|
2399
|
+
const path = ownString(options, "caCertPath") ?? (sslRootCert ? sslRootCert : undefined) ?? ownString(env, "PGSSLROOTCERT") ?? ownString(env, "NODE_EXTRA_CA_CERTS");
|
|
2115
2400
|
if (path && path.trim())
|
|
2116
2401
|
return readFileSync2(path.trim(), "utf8");
|
|
2117
2402
|
return null;
|
|
2118
2403
|
}
|
|
2404
|
+
function loadClientCertificate(connectionString) {
|
|
2405
|
+
const values = tlsQueryValues(connectionString);
|
|
2406
|
+
const material = {};
|
|
2407
|
+
const certPath = values.get("sslcert")?.trim();
|
|
2408
|
+
if (certPath)
|
|
2409
|
+
material.cert = readFileSync2(certPath, "utf8");
|
|
2410
|
+
const keyPath = values.get("sslkey")?.trim();
|
|
2411
|
+
if (keyPath)
|
|
2412
|
+
material.key = readFileSync2(keyPath, "utf8");
|
|
2413
|
+
const passphrase = values.get("sslpassword");
|
|
2414
|
+
if (passphrase)
|
|
2415
|
+
material.passphrase = passphrase;
|
|
2416
|
+
return material;
|
|
2417
|
+
}
|
|
2119
2418
|
function resolveTlsConfig(connectionString, options = {}) {
|
|
2120
2419
|
const mode = sslModeFromConnectionString(connectionString);
|
|
2121
|
-
if (mode === "disable"
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
return
|
|
2420
|
+
if (mode === "disable") {
|
|
2421
|
+
const values = tlsQueryValues(connectionString);
|
|
2422
|
+
const sslmode = rawSslMode(values);
|
|
2423
|
+
const ssl = values.get("ssl")?.trim().toLowerCase();
|
|
2424
|
+
const explicitlyOff = sslmode === "disable" || ssl !== undefined && EXPLICIT_SSL_OFF_VALUES.has(ssl);
|
|
2425
|
+
return explicitlyOff ? false : undefined;
|
|
2426
|
+
}
|
|
2427
|
+
const ca = loadCaBundle(connectionString, options);
|
|
2428
|
+
const clientCertificate = loadClientCertificate(connectionString);
|
|
2429
|
+
if (mode === "prefer" || mode === "require") {
|
|
2430
|
+
return { rejectUnauthorized: true, ...ca ? { ca } : {}, ...clientCertificate };
|
|
2127
2431
|
}
|
|
2128
2432
|
if (!ca) {
|
|
2129
2433
|
throw new Error(`sslmode=${mode} requires a CA bundle. Set PGSSLROOTCERT (or pass caCertPath/ca) to the ` + `Amazon RDS global bundle: https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem`);
|
|
2130
2434
|
}
|
|
2131
|
-
return { rejectUnauthorized: true, ca };
|
|
2435
|
+
return { rejectUnauthorized: true, ca, ...clientCertificate };
|
|
2132
2436
|
}
|
|
2133
2437
|
// src/generated/storage-kit/query.ts
|
|
2134
2438
|
function wrapExecutor(executor) {
|
|
@@ -2185,23 +2489,58 @@ function createQueryClient(pool) {
|
|
|
2185
2489
|
}
|
|
2186
2490
|
// src/generated/storage-kit/pool.ts
|
|
2187
2491
|
import pg from "pg";
|
|
2492
|
+
function ownPoolOptions(options) {
|
|
2493
|
+
const own = Object.create(null);
|
|
2494
|
+
const ca = ownString(options, "ca");
|
|
2495
|
+
if (ca !== undefined)
|
|
2496
|
+
own.ca = ca;
|
|
2497
|
+
const caCertPath = ownString(options, "caCertPath");
|
|
2498
|
+
if (caCertPath !== undefined)
|
|
2499
|
+
own.caCertPath = caCertPath;
|
|
2500
|
+
const env = ownProp(options, "env");
|
|
2501
|
+
if (env !== undefined)
|
|
2502
|
+
own.env = env;
|
|
2503
|
+
const max = ownProp(options, "max");
|
|
2504
|
+
if (max !== undefined)
|
|
2505
|
+
own.max = max;
|
|
2506
|
+
const idleTimeoutMillis = ownProp(options, "idleTimeoutMillis");
|
|
2507
|
+
if (idleTimeoutMillis !== undefined)
|
|
2508
|
+
own.idleTimeoutMillis = idleTimeoutMillis;
|
|
2509
|
+
const connectionTimeoutMillis = ownProp(options, "connectionTimeoutMillis");
|
|
2510
|
+
if (connectionTimeoutMillis !== undefined)
|
|
2511
|
+
own.connectionTimeoutMillis = connectionTimeoutMillis;
|
|
2512
|
+
const applicationName = ownString(options, "applicationName");
|
|
2513
|
+
if (applicationName !== undefined)
|
|
2514
|
+
own.applicationName = applicationName;
|
|
2515
|
+
return own;
|
|
2516
|
+
}
|
|
2188
2517
|
function createPgPool(options) {
|
|
2189
|
-
const
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2518
|
+
const connectionString = ownString(options, "connectionString");
|
|
2519
|
+
if (!connectionString || !connectionString.trim()) {
|
|
2520
|
+
throw new Error("createPgPool requires an own `connectionString` on the options object.");
|
|
2521
|
+
}
|
|
2522
|
+
const own = ownPoolOptions(options);
|
|
2523
|
+
const ssl = resolveTlsConfig(connectionString, {
|
|
2524
|
+
...own.ca !== undefined ? { ca: own.ca } : {},
|
|
2525
|
+
...own.caCertPath !== undefined ? { caCertPath: own.caCertPath } : {},
|
|
2526
|
+
...own.env !== undefined ? { env: own.env } : {}
|
|
2193
2527
|
});
|
|
2194
|
-
const config = {
|
|
2528
|
+
const config = {
|
|
2529
|
+
connectionString: connectionStringWithoutTlsParameters(connectionString)
|
|
2530
|
+
};
|
|
2195
2531
|
if (ssl !== undefined)
|
|
2196
2532
|
config.ssl = ssl;
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2533
|
+
const sslnegotiation = sslNegotiationFromConnectionString(connectionString);
|
|
2534
|
+
if (sslnegotiation !== undefined)
|
|
2535
|
+
config.sslnegotiation = sslnegotiation;
|
|
2536
|
+
if (own.max !== undefined)
|
|
2537
|
+
config.max = own.max;
|
|
2538
|
+
if (own.idleTimeoutMillis !== undefined)
|
|
2539
|
+
config.idleTimeoutMillis = own.idleTimeoutMillis;
|
|
2540
|
+
if (own.connectionTimeoutMillis !== undefined)
|
|
2541
|
+
config.connectionTimeoutMillis = own.connectionTimeoutMillis;
|
|
2542
|
+
if (own.applicationName !== undefined)
|
|
2543
|
+
config.application_name = own.applicationName;
|
|
2205
2544
|
return new pg.Pool(config);
|
|
2206
2545
|
}
|
|
2207
2546
|
// src/storage/schema.ts
|
|
@@ -2282,15 +2621,37 @@ function instructionsSchemaSql() {
|
|
|
2282
2621
|
];
|
|
2283
2622
|
}
|
|
2284
2623
|
|
|
2624
|
+
// src/lib/retired-storage-mode.ts
|
|
2625
|
+
var LEGACY_STORAGE_MODE_KEYS = [
|
|
2626
|
+
"HASNA_INSTRUCTIONS_STORAGE_MODE",
|
|
2627
|
+
"HASNA_INSTRUCTIONS_MODE",
|
|
2628
|
+
"INSTRUCTIONS_STORAGE_MODE",
|
|
2629
|
+
"INSTRUCTIONS_MODE"
|
|
2630
|
+
];
|
|
2631
|
+
function firstDefinedEnvKey(env, keys) {
|
|
2632
|
+
for (const key of keys) {
|
|
2633
|
+
if (Object.hasOwn(env, key) && env[key] !== undefined)
|
|
2634
|
+
return key;
|
|
2635
|
+
}
|
|
2636
|
+
return null;
|
|
2637
|
+
}
|
|
2638
|
+
function assertNoLegacyStorageMode(env = process.env) {
|
|
2639
|
+
const legacyKey = firstDefinedEnvKey(env, LEGACY_STORAGE_MODE_KEYS);
|
|
2640
|
+
if (!legacyKey)
|
|
2641
|
+
return;
|
|
2642
|
+
throw new Error(`${legacyKey} was removed. Deployment modes no longer exist: delete the storage-mode variable. ` + `The client uses the local SQLite store, or the HTTP API selected by ` + `HASNA_INSTRUCTIONS_API_URL + HASNA_INSTRUCTIONS_API_KEY. ` + `On the server, set HASNA_INSTRUCTIONS_DATABASE_URL to select the postgresql backend, ` + `or leave it unset for sqlite.`);
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2285
2645
|
// src/server/cloud.ts
|
|
2286
2646
|
var INSTRUCTIONS_APP_SLUG = "instructions";
|
|
2287
2647
|
function resolveCloudDatabaseUrl(env = process.env) {
|
|
2648
|
+
assertNoLegacyStorageMode(env);
|
|
2288
2649
|
return env.HASNA_INSTRUCTIONS_DATABASE_URL || env.INSTRUCTIONS_DATABASE_URL || env.DATABASE_URL || undefined;
|
|
2289
2650
|
}
|
|
2290
2651
|
function resolveSigningSecret(env = process.env) {
|
|
2291
2652
|
return env.HASNA_INSTRUCTIONS_API_SIGNING_KEY || env.HASNA_API_SIGNING_KEY || env.API_KEY_SIGNING_SECRET || undefined;
|
|
2292
2653
|
}
|
|
2293
|
-
function
|
|
2654
|
+
function isPostgresBackendEnabled(env = process.env) {
|
|
2294
2655
|
return Boolean(resolveCloudDatabaseUrl(env));
|
|
2295
2656
|
}
|
|
2296
2657
|
var cachedClient = null;
|
|
@@ -2748,119 +3109,119 @@ Policy reference: \`${CODEWITH_SHARED_TODOS_STORAGE_POLICY_REFERENCE}\`
|
|
|
2748
3109
|
// src/lib/project-context.ts
|
|
2749
3110
|
import { basename, dirname as dirname2, isAbsolute, join as join2, parse, relative, resolve } from "path";
|
|
2750
3111
|
|
|
2751
|
-
// node_modules/zod/v3/external.js
|
|
3112
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
|
|
2752
3113
|
var exports_external = {};
|
|
2753
3114
|
__export(exports_external, {
|
|
2754
|
-
|
|
2755
|
-
util: () => util,
|
|
2756
|
-
unknown: () => unknownType,
|
|
2757
|
-
union: () => unionType,
|
|
2758
|
-
undefined: () => undefinedType,
|
|
2759
|
-
tuple: () => tupleType,
|
|
2760
|
-
transformer: () => effectsType,
|
|
2761
|
-
symbol: () => symbolType,
|
|
2762
|
-
string: () => stringType,
|
|
2763
|
-
strictObject: () => strictObjectType,
|
|
2764
|
-
setErrorMap: () => setErrorMap,
|
|
2765
|
-
set: () => setType,
|
|
2766
|
-
record: () => recordType,
|
|
2767
|
-
quotelessJson: () => quotelessJson,
|
|
2768
|
-
promise: () => promiseType,
|
|
2769
|
-
preprocess: () => preprocessType,
|
|
2770
|
-
pipeline: () => pipelineType,
|
|
2771
|
-
ostring: () => ostring,
|
|
2772
|
-
optional: () => optionalType,
|
|
2773
|
-
onumber: () => onumber,
|
|
2774
|
-
oboolean: () => oboolean,
|
|
2775
|
-
objectUtil: () => objectUtil,
|
|
2776
|
-
object: () => objectType,
|
|
2777
|
-
number: () => numberType,
|
|
2778
|
-
nullable: () => nullableType,
|
|
2779
|
-
null: () => nullType,
|
|
2780
|
-
never: () => neverType,
|
|
2781
|
-
nativeEnum: () => nativeEnumType,
|
|
2782
|
-
nan: () => nanType,
|
|
2783
|
-
map: () => mapType,
|
|
2784
|
-
makeIssue: () => makeIssue,
|
|
2785
|
-
literal: () => literalType,
|
|
2786
|
-
lazy: () => lazyType,
|
|
2787
|
-
late: () => late,
|
|
2788
|
-
isValid: () => isValid,
|
|
2789
|
-
isDirty: () => isDirty,
|
|
2790
|
-
isAsync: () => isAsync,
|
|
2791
|
-
isAborted: () => isAborted,
|
|
2792
|
-
intersection: () => intersectionType,
|
|
2793
|
-
instanceof: () => instanceOfType,
|
|
2794
|
-
getParsedType: () => getParsedType,
|
|
2795
|
-
getErrorMap: () => getErrorMap,
|
|
2796
|
-
function: () => functionType,
|
|
2797
|
-
enum: () => enumType,
|
|
2798
|
-
effect: () => effectsType,
|
|
2799
|
-
discriminatedUnion: () => discriminatedUnionType,
|
|
2800
|
-
defaultErrorMap: () => en_default,
|
|
2801
|
-
datetimeRegex: () => datetimeRegex,
|
|
2802
|
-
date: () => dateType,
|
|
2803
|
-
custom: () => custom,
|
|
2804
|
-
coerce: () => coerce,
|
|
2805
|
-
boolean: () => booleanType,
|
|
2806
|
-
bigint: () => bigIntType,
|
|
2807
|
-
array: () => arrayType,
|
|
2808
|
-
any: () => anyType,
|
|
2809
|
-
addIssueToContext: () => addIssueToContext,
|
|
2810
|
-
ZodVoid: () => ZodVoid,
|
|
2811
|
-
ZodUnknown: () => ZodUnknown,
|
|
2812
|
-
ZodUnion: () => ZodUnion,
|
|
2813
|
-
ZodUndefined: () => ZodUndefined,
|
|
2814
|
-
ZodType: () => ZodType,
|
|
2815
|
-
ZodTuple: () => ZodTuple,
|
|
2816
|
-
ZodTransformer: () => ZodEffects,
|
|
2817
|
-
ZodSymbol: () => ZodSymbol,
|
|
2818
|
-
ZodString: () => ZodString,
|
|
2819
|
-
ZodSet: () => ZodSet,
|
|
2820
|
-
ZodSchema: () => ZodType,
|
|
2821
|
-
ZodRecord: () => ZodRecord,
|
|
2822
|
-
ZodReadonly: () => ZodReadonly,
|
|
2823
|
-
ZodPromise: () => ZodPromise,
|
|
2824
|
-
ZodPipeline: () => ZodPipeline,
|
|
2825
|
-
ZodParsedType: () => ZodParsedType,
|
|
2826
|
-
ZodOptional: () => ZodOptional,
|
|
2827
|
-
ZodObject: () => ZodObject,
|
|
2828
|
-
ZodNumber: () => ZodNumber,
|
|
2829
|
-
ZodNullable: () => ZodNullable,
|
|
2830
|
-
ZodNull: () => ZodNull,
|
|
2831
|
-
ZodNever: () => ZodNever,
|
|
2832
|
-
ZodNativeEnum: () => ZodNativeEnum,
|
|
2833
|
-
ZodNaN: () => ZodNaN,
|
|
2834
|
-
ZodMap: () => ZodMap,
|
|
2835
|
-
ZodLiteral: () => ZodLiteral,
|
|
2836
|
-
ZodLazy: () => ZodLazy,
|
|
2837
|
-
ZodIssueCode: () => ZodIssueCode,
|
|
2838
|
-
ZodIntersection: () => ZodIntersection,
|
|
2839
|
-
ZodFunction: () => ZodFunction,
|
|
2840
|
-
ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
|
|
2841
|
-
ZodError: () => ZodError,
|
|
2842
|
-
ZodEnum: () => ZodEnum,
|
|
2843
|
-
ZodEffects: () => ZodEffects,
|
|
2844
|
-
ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
|
|
2845
|
-
ZodDefault: () => ZodDefault,
|
|
2846
|
-
ZodDate: () => ZodDate,
|
|
2847
|
-
ZodCatch: () => ZodCatch,
|
|
2848
|
-
ZodBranded: () => ZodBranded,
|
|
2849
|
-
ZodBoolean: () => ZodBoolean,
|
|
2850
|
-
ZodBigInt: () => ZodBigInt,
|
|
2851
|
-
ZodArray: () => ZodArray,
|
|
2852
|
-
ZodAny: () => ZodAny,
|
|
2853
|
-
Schema: () => ZodType,
|
|
2854
|
-
ParseStatus: () => ParseStatus,
|
|
2855
|
-
OK: () => OK,
|
|
2856
|
-
NEVER: () => NEVER,
|
|
2857
|
-
INVALID: () => INVALID,
|
|
2858
|
-
EMPTY_PATH: () => EMPTY_PATH,
|
|
3115
|
+
BRAND: () => BRAND,
|
|
2859
3116
|
DIRTY: () => DIRTY,
|
|
2860
|
-
|
|
3117
|
+
EMPTY_PATH: () => EMPTY_PATH,
|
|
3118
|
+
INVALID: () => INVALID,
|
|
3119
|
+
NEVER: () => NEVER,
|
|
3120
|
+
OK: () => OK,
|
|
3121
|
+
ParseStatus: () => ParseStatus,
|
|
3122
|
+
Schema: () => ZodType,
|
|
3123
|
+
ZodAny: () => ZodAny,
|
|
3124
|
+
ZodArray: () => ZodArray,
|
|
3125
|
+
ZodBigInt: () => ZodBigInt,
|
|
3126
|
+
ZodBoolean: () => ZodBoolean,
|
|
3127
|
+
ZodBranded: () => ZodBranded,
|
|
3128
|
+
ZodCatch: () => ZodCatch,
|
|
3129
|
+
ZodDate: () => ZodDate,
|
|
3130
|
+
ZodDefault: () => ZodDefault,
|
|
3131
|
+
ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
|
|
3132
|
+
ZodEffects: () => ZodEffects,
|
|
3133
|
+
ZodEnum: () => ZodEnum,
|
|
3134
|
+
ZodError: () => ZodError,
|
|
3135
|
+
ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
|
|
3136
|
+
ZodFunction: () => ZodFunction,
|
|
3137
|
+
ZodIntersection: () => ZodIntersection,
|
|
3138
|
+
ZodIssueCode: () => ZodIssueCode,
|
|
3139
|
+
ZodLazy: () => ZodLazy,
|
|
3140
|
+
ZodLiteral: () => ZodLiteral,
|
|
3141
|
+
ZodMap: () => ZodMap,
|
|
3142
|
+
ZodNaN: () => ZodNaN,
|
|
3143
|
+
ZodNativeEnum: () => ZodNativeEnum,
|
|
3144
|
+
ZodNever: () => ZodNever,
|
|
3145
|
+
ZodNull: () => ZodNull,
|
|
3146
|
+
ZodNullable: () => ZodNullable,
|
|
3147
|
+
ZodNumber: () => ZodNumber,
|
|
3148
|
+
ZodObject: () => ZodObject,
|
|
3149
|
+
ZodOptional: () => ZodOptional,
|
|
3150
|
+
ZodParsedType: () => ZodParsedType,
|
|
3151
|
+
ZodPipeline: () => ZodPipeline,
|
|
3152
|
+
ZodPromise: () => ZodPromise,
|
|
3153
|
+
ZodReadonly: () => ZodReadonly,
|
|
3154
|
+
ZodRecord: () => ZodRecord,
|
|
3155
|
+
ZodSchema: () => ZodType,
|
|
3156
|
+
ZodSet: () => ZodSet,
|
|
3157
|
+
ZodString: () => ZodString,
|
|
3158
|
+
ZodSymbol: () => ZodSymbol,
|
|
3159
|
+
ZodTransformer: () => ZodEffects,
|
|
3160
|
+
ZodTuple: () => ZodTuple,
|
|
3161
|
+
ZodType: () => ZodType,
|
|
3162
|
+
ZodUndefined: () => ZodUndefined,
|
|
3163
|
+
ZodUnion: () => ZodUnion,
|
|
3164
|
+
ZodUnknown: () => ZodUnknown,
|
|
3165
|
+
ZodVoid: () => ZodVoid,
|
|
3166
|
+
addIssueToContext: () => addIssueToContext,
|
|
3167
|
+
any: () => anyType,
|
|
3168
|
+
array: () => arrayType,
|
|
3169
|
+
bigint: () => bigIntType,
|
|
3170
|
+
boolean: () => booleanType,
|
|
3171
|
+
coerce: () => coerce,
|
|
3172
|
+
custom: () => custom,
|
|
3173
|
+
date: () => dateType,
|
|
3174
|
+
datetimeRegex: () => datetimeRegex,
|
|
3175
|
+
defaultErrorMap: () => en_default,
|
|
3176
|
+
discriminatedUnion: () => discriminatedUnionType,
|
|
3177
|
+
effect: () => effectsType,
|
|
3178
|
+
enum: () => enumType,
|
|
3179
|
+
function: () => functionType,
|
|
3180
|
+
getErrorMap: () => getErrorMap,
|
|
3181
|
+
getParsedType: () => getParsedType,
|
|
3182
|
+
instanceof: () => instanceOfType,
|
|
3183
|
+
intersection: () => intersectionType,
|
|
3184
|
+
isAborted: () => isAborted,
|
|
3185
|
+
isAsync: () => isAsync,
|
|
3186
|
+
isDirty: () => isDirty,
|
|
3187
|
+
isValid: () => isValid,
|
|
3188
|
+
late: () => late,
|
|
3189
|
+
lazy: () => lazyType,
|
|
3190
|
+
literal: () => literalType,
|
|
3191
|
+
makeIssue: () => makeIssue,
|
|
3192
|
+
map: () => mapType,
|
|
3193
|
+
nan: () => nanType,
|
|
3194
|
+
nativeEnum: () => nativeEnumType,
|
|
3195
|
+
never: () => neverType,
|
|
3196
|
+
null: () => nullType,
|
|
3197
|
+
nullable: () => nullableType,
|
|
3198
|
+
number: () => numberType,
|
|
3199
|
+
object: () => objectType,
|
|
3200
|
+
objectUtil: () => objectUtil,
|
|
3201
|
+
oboolean: () => oboolean,
|
|
3202
|
+
onumber: () => onumber,
|
|
3203
|
+
optional: () => optionalType,
|
|
3204
|
+
ostring: () => ostring,
|
|
3205
|
+
pipeline: () => pipelineType,
|
|
3206
|
+
preprocess: () => preprocessType,
|
|
3207
|
+
promise: () => promiseType,
|
|
3208
|
+
quotelessJson: () => quotelessJson,
|
|
3209
|
+
record: () => recordType,
|
|
3210
|
+
set: () => setType,
|
|
3211
|
+
setErrorMap: () => setErrorMap,
|
|
3212
|
+
strictObject: () => strictObjectType,
|
|
3213
|
+
string: () => stringType,
|
|
3214
|
+
symbol: () => symbolType,
|
|
3215
|
+
transformer: () => effectsType,
|
|
3216
|
+
tuple: () => tupleType,
|
|
3217
|
+
undefined: () => undefinedType,
|
|
3218
|
+
union: () => unionType,
|
|
3219
|
+
unknown: () => unknownType,
|
|
3220
|
+
util: () => util,
|
|
3221
|
+
void: () => voidType
|
|
2861
3222
|
});
|
|
2862
3223
|
|
|
2863
|
-
// node_modules/zod/v3/helpers/util.js
|
|
3224
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
2864
3225
|
var util;
|
|
2865
3226
|
(function(util2) {
|
|
2866
3227
|
util2.assertEqual = (_) => {};
|
|
@@ -2991,7 +3352,7 @@ var getParsedType = (data) => {
|
|
|
2991
3352
|
}
|
|
2992
3353
|
};
|
|
2993
3354
|
|
|
2994
|
-
// node_modules/zod/v3/ZodError.js
|
|
3355
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
|
|
2995
3356
|
var ZodIssueCode = util.arrayToEnum([
|
|
2996
3357
|
"invalid_type",
|
|
2997
3358
|
"invalid_literal",
|
|
@@ -3110,7 +3471,7 @@ ZodError.create = (issues) => {
|
|
|
3110
3471
|
return error;
|
|
3111
3472
|
};
|
|
3112
3473
|
|
|
3113
|
-
// node_modules/zod/v3/locales/en.js
|
|
3474
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
|
|
3114
3475
|
var errorMap = (issue, _ctx) => {
|
|
3115
3476
|
let message;
|
|
3116
3477
|
switch (issue.code) {
|
|
@@ -3213,7 +3574,7 @@ var errorMap = (issue, _ctx) => {
|
|
|
3213
3574
|
};
|
|
3214
3575
|
var en_default = errorMap;
|
|
3215
3576
|
|
|
3216
|
-
// node_modules/zod/v3/errors.js
|
|
3577
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
|
|
3217
3578
|
var overrideErrorMap = en_default;
|
|
3218
3579
|
function setErrorMap(map) {
|
|
3219
3580
|
overrideErrorMap = map;
|
|
@@ -3221,7 +3582,7 @@ function setErrorMap(map) {
|
|
|
3221
3582
|
function getErrorMap() {
|
|
3222
3583
|
return overrideErrorMap;
|
|
3223
3584
|
}
|
|
3224
|
-
// node_modules/zod/v3/helpers/parseUtil.js
|
|
3585
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
3225
3586
|
var makeIssue = (params) => {
|
|
3226
3587
|
const { data, path, errorMaps, issueData } = params;
|
|
3227
3588
|
const fullPath = [...path, ...issueData.path || []];
|
|
@@ -3327,14 +3688,14 @@ var isAborted = (x) => x.status === "aborted";
|
|
|
3327
3688
|
var isDirty = (x) => x.status === "dirty";
|
|
3328
3689
|
var isValid = (x) => x.status === "valid";
|
|
3329
3690
|
var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
|
|
3330
|
-
// node_modules/zod/v3/helpers/errorUtil.js
|
|
3691
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
|
|
3331
3692
|
var errorUtil;
|
|
3332
3693
|
(function(errorUtil2) {
|
|
3333
3694
|
errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
|
|
3334
3695
|
errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
|
|
3335
3696
|
})(errorUtil || (errorUtil = {}));
|
|
3336
3697
|
|
|
3337
|
-
// node_modules/zod/v3/types.js
|
|
3698
|
+
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
|
|
3338
3699
|
class ParseInputLazyPath {
|
|
3339
3700
|
constructor(parent, value, path, key) {
|
|
3340
3701
|
this._cachedPath = [];
|
|
@@ -6960,6 +7321,9 @@ var DEPRECATED_CONFIG_AGENT_SET = new Set(DEPRECATED_CONFIG_AGENTS);
|
|
|
6960
7321
|
|
|
6961
7322
|
// src/lib/cursor-authority.ts
|
|
6962
7323
|
var CURSOR_GLOBAL_AUTHORITY_MAX_BYTES = 256 * 1024;
|
|
7324
|
+
|
|
7325
|
+
// src/lib/session-authority.ts
|
|
7326
|
+
var CLAUDE_LEGACY_AUTHORITY_MAX_BYTES = 256 * 1024;
|
|
6963
7327
|
// src/lib/session-render.ts
|
|
6964
7328
|
var SESSION_RENDER_PROFILE_ENTRYPOINTS = [
|
|
6965
7329
|
".claude/CLAUDE.md",
|
|
@@ -7257,15 +7621,15 @@ function normalizeActivation(value) {
|
|
|
7257
7621
|
if (!INSTRUCTION_ACTIVATION_MODES.includes(record["mode"])) {
|
|
7258
7622
|
throw new Error(`Invalid instruction activation mode: ${String(record["mode"])}`);
|
|
7259
7623
|
}
|
|
7260
|
-
const
|
|
7624
|
+
const mode = record["mode"];
|
|
7261
7625
|
const globs = stringArray(record["globs"], "activation.globs");
|
|
7262
7626
|
const models = stringArray(record["models"], "activation.models");
|
|
7263
|
-
if (
|
|
7627
|
+
if (mode === "glob" && (!globs || globs.length === 0))
|
|
7264
7628
|
throw new Error("Glob activation requires at least one glob.");
|
|
7265
|
-
if (
|
|
7629
|
+
if (mode === "model" && (!models || models.length === 0))
|
|
7266
7630
|
throw new Error("Model activation requires at least one model.");
|
|
7267
7631
|
return {
|
|
7268
|
-
mode
|
|
7632
|
+
mode,
|
|
7269
7633
|
...globs ? { globs } : {},
|
|
7270
7634
|
...models ? { models } : {},
|
|
7271
7635
|
...optionalString(record["description"], "activation.description") ? { description: record["description"] } : {},
|
|
@@ -7417,9 +7781,15 @@ async function createConfig2(client, input) {
|
|
|
7417
7781
|
throw new Error("category is required");
|
|
7418
7782
|
const id = randomUUID();
|
|
7419
7783
|
const slug = await uniqueSlug(client, input.name);
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7784
|
+
const snapshotId = randomUUID();
|
|
7785
|
+
await client.execute(`WITH inserted_config AS (
|
|
7786
|
+
INSERT INTO configs
|
|
7787
|
+
(id, name, slug, kind, category, agent, target_path, outputs, format, content, description, tags, is_template, version, created_at, updated_at)
|
|
7788
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8::jsonb,$9,$10,$11,$12::jsonb,$13,1,now(),now())
|
|
7789
|
+
RETURNING id, content, version
|
|
7790
|
+
)
|
|
7791
|
+
INSERT INTO config_snapshots (id, config_id, content, version, created_at)
|
|
7792
|
+
SELECT $14, id, content, version, now() FROM inserted_config`, [
|
|
7423
7793
|
id,
|
|
7424
7794
|
input.name,
|
|
7425
7795
|
slug,
|
|
@@ -7432,7 +7802,8 @@ async function createConfig2(client, input) {
|
|
|
7432
7802
|
input.content ?? "",
|
|
7433
7803
|
input.description ?? null,
|
|
7434
7804
|
JSON.stringify(input.tags ?? []),
|
|
7435
|
-
input.is_template ?? false
|
|
7805
|
+
input.is_template ?? false,
|
|
7806
|
+
snapshotId
|
|
7436
7807
|
]);
|
|
7437
7808
|
return getConfig2(client, id);
|
|
7438
7809
|
}
|
|
@@ -7471,7 +7842,15 @@ async function updateConfig2(client, idOrSlug, input) {
|
|
|
7471
7842
|
if (input.synced_at !== undefined)
|
|
7472
7843
|
set("synced_at", input.synced_at, "::timestamptz");
|
|
7473
7844
|
params.push(existing.id);
|
|
7474
|
-
|
|
7845
|
+
const configIdParam = params.length;
|
|
7846
|
+
params.push(randomUUID());
|
|
7847
|
+
const snapshotIdParam = params.length;
|
|
7848
|
+
await client.execute(`WITH updated_config AS (
|
|
7849
|
+
UPDATE configs SET ${sets.join(", ")} WHERE id = $${configIdParam}
|
|
7850
|
+
RETURNING id, content, version
|
|
7851
|
+
)
|
|
7852
|
+
INSERT INTO config_snapshots (id, config_id, content, version, created_at)
|
|
7853
|
+
SELECT $${snapshotIdParam}, id, content, version, now() FROM updated_config`, params);
|
|
7475
7854
|
return getConfig2(client, existing.id);
|
|
7476
7855
|
}
|
|
7477
7856
|
async function deleteConfig2(client, idOrSlug) {
|
|
@@ -8655,22 +9034,22 @@ if (process.argv.includes("--version") || process.argv.includes("-V")) {
|
|
|
8655
9034
|
var PORT = Number(process.env["PORT"] ?? process.env["INSTRUCTIONS_PORT"] ?? 3457);
|
|
8656
9035
|
var app = new Hono2;
|
|
8657
9036
|
app.use("*", cors());
|
|
8658
|
-
function
|
|
8659
|
-
return
|
|
9037
|
+
function serviceBackend() {
|
|
9038
|
+
return isPostgresBackendEnabled() ? "postgresql" : "sqlite";
|
|
8660
9039
|
}
|
|
8661
|
-
app.get("/health", (c) => c.json({ status: "ok", version: getPackageVersion(),
|
|
8662
|
-
app.get("/version", (c) => c.json({ status: "ok", version: getPackageVersion(),
|
|
9040
|
+
app.get("/health", (c) => c.json({ status: "ok", version: getPackageVersion(), backend: serviceBackend(), name: "instructions" }));
|
|
9041
|
+
app.get("/version", (c) => c.json({ status: "ok", version: getPackageVersion(), backend: serviceBackend(), name: "instructions" }));
|
|
8663
9042
|
app.get("/ready", async (c) => {
|
|
8664
9043
|
const version = getPackageVersion();
|
|
8665
|
-
const
|
|
8666
|
-
if (
|
|
9044
|
+
const backend2 = serviceBackend();
|
|
9045
|
+
if (backend2 === "postgresql") {
|
|
8667
9046
|
try {
|
|
8668
9047
|
await pingCloud();
|
|
8669
9048
|
} catch (e) {
|
|
8670
|
-
return c.json({ status: "unavailable", version,
|
|
9049
|
+
return c.json({ status: "unavailable", version, backend: backend2, error: e.message }, 503);
|
|
8671
9050
|
}
|
|
8672
9051
|
}
|
|
8673
|
-
return c.json({ status: "ready", version,
|
|
9052
|
+
return c.json({ status: "ready", version, backend: backend2 });
|
|
8674
9053
|
});
|
|
8675
9054
|
app.get("/openapi.json", (c) => c.json(buildV1OpenApiDocument()));
|
|
8676
9055
|
app.get("/v1/openapi.json", (c) => c.json(buildV1OpenApiDocument()));
|
|
@@ -8722,7 +9101,7 @@ if (dashDir) {
|
|
|
8722
9101
|
});
|
|
8723
9102
|
}
|
|
8724
9103
|
var HOST = process.env["HOST"] ?? process.env["INSTRUCTIONS_HOST"] ?? "localhost";
|
|
8725
|
-
console.log(`instructions-serve listening on http://${HOST}:${PORT} (
|
|
9104
|
+
console.log(`instructions-serve listening on http://${HOST}:${PORT} (backend: ${serviceBackend()})${dashDir ? " (dashboard: /)" : " (no dashboard)"}`);
|
|
8726
9105
|
var server_default = { port: PORT, hostname: HOST, fetch: app.fetch };
|
|
8727
9106
|
export {
|
|
8728
9107
|
server_default as default
|