@astrale-os/kernel-server 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/app/create.d.ts +48 -0
  2. package/dist/app/create.d.ts.map +1 -0
  3. package/dist/app/create.js +107 -0
  4. package/dist/app/create.js.map +1 -0
  5. package/dist/app/index.d.ts +4 -0
  6. package/dist/app/index.d.ts.map +1 -0
  7. package/dist/app/index.js +4 -0
  8. package/dist/app/index.js.map +1 -0
  9. package/dist/app/multiplexed.d.ts +53 -0
  10. package/dist/app/multiplexed.d.ts.map +1 -0
  11. package/dist/app/multiplexed.js +63 -0
  12. package/dist/app/multiplexed.js.map +1 -0
  13. package/dist/app/ws-upgrade.d.ts +35 -0
  14. package/dist/app/ws-upgrade.d.ts.map +1 -0
  15. package/dist/app/ws-upgrade.js +93 -0
  16. package/dist/app/ws-upgrade.js.map +1 -0
  17. package/dist/cors.d.ts +21 -0
  18. package/dist/cors.d.ts.map +1 -0
  19. package/dist/cors.js +17 -0
  20. package/dist/cors.js.map +1 -0
  21. package/dist/envelope/batch.d.ts +12 -0
  22. package/dist/envelope/batch.d.ts.map +1 -0
  23. package/dist/envelope/batch.js +90 -0
  24. package/dist/envelope/batch.js.map +1 -0
  25. package/dist/envelope/codec.d.ts +26 -0
  26. package/dist/envelope/codec.d.ts.map +1 -0
  27. package/dist/envelope/codec.js +52 -0
  28. package/dist/envelope/codec.js.map +1 -0
  29. package/dist/envelope/credential.d.ts +20 -0
  30. package/dist/envelope/credential.d.ts.map +1 -0
  31. package/dist/envelope/credential.js +32 -0
  32. package/dist/envelope/credential.js.map +1 -0
  33. package/dist/envelope/http.d.ts +30 -0
  34. package/dist/envelope/http.d.ts.map +1 -0
  35. package/dist/envelope/http.js +128 -0
  36. package/dist/envelope/http.js.map +1 -0
  37. package/dist/envelope/index.d.ts +6 -0
  38. package/dist/envelope/index.d.ts.map +1 -0
  39. package/dist/envelope/index.js +6 -0
  40. package/dist/envelope/index.js.map +1 -0
  41. package/dist/envelope/sse.d.ts +11 -0
  42. package/dist/envelope/sse.d.ts.map +1 -0
  43. package/dist/envelope/sse.js +73 -0
  44. package/dist/envelope/sse.js.map +1 -0
  45. package/dist/envelope/ws.d.ts +32 -0
  46. package/dist/envelope/ws.d.ts.map +1 -0
  47. package/dist/envelope/ws.js +136 -0
  48. package/dist/envelope/ws.js.map +1 -0
  49. package/dist/index.d.ts +11 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +17 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/jwks/discovery.d.ts +40 -0
  54. package/dist/jwks/discovery.d.ts.map +1 -0
  55. package/dist/jwks/discovery.js +113 -0
  56. package/dist/jwks/discovery.js.map +1 -0
  57. package/dist/jwks/index.d.ts +3 -0
  58. package/dist/jwks/index.d.ts.map +1 -0
  59. package/dist/jwks/index.js +3 -0
  60. package/dist/jwks/index.js.map +1 -0
  61. package/dist/jwks/issuers.d.ts +47 -0
  62. package/dist/jwks/issuers.d.ts.map +1 -0
  63. package/dist/jwks/issuers.js +76 -0
  64. package/dist/jwks/issuers.js.map +1 -0
  65. package/dist/jwks/keys.d.ts +44 -0
  66. package/dist/jwks/keys.d.ts.map +1 -0
  67. package/dist/jwks/keys.js +56 -0
  68. package/dist/jwks/keys.js.map +1 -0
  69. package/dist/plan/host-params.d.ts +13 -0
  70. package/dist/plan/host-params.d.ts.map +1 -0
  71. package/dist/plan/host-params.js +23 -0
  72. package/dist/plan/host-params.js.map +1 -0
  73. package/dist/plan/host.d.ts +24 -0
  74. package/dist/plan/host.d.ts.map +1 -0
  75. package/dist/plan/host.js +24 -0
  76. package/dist/plan/host.js.map +1 -0
  77. package/dist/plan/index.d.ts +4 -0
  78. package/dist/plan/index.d.ts.map +1 -0
  79. package/dist/plan/index.js +4 -0
  80. package/dist/plan/index.js.map +1 -0
  81. package/dist/plan/walk.d.ts +51 -0
  82. package/dist/plan/walk.d.ts.map +1 -0
  83. package/dist/plan/walk.js +110 -0
  84. package/dist/plan/walk.js.map +1 -0
  85. package/dist/render/binary.d.ts +19 -0
  86. package/dist/render/binary.d.ts.map +1 -0
  87. package/dist/render/binary.js +33 -0
  88. package/dist/render/binary.js.map +1 -0
  89. package/dist/render/body.d.ts +10 -0
  90. package/dist/render/body.d.ts.map +1 -0
  91. package/dist/render/body.js +17 -0
  92. package/dist/render/body.js.map +1 -0
  93. package/dist/render/index.d.ts +3 -0
  94. package/dist/render/index.d.ts.map +1 -0
  95. package/dist/render/index.js +3 -0
  96. package/dist/render/index.js.map +1 -0
  97. package/dist/routed/credential.d.ts +10 -0
  98. package/dist/routed/credential.d.ts.map +1 -0
  99. package/dist/routed/credential.js +55 -0
  100. package/dist/routed/credential.js.map +1 -0
  101. package/dist/routed/handler.d.ts +36 -0
  102. package/dist/routed/handler.d.ts.map +1 -0
  103. package/dist/routed/handler.js +119 -0
  104. package/dist/routed/handler.js.map +1 -0
  105. package/dist/routed/index.d.ts +5 -0
  106. package/dist/routed/index.d.ts.map +1 -0
  107. package/dist/routed/index.js +5 -0
  108. package/dist/routed/index.js.map +1 -0
  109. package/dist/routed/params.d.ts +40 -0
  110. package/dist/routed/params.d.ts.map +1 -0
  111. package/dist/routed/params.js +146 -0
  112. package/dist/routed/params.js.map +1 -0
  113. package/dist/routed/stream.d.ts +21 -0
  114. package/dist/routed/stream.d.ts.map +1 -0
  115. package/dist/routed/stream.js +69 -0
  116. package/dist/routed/stream.js.map +1 -0
  117. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACpF,OAAO,EACL,0BAA0B,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EACL,UAAU,EACV,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,QAAQ,CAAA;AAIf,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAA;AAI1D,OAAO,EAAE,sBAAsB,EAAE,KAAK,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAItE,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAItE,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,EAC3B,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,GAClC,MAAM,QAAQ,CAAA;AAIf,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAChE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ // ─── App entry points ─────────────────────────────────────────────────────────
2
+ export { createKernelApp } from './app/create';
3
+ export { createMultiplexedKernelApp, } from './app/multiplexed';
4
+ // ─── Plan ────────────────────────────────────────────────────────────────────
5
+ export { walkDomain, } from './plan';
6
+ // ─── Cross-cutting ───────────────────────────────────────────────────────────
7
+ export { buildCorsHeaders } from './cors';
8
+ // ─── Kernel envelope dispatcher ──────────────────────────────────────────────
9
+ export { createKernelDispatcher } from './envelope/http';
10
+ export { KernelWsConnection } from './envelope/ws';
11
+ // ─── Routed HTTP handler (per-route) ─────────────────────────────────────────
12
+ export { createRouteHandler } from './routed';
13
+ // ─── JWKS (OIDC Discovery + JSON Web Key Set) ───────────────────────────────
14
+ export { mountJwks, mountInstanceJwks, mountIssuerRegistry, mountInstanceIssuerRegistry, } from './jwks';
15
+ // ─── Dispatch (for custom integrations) ──────────────────────────────────────
16
+ export { dispatch, classifyError } from '@astrale-os/kernel-api';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,OAAO,EAAE,eAAe,EAAwC,MAAM,cAAc,CAAA;AACpF,OAAO,EACL,0BAA0B,GAG3B,MAAM,mBAAmB,CAAA;AAE1B,gFAAgF;AAEhF,OAAO,EACL,UAAU,GAKX,MAAM,QAAQ,CAAA;AAEf,gFAAgF;AAEhF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,QAAQ,CAAA;AAE1D,gFAAgF;AAEhF,OAAO,EAAE,sBAAsB,EAAgC,MAAM,iBAAiB,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAA;AAEtE,gFAAgF;AAEhF,OAAO,EAAE,kBAAkB,EAA2B,MAAM,UAAU,CAAA;AAEtE,+EAA+E;AAE/E,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,mBAAmB,EACnB,2BAA2B,GAO5B,MAAM,QAAQ,CAAA;AAEf,gFAAgF;AAEhF,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * OIDC discovery-document construction — the `issuer`/`jwks_uri` pair and the
3
+ * reachable-URL derivation behind it. Shared by `mountJwks`,
4
+ * `mountInstanceJwks`, and the issuer-registry mounts.
5
+ *
6
+ * Identity vs reachability — the two published fields are intentionally
7
+ * asymmetric, and that asymmetry is load-bearing:
8
+ * • `issuer` is the IDENTITY claim, published VERBATIM. OIDC Discovery /
9
+ * RFC 8414 require it to equal the issuer used to build the discovery URL
10
+ * and the `iss` claim the kernel signs into tokens. Normalizing it would
11
+ * break token validation whenever the configured issuer is non-canonical
12
+ * (a bare slug, odd casing, …) — so it is never rewritten here.
13
+ * • `jwks_uri` is a REACHABILITY concern: it must be a fetchable absolute URL.
14
+ * It is derived from the canonical issuer URL when that is usable, else from
15
+ * the request's externally-reachable origin (proxy headers). A bare-slug or
16
+ * port-0 issuer is a valid identity but an unfetchable URL — hence the
17
+ * divergence. (Regression coverage: M-19, host `jwks-keys.test.ts`.)
18
+ *
19
+ * Edge-topology contract — KEEP IN SYNC with kernel/host/network/Caddyfile:
20
+ * In the Caddy-only edge the host kernel is mounted publicly under
21
+ * `/kernel/{slug}` (the issuer carries that path) but served internally at the
22
+ * stripped path (`/` for the host, `/{id}` for children). `jwks_uri` is built
23
+ * from the ISSUER's path, never the request path, so the edge only strips the
24
+ * prefix on the way IN — no response-body rewrite. If a future edge stops
25
+ * stripping `/kernel/{slug}`, or a kernel is mounted at a different public
26
+ * path, the issuer's path and that edge rule must move together.
27
+ */
28
+ export interface DiscoveryDoc {
29
+ issuer: string;
30
+ jwks_uri: string;
31
+ subject_types_supported: string[];
32
+ id_token_signing_alg_values_supported: string[];
33
+ }
34
+ /**
35
+ * Build the OIDC discovery document served at `/.well-known/openid-configuration`.
36
+ * `issuer` is echoed verbatim (identity); `jwks_uri` is derived to be reachable.
37
+ * See the file header for why the two diverge.
38
+ */
39
+ export declare function discoveryDoc(req: Request, issuer: string, signingAlgorithm: string): DiscoveryDoc;
40
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../jwks/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,uBAAuB,EAAE,MAAM,EAAE,CAAA;IACjC,qCAAqC,EAAE,MAAM,EAAE,CAAA;CAChD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,YAAY,CAOjG"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * OIDC discovery-document construction — the `issuer`/`jwks_uri` pair and the
3
+ * reachable-URL derivation behind it. Shared by `mountJwks`,
4
+ * `mountInstanceJwks`, and the issuer-registry mounts.
5
+ *
6
+ * Identity vs reachability — the two published fields are intentionally
7
+ * asymmetric, and that asymmetry is load-bearing:
8
+ * • `issuer` is the IDENTITY claim, published VERBATIM. OIDC Discovery /
9
+ * RFC 8414 require it to equal the issuer used to build the discovery URL
10
+ * and the `iss` claim the kernel signs into tokens. Normalizing it would
11
+ * break token validation whenever the configured issuer is non-canonical
12
+ * (a bare slug, odd casing, …) — so it is never rewritten here.
13
+ * • `jwks_uri` is a REACHABILITY concern: it must be a fetchable absolute URL.
14
+ * It is derived from the canonical issuer URL when that is usable, else from
15
+ * the request's externally-reachable origin (proxy headers). A bare-slug or
16
+ * port-0 issuer is a valid identity but an unfetchable URL — hence the
17
+ * divergence. (Regression coverage: M-19, host `jwks-keys.test.ts`.)
18
+ *
19
+ * Edge-topology contract — KEEP IN SYNC with kernel/host/network/Caddyfile:
20
+ * In the Caddy-only edge the host kernel is mounted publicly under
21
+ * `/kernel/{slug}` (the issuer carries that path) but served internally at the
22
+ * stripped path (`/` for the host, `/{id}` for children). `jwks_uri` is built
23
+ * from the ISSUER's path, never the request path, so the edge only strips the
24
+ * prefix on the way IN — no response-body rewrite. If a future edge stops
25
+ * stripping `/kernel/{slug}`, or a kernel is mounted at a different public
26
+ * path, the issuer's path and that edge rule must move together.
27
+ */
28
+ import { normalizeIssuerId } from '@astrale-os/kernel-core';
29
+ /**
30
+ * Build the OIDC discovery document served at `/.well-known/openid-configuration`.
31
+ * `issuer` is echoed verbatim (identity); `jwks_uri` is derived to be reachable.
32
+ * See the file header for why the two diverge.
33
+ */
34
+ export function discoveryDoc(req, issuer, signingAlgorithm) {
35
+ return {
36
+ issuer,
37
+ jwks_uri: jwksUriFor(req, issuer),
38
+ subject_types_supported: ['public'],
39
+ id_token_signing_alg_values_supported: [signingAlgorithm],
40
+ };
41
+ }
42
+ // Public URL of a discovery document's sibling `jwks.json`. Three cases, in
43
+ // priority order:
44
+ // 1. `issuer` is a usable http(s) URL WITH a path → that path is this
45
+ // kernel/instance's full public mount (e.g. `…/kernel/host`). jwks lives
46
+ // directly under it (`{issuer}/.well-known/jwks.json`) — the OIDC invariant
47
+ // that needs no proxy body-rewrite.
48
+ // 2. `issuer` is a usable http(s) URL but origin-only → the public mount path
49
+ // comes from the request path (kernel reached at its canonical origin).
50
+ // 3. `issuer` is a bare slug / non-URL / port-0 fixture → fall back to the
51
+ // request's externally-reachable origin (proxy headers) plus its own path.
52
+ function jwksUriFor(req, issuer) {
53
+ const requestJwksPath = new URL(req.url).pathname.replace(/\/openid-configuration$/, '/jwks.json');
54
+ const canonical = canonicalIssuerUrl(issuer);
55
+ if (!canonical) {
56
+ return `${externalOriginFromRequest(req)}${requestJwksPath}`;
57
+ }
58
+ if (canonical.pathname && canonical.pathname !== '/') {
59
+ return `${canonical.origin}${canonical.pathname.replace(/\/+$/, '')}/.well-known/jwks.json`;
60
+ }
61
+ return `${canonical.origin}${requestJwksPath}`;
62
+ }
63
+ // Parse `issuer` into its canonical http(s) URL, or null when it is not a
64
+ // verifier-reachable origin: a bare slug (no scheme), a non-http(s) scheme, or
65
+ // the `:0` placeholder port that test/dev fixtures use as a non-canonical stand-in.
66
+ function canonicalIssuerUrl(issuer) {
67
+ try {
68
+ const u = new URL(normalizeIssuerId(issuer));
69
+ if (!u.host)
70
+ return null;
71
+ if (u.protocol !== 'http:' && u.protocol !== 'https:')
72
+ return null;
73
+ if (u.port === '0')
74
+ return null;
75
+ return u;
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ // Externally-reachable origin of the request. Reverse proxies commonly
82
+ // terminate TLS and rewrite Host to an internal hostname; prefer the forwarding
83
+ // headers (X-Forwarded-* then RFC 7239 Forwarded) before the request URL, so
84
+ // discovery never publishes an unreachable jwks_uri.
85
+ function externalOriginFromRequest(req) {
86
+ const xfHost = firstHeaderValue(req.headers.get('x-forwarded-host'));
87
+ if (xfHost) {
88
+ const proto = (firstHeaderValue(req.headers.get('x-forwarded-proto')) ?? 'https').toLowerCase();
89
+ return `${proto}://${xfHost}`;
90
+ }
91
+ const fwd = firstHeaderValue(req.headers.get('forwarded'));
92
+ if (fwd) {
93
+ const map = {};
94
+ for (const part of fwd.split(';')) {
95
+ const [k, v] = part.split('=');
96
+ if (k && v)
97
+ map[k.trim().toLowerCase()] = stripQuotes(v.trim());
98
+ }
99
+ if (map.host) {
100
+ const proto = (map.proto ?? 'https').toLowerCase();
101
+ return `${proto}://${map.host}`;
102
+ }
103
+ }
104
+ return new URL(req.url).origin;
105
+ }
106
+ function firstHeaderValue(value) {
107
+ const first = value?.split(',')[0]?.trim();
108
+ return first ? stripQuotes(first) : null;
109
+ }
110
+ function stripQuotes(value) {
111
+ return value.replace(/^"|"$/g, '');
112
+ }
113
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../jwks/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { mountJwks, mountInstanceJwks, type JwksKeys, type MultiplexedJwks, type JwksConfig, type InstanceJwksConfig, } from './keys';
2
+ export { mountIssuerRegistry, mountInstanceIssuerRegistry, type IssuerRegistryConfig, type InstanceIssuerRegistryConfig, } from './issuers';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../jwks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,kBAAkB,GACxB,MAAM,QAAQ,CAAA;AAEf,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,GAClC,MAAM,WAAW,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { mountJwks, mountInstanceJwks, } from './keys';
2
+ export { mountIssuerRegistry, mountInstanceIssuerRegistry, } from './issuers';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../jwks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,iBAAiB,GAKlB,MAAM,QAAQ,CAAA;AAEf,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAG5B,MAAM,WAAW,CAAA"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Issuer Registry — kernel-specific convention for hosting external issuers' keys.
3
+ *
4
+ * The kernel allows external identities to publish their public keys via
5
+ * `Authentication.publishIssuer()`. Those issuers get stable URLs of the form
6
+ * `{kernel}/iss/{issId}`, and their JWKS is served at
7
+ * `{kernel}/iss/{issId}/.well-known/jwks.json`.
8
+ *
9
+ * This is NOT standard OIDC — it's a kernel-specific trust model. Only kernels
10
+ * with an issuer store should mount these routes. Generic services that just
11
+ * sign their own JWTs don't need this.
12
+ */
13
+ import type { Hono } from 'hono';
14
+ import { type CorsConfig } from '../cors';
15
+ export type IssuerRegistryConfig = {
16
+ /** Base issuer URL — registered issuer URLs are constructed as `${issuer}/iss/{issId}`. */
17
+ issuer: string;
18
+ /** Load a registered external issuer's keys. Empty array if unknown. */
19
+ loadKeys: (issuerId: string) => Promise<Record<string, unknown>[]>;
20
+ /** Signing algorithm (used in openid-configuration). Defaults to 'ES256'. */
21
+ signingAlgorithm?: string;
22
+ cors?: CorsConfig;
23
+ };
24
+ /**
25
+ * Mount issuer registry endpoints — kernel-specific convention for hosting
26
+ * externally-registered issuers' keys.
27
+ *
28
+ * - GET /iss/:issId/.well-known/openid-configuration → external issuer discovery
29
+ * - GET /iss/:issId/.well-known/jwks.json → external issuer keys
30
+ */
31
+ export declare function mountIssuerRegistry(app: Hono, config: IssuerRegistryConfig): void;
32
+ export type InstanceIssuerRegistryConfig = {
33
+ /** Resolve the instance's base issuer URL. Return null if unknown. */
34
+ resolveIssuer: (instanceId: string) => string | null;
35
+ /** Load a registered external issuer's keys for an instance. */
36
+ loadKeys: (instanceId: string, issuerId: string) => Promise<Record<string, unknown>[]>;
37
+ signingAlgorithm?: string;
38
+ cors?: CorsConfig;
39
+ };
40
+ /**
41
+ * Mount per-instance issuer registry endpoints (multiplexed kernel-specific).
42
+ *
43
+ * - GET /:id/iss/:issId/.well-known/openid-configuration
44
+ * - GET /:id/iss/:issId/.well-known/jwks.json
45
+ */
46
+ export declare function mountInstanceIssuerRegistry(app: Hono, instancePrefix: string, config: InstanceIssuerRegistryConfig): void;
47
+ //# sourceMappingURL=issuers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuers.d.ts","sourceRoot":"","sources":["../../jwks/issuers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAK3D,MAAM,MAAM,oBAAoB,GAAG;IACjC,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;IAClE,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAoBjF;AAID,MAAM,MAAM,4BAA4B,GAAG;IACzC,sEAAsE;IACtE,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IACpD,gEAAgE;IAChE,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;IACtF,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,IAAI,EACT,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,4BAA4B,GACnC,IAAI,CAyBN"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Issuer Registry — kernel-specific convention for hosting external issuers' keys.
3
+ *
4
+ * The kernel allows external identities to publish their public keys via
5
+ * `Authentication.publishIssuer()`. Those issuers get stable URLs of the form
6
+ * `{kernel}/iss/{issId}`, and their JWKS is served at
7
+ * `{kernel}/iss/{issId}/.well-known/jwks.json`.
8
+ *
9
+ * This is NOT standard OIDC — it's a kernel-specific trust model. Only kernels
10
+ * with an issuer store should mount these routes. Generic services that just
11
+ * sign their own JWTs don't need this.
12
+ */
13
+ import { buildCorsHeaders } from '../cors';
14
+ import { discoveryDoc } from './discovery';
15
+ /**
16
+ * Mount issuer registry endpoints — kernel-specific convention for hosting
17
+ * externally-registered issuers' keys.
18
+ *
19
+ * - GET /iss/:issId/.well-known/openid-configuration → external issuer discovery
20
+ * - GET /iss/:issId/.well-known/jwks.json → external issuer keys
21
+ */
22
+ export function mountIssuerRegistry(app, config) {
23
+ const corsHeaders = buildCorsHeaders(config.cors ?? { origin: '*' });
24
+ const headers = { 'cache-control': 'no-cache', ...corsHeaders };
25
+ const alg = config.signingAlgorithm ?? 'ES256';
26
+ app.get('/iss/:issId/.well-known/openid-configuration', (c) => {
27
+ const issId = c.req.param('issId');
28
+ const issuerUrl = `${config.issuer}/iss/${issId}`;
29
+ return c.json(discoveryDoc(c.req.raw, issuerUrl, alg), 200, headers);
30
+ });
31
+ app.get('/iss/:issId/.well-known/jwks.json', async (c) => {
32
+ const issId = c.req.param('issId');
33
+ const issuerUrl = `${config.issuer}/iss/${issId}`;
34
+ const keys = await config.loadKeys(issuerUrl);
35
+ if (keys.length === 0) {
36
+ return c.json({ error: 'Issuer not found' }, 404, headers);
37
+ }
38
+ return c.json({ keys }, 200, headers);
39
+ });
40
+ }
41
+ /**
42
+ * Mount per-instance issuer registry endpoints (multiplexed kernel-specific).
43
+ *
44
+ * - GET /:id/iss/:issId/.well-known/openid-configuration
45
+ * - GET /:id/iss/:issId/.well-known/jwks.json
46
+ */
47
+ export function mountInstanceIssuerRegistry(app, instancePrefix, config) {
48
+ const corsHeaders = buildCorsHeaders(config.cors ?? { origin: '*' });
49
+ const headers = { 'cache-control': 'no-cache', ...corsHeaders };
50
+ const alg = config.signingAlgorithm ?? 'ES256';
51
+ app.get(`${instancePrefix}/iss/:issId/.well-known/openid-configuration`, (c) => {
52
+ const id = c.req.param('id');
53
+ const issId = c.req.param('issId');
54
+ if (!id || !issId)
55
+ return c.json({ error: 'Instance not found' }, 404, headers);
56
+ const issuer = config.resolveIssuer(id);
57
+ if (!issuer)
58
+ return c.json({ error: 'Instance not found' }, 404, headers);
59
+ const issuerUrl = `${issuer}/iss/${issId}`;
60
+ return c.json(discoveryDoc(c.req.raw, issuerUrl, alg), 200, headers);
61
+ });
62
+ app.get(`${instancePrefix}/iss/:issId/.well-known/jwks.json`, async (c) => {
63
+ const id = c.req.param('id');
64
+ const issId = c.req.param('issId');
65
+ if (!id || !issId)
66
+ return c.json({ error: 'Instance not found' }, 404, headers);
67
+ const issuer = config.resolveIssuer(id);
68
+ if (!issuer)
69
+ return c.json({ error: 'Instance not found' }, 404, headers);
70
+ const keys = await config.loadKeys(id, `${issuer}/iss/${issId}`);
71
+ if (keys.length === 0)
72
+ return c.json({ error: 'Issuer not found' }, 404, headers);
73
+ return c.json({ keys }, 200, headers);
74
+ });
75
+ }
76
+ //# sourceMappingURL=issuers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issuers.js","sourceRoot":"","sources":["../../jwks/issuers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAE,gBAAgB,EAAmB,MAAM,SAAS,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAc1C;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAS,EAAE,MAA4B;IACzE,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACpE,MAAM,OAAO,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,WAAW,EAAE,CAAA;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,IAAI,OAAO,CAAA;IAE9C,GAAG,CAAC,GAAG,CAAC,8CAA8C,EAAE,CAAC,CAAC,EAAE,EAAE;QAC5D,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClC,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,MAAM,QAAQ,KAAK,EAAE,CAAA;QACjD,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACtE,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACvD,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClC,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,MAAM,QAAQ,KAAK,EAAE,CAAA;QACjD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAC5D,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;AACJ,CAAC;AAaD;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CACzC,GAAS,EACT,cAAsB,EACtB,MAAoC;IAEpC,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACpE,MAAM,OAAO,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,GAAG,WAAW,EAAE,CAAA;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,gBAAgB,IAAI,OAAO,CAAA;IAE9C,GAAG,CAAC,GAAG,CAAC,GAAG,cAAc,8CAA8C,EAAE,CAAC,CAAC,EAAE,EAAE;QAC7E,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAC/E,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACvC,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QACzE,MAAM,SAAS,GAAG,GAAG,MAAM,QAAQ,KAAK,EAAE,CAAA;QAC1C,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACtE,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,GAAG,CAAC,GAAG,cAAc,mCAAmC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACxE,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QAC/E,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACvC,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QACzE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,MAAM,QAAQ,KAAK,EAAE,CAAC,CAAA;QAChE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;QACjF,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * JWKS — generic OpenID Connect Discovery + JSON Web Key Set exposure.
3
+ *
4
+ * Mounts the standard OIDC discovery and JWKS endpoints for the server's
5
+ * own signing keys. Used by every server that signs JWTs.
6
+ */
7
+ import type { Hono } from 'hono';
8
+ import { type CorsConfig } from '../cors';
9
+ export type JwksKeys = {
10
+ /** The server's own issuer URL. */
11
+ issuer: string;
12
+ /** Return the server's own public signing key(s). */
13
+ loadOwnKeys: () => Promise<Record<string, unknown>[]>;
14
+ };
15
+ export type MultiplexedJwks = {
16
+ /** Resolve the issuer URL for an instance. Return null if unknown. */
17
+ resolveIssuer: (instanceId: string) => string | null;
18
+ /** Load the instance's own public keys. Empty array if unknown. */
19
+ loadOwnKeys: (instanceId: string) => Promise<Record<string, unknown>[]>;
20
+ };
21
+ export type JwksConfig = JwksKeys & {
22
+ /** Signing algorithm (used in openid-configuration). Defaults to 'ES256'. */
23
+ signingAlgorithm?: string;
24
+ cors?: CorsConfig;
25
+ };
26
+ /**
27
+ * Mount OpenID Connect Discovery and JWKS endpoints for the server's own keys.
28
+ *
29
+ * - GET /.well-known/openid-configuration → OIDC discovery document
30
+ * - GET /.well-known/jwks.json → server's own public keys
31
+ */
32
+ export declare function mountJwks(app: Hono, config: JwksConfig): void;
33
+ export type InstanceJwksConfig = MultiplexedJwks & {
34
+ signingAlgorithm?: string;
35
+ cors?: CorsConfig;
36
+ };
37
+ /**
38
+ * Mount per-instance OpenID Connect Discovery and JWKS endpoints (own keys).
39
+ *
40
+ * Routes are prefixed with the instance path (e.g. `/:id`).
41
+ * The instance ID is extracted from the Hono `:id` param.
42
+ */
43
+ export declare function mountInstanceJwks(app: Hono, instancePrefix: string, config: InstanceJwksConfig): void;
44
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../jwks/keys.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAK3D,MAAM,MAAM,QAAQ,GAAG;IACrB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,qDAAqD;IACrD,WAAW,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;CACtD,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,sEAAsE;IACtE,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAA;IACpD,mEAAmE;IACnE,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;CACxE,CAAA;AAID,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG;IAClC,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAa7D;AAID,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,IAAI,EACT,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,kBAAkB,GACzB,IAAI,CAoBN"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * JWKS — generic OpenID Connect Discovery + JSON Web Key Set exposure.
3
+ *
4
+ * Mounts the standard OIDC discovery and JWKS endpoints for the server's
5
+ * own signing keys. Used by every server that signs JWTs.
6
+ */
7
+ import { buildCorsHeaders } from '../cors';
8
+ import { discoveryDoc } from './discovery';
9
+ /**
10
+ * Mount OpenID Connect Discovery and JWKS endpoints for the server's own keys.
11
+ *
12
+ * - GET /.well-known/openid-configuration → OIDC discovery document
13
+ * - GET /.well-known/jwks.json → server's own public keys
14
+ */
15
+ export function mountJwks(app, config) {
16
+ const corsHeaders = buildCorsHeaders(config.cors ?? { origin: '*' });
17
+ const headers = { 'cache-control': 'no-cache', ...corsHeaders };
18
+ const alg = config.signingAlgorithm ?? 'ES256';
19
+ app.get('/.well-known/openid-configuration', (c) => {
20
+ return c.json(discoveryDoc(c.req.raw, config.issuer, alg), 200, headers);
21
+ });
22
+ app.get('/.well-known/jwks.json', async (c) => {
23
+ const keys = await config.loadOwnKeys();
24
+ return c.json({ keys }, 200, headers);
25
+ });
26
+ }
27
+ /**
28
+ * Mount per-instance OpenID Connect Discovery and JWKS endpoints (own keys).
29
+ *
30
+ * Routes are prefixed with the instance path (e.g. `/:id`).
31
+ * The instance ID is extracted from the Hono `:id` param.
32
+ */
33
+ export function mountInstanceJwks(app, instancePrefix, config) {
34
+ const corsHeaders = buildCorsHeaders(config.cors ?? { origin: '*' });
35
+ const headers = { 'cache-control': 'no-cache', ...corsHeaders };
36
+ const alg = config.signingAlgorithm ?? 'ES256';
37
+ app.get(`${instancePrefix}/.well-known/openid-configuration`, (c) => {
38
+ const id = c.req.param('id');
39
+ if (!id)
40
+ return c.json({ error: 'Instance not found' }, 404, headers);
41
+ const issuer = config.resolveIssuer(id);
42
+ if (!issuer)
43
+ return c.json({ error: 'Instance not found' }, 404, headers);
44
+ return c.json(discoveryDoc(c.req.raw, issuer, alg), 200, headers);
45
+ });
46
+ app.get(`${instancePrefix}/.well-known/jwks.json`, async (c) => {
47
+ const id = c.req.param('id');
48
+ if (!id)
49
+ return c.json({ error: 'Instance not found' }, 404, headers);
50
+ const keys = await config.loadOwnKeys(id);
51
+ if (keys.length === 0)
52
+ return c.json({ error: 'Instance not found' }, 404, headers);
53
+ return c.json({ keys }, 200, headers);
54
+ });
55
+ }
56
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../jwks/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Extract host placeholder values from an incoming request's Host header.
3
+ *
4
+ * Used by request-time middleware to merge tenant identifiers from the host
5
+ * into the dispatched params (at lowest priority).
6
+ *
7
+ * Returns:
8
+ * - `null` when the matcher exists but the host doesn't match (caller 404s)
9
+ * - `{}` when there are no placeholders (single-tenant server)
10
+ * - the captured groups otherwise
11
+ */
12
+ export declare function extractHostParams(matcher: RegExp | null, request: Request): Record<string, string> | null;
13
+ //# sourceMappingURL=host-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-params.d.ts","sourceRoot":"","sources":["../../plan/host-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAO/B"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Extract host placeholder values from an incoming request's Host header.
3
+ *
4
+ * Used by request-time middleware to merge tenant identifiers from the host
5
+ * into the dispatched params (at lowest priority).
6
+ *
7
+ * Returns:
8
+ * - `null` when the matcher exists but the host doesn't match (caller 404s)
9
+ * - `{}` when there are no placeholders (single-tenant server)
10
+ * - the captured groups otherwise
11
+ */
12
+ export function extractHostParams(matcher, request) {
13
+ if (!matcher)
14
+ return {};
15
+ const host = request.headers.get('host');
16
+ if (!host)
17
+ return null;
18
+ const result = matcher.exec(host);
19
+ if (!result)
20
+ return null;
21
+ return { ...result.groups };
22
+ }
23
+ //# sourceMappingURL=host-params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-params.js","sourceRoot":"","sources":["../../plan/host-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,UAAU,iBAAiB,CAC/B,OAAsB,EACtB,OAAgB;IAEhB,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IACvB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACtB,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Server host URL and its parsed form.
3
+ *
4
+ * The server host URL is the canonical address of THIS kernel server. It may
5
+ * contain host placeholders (`{tenant}.example.com`) for multi-tenant servers.
6
+ * `parseServerHost` extracts the pieces needed by the walker and the
7
+ * request-time host param extractor.
8
+ */
9
+ export type ServerHost = {
10
+ /** Full server URL — may contain host placeholders for multi-tenant servers. */
11
+ url: string;
12
+ };
13
+ export type ParsedServerHost = {
14
+ /** Canonical host pattern (with `{name}` placeholders) used for anchoring checks. */
15
+ hostPattern: string;
16
+ /** Base path stripped of any trailing slash. */
17
+ basePath: string;
18
+ /** Compiled Host header matcher, or `null` when there are no placeholders. */
19
+ hostMatcher: RegExp | null;
20
+ /** Host placeholder names in source order. */
21
+ hostPlaceholders: string[];
22
+ };
23
+ export declare function parseServerHost(host: ServerHost): ParsedServerHost;
24
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../plan/host.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,UAAU,GAAG;IACvB,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAA;IACnB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAChB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC3B,CAAA;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,CAQlE"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Server host URL and its parsed form.
3
+ *
4
+ * The server host URL is the canonical address of THIS kernel server. It may
5
+ * contain host placeholders (`{tenant}.example.com`) for multi-tenant servers.
6
+ * `parseServerHost` extracts the pieces needed by the walker and the
7
+ * request-time host param extractor.
8
+ */
9
+ import { compileHostMatcher, parseUrlTemplate } from '@astrale-os/kernel-api/routed';
10
+ export function parseServerHost(host) {
11
+ const parsed = parseUrlTemplate(host.url);
12
+ return {
13
+ hostPattern: parsed.hostPattern,
14
+ basePath: stripTrailingSlash(parsed.basePath),
15
+ hostMatcher: parsed.hostPlaceholders.length > 0 ? compileHostMatcher(parsed.hostPattern) : null,
16
+ hostPlaceholders: parsed.hostPlaceholders,
17
+ };
18
+ }
19
+ function stripTrailingSlash(p) {
20
+ if (p.length > 1 && p.endsWith('/'))
21
+ return p.slice(0, -1);
22
+ return p;
23
+ }
24
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../plan/host.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAkBpF,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC9C,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzC,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC7C,WAAW,EAAE,MAAM,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI;QAC/F,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAA;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAS;IACnC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC1D,OAAO,CAAC,CAAA;AACV,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { walkDomain, type MountedFunction, type MountedRoute, type MountPlan } from './walk';
2
+ export { parseServerHost, type ServerHost, type ParsedServerHost } from './host';
3
+ export { extractHostParams } from './host-params';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../plan/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC5F,OAAO,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { walkDomain } from './walk';
2
+ export { parseServerHost } from './host';
3
+ export { extractHostParams } from './host-params';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../plan/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2D,MAAM,QAAQ,CAAA;AAC5F,OAAO,EAAE,eAAe,EAA0C,MAAM,QAAQ,CAAA;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA"}