@astrale-os/kernel-server 0.5.0-beta.2 → 0.5.0-beta.20
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/dist/capture.d.ts +0 -1
- package/dist/capture.js +0 -1
- package/dist/cors/cors.d.ts +0 -1
- package/dist/cors/cors.js +0 -1
- package/dist/cors/index.d.ts +0 -1
- package/dist/cors/index.js +0 -1
- package/dist/cors/types.d.ts +0 -1
- package/dist/cors/types.js +0 -1
- package/dist/errors/availability.d.ts +0 -1
- package/dist/errors/availability.js +0 -1
- package/dist/errors/classify.d.ts +2 -3
- package/dist/errors/classify.js +4 -279
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/errors/request-body.d.ts +0 -1
- package/dist/errors/request-body.js +0 -1
- package/dist/errors/response-body.d.ts +0 -1
- package/dist/errors/response-body.js +0 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/invocation/context.d.ts +2 -3
- package/dist/invocation/context.js +2 -3
- package/dist/invocation/identity.d.ts +9 -0
- package/dist/invocation/identity.js +11 -0
- package/dist/invocation/index.d.ts +2 -2
- package/dist/invocation/index.js +1 -1
- package/dist/invocation/publication-route.d.ts +5 -4
- package/dist/invocation/publication-route.js +8 -7
- package/dist/invocation/types.d.ts +33 -9
- package/dist/invocation/types.js +0 -1
- package/dist/issuer/exchange.d.ts +2 -3
- package/dist/issuer/exchange.js +13 -12
- package/dist/issuer/index.d.ts +0 -1
- package/dist/issuer/index.js +0 -1
- package/dist/issuer/routes.d.ts +0 -1
- package/dist/issuer/routes.js +14 -12
- package/dist/issuer/types.d.ts +2 -2
- package/dist/issuer/types.js +0 -1
- package/dist/lifecycle/active.d.ts +2 -1
- package/dist/lifecycle/active.js +5 -3
- package/dist/lifecycle/index.d.ts +0 -1
- package/dist/lifecycle/index.js +0 -1
- package/dist/publication/delivery/handler.d.ts +0 -1
- package/dist/publication/delivery/handler.js +2 -2
- package/dist/publication/delivery/index.d.ts +0 -1
- package/dist/publication/delivery/index.js +0 -1
- package/dist/publication/delivery/types.d.ts +1 -2
- package/dist/publication/delivery/types.js +0 -1
- package/dist/publication/index.d.ts +0 -1
- package/dist/publication/index.js +0 -1
- package/dist/publication/snapshot.d.ts +5 -3
- package/dist/publication/snapshot.js +14 -7
- package/dist/publication/table.d.ts +4 -0
- package/dist/publication/table.js +16 -0
- package/dist/publication/types.d.ts +5 -2
- package/dist/publication/types.js +0 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/index.js +0 -1
- package/dist/routes/routes.d.ts +3 -3
- package/dist/routes/routes.js +91 -26
- package/dist/server.d.ts +0 -1
- package/dist/server.js +13 -7
- package/dist/transport/body.d.ts +0 -1
- package/dist/transport/body.js +0 -1
- package/dist/transport/codecs.d.ts +1 -2
- package/dist/transport/codecs.js +1 -2
- package/dist/transport/credential.d.ts +1 -2
- package/dist/transport/credential.js +1 -2
- package/dist/transport/http/handler.d.ts +2 -1
- package/dist/transport/http/handler.js +36 -33
- package/dist/transport/http/index.d.ts +0 -1
- package/dist/transport/http/index.js +0 -1
- package/dist/transport/http/render.d.ts +17 -13
- package/dist/transport/http/render.js +120 -41
- package/dist/transport/index.d.ts +0 -1
- package/dist/transport/index.js +0 -1
- package/dist/transport/router.d.ts +0 -1
- package/dist/transport/router.js +0 -1
- package/dist/transport/stream-error.d.ts +2 -3
- package/dist/transport/stream-error.js +3 -4
- package/dist/transport/types.d.ts +1 -2
- package/dist/transport/types.js +0 -1
- package/dist/transport/websocket/index.d.ts +0 -1
- package/dist/transport/websocket/index.js +0 -1
- package/dist/transport/websocket/session.d.ts +4 -3
- package/dist/transport/websocket/session.js +56 -39
- package/dist/transport/websocket/upgrade.d.ts +2 -1
- package/dist/transport/websocket/upgrade.js +2 -2
- package/dist/types.d.ts +6 -4
- package/dist/types.js +0 -1
- package/package.json +23 -13
- package/dist/capture.d.ts.map +0 -1
- package/dist/capture.js.map +0 -1
- package/dist/cors/cors.d.ts.map +0 -1
- package/dist/cors/cors.js.map +0 -1
- package/dist/cors/index.d.ts.map +0 -1
- package/dist/cors/index.js.map +0 -1
- package/dist/cors/types.d.ts.map +0 -1
- package/dist/cors/types.js.map +0 -1
- package/dist/errors/availability.d.ts.map +0 -1
- package/dist/errors/availability.js.map +0 -1
- package/dist/errors/classify.d.ts.map +0 -1
- package/dist/errors/classify.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/errors/request-body.d.ts.map +0 -1
- package/dist/errors/request-body.js.map +0 -1
- package/dist/errors/response-body.d.ts.map +0 -1
- package/dist/errors/response-body.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invocation/context.d.ts.map +0 -1
- package/dist/invocation/context.js.map +0 -1
- package/dist/invocation/index.d.ts.map +0 -1
- package/dist/invocation/index.js.map +0 -1
- package/dist/invocation/publication-route.d.ts.map +0 -1
- package/dist/invocation/publication-route.js.map +0 -1
- package/dist/invocation/types.d.ts.map +0 -1
- package/dist/invocation/types.js.map +0 -1
- package/dist/issuer/exchange.d.ts.map +0 -1
- package/dist/issuer/exchange.js.map +0 -1
- package/dist/issuer/index.d.ts.map +0 -1
- package/dist/issuer/index.js.map +0 -1
- package/dist/issuer/routes.d.ts.map +0 -1
- package/dist/issuer/routes.js.map +0 -1
- package/dist/issuer/types.d.ts.map +0 -1
- package/dist/issuer/types.js.map +0 -1
- package/dist/lifecycle/active.d.ts.map +0 -1
- package/dist/lifecycle/active.js.map +0 -1
- package/dist/lifecycle/index.d.ts.map +0 -1
- package/dist/lifecycle/index.js.map +0 -1
- package/dist/publication/delivery/handler.d.ts.map +0 -1
- package/dist/publication/delivery/handler.js.map +0 -1
- package/dist/publication/delivery/index.d.ts.map +0 -1
- package/dist/publication/delivery/index.js.map +0 -1
- package/dist/publication/delivery/types.d.ts.map +0 -1
- package/dist/publication/delivery/types.js.map +0 -1
- package/dist/publication/index.d.ts.map +0 -1
- package/dist/publication/index.js.map +0 -1
- package/dist/publication/snapshot.d.ts.map +0 -1
- package/dist/publication/snapshot.js.map +0 -1
- package/dist/publication/types.d.ts.map +0 -1
- package/dist/publication/types.js.map +0 -1
- package/dist/routes/index.d.ts.map +0 -1
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/routes.d.ts.map +0 -1
- package/dist/routes/routes.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/transport/body.d.ts.map +0 -1
- package/dist/transport/body.js.map +0 -1
- package/dist/transport/codecs.d.ts.map +0 -1
- package/dist/transport/codecs.js.map +0 -1
- package/dist/transport/credential.d.ts.map +0 -1
- package/dist/transport/credential.js.map +0 -1
- package/dist/transport/http/handler.d.ts.map +0 -1
- package/dist/transport/http/handler.js.map +0 -1
- package/dist/transport/http/index.d.ts.map +0 -1
- package/dist/transport/http/index.js.map +0 -1
- package/dist/transport/http/render.d.ts.map +0 -1
- package/dist/transport/http/render.js.map +0 -1
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/router.d.ts.map +0 -1
- package/dist/transport/router.js.map +0 -1
- package/dist/transport/stream-error.d.ts.map +0 -1
- package/dist/transport/stream-error.js.map +0 -1
- package/dist/transport/types.d.ts.map +0 -1
- package/dist/transport/types.js.map +0 -1
- package/dist/transport/websocket/index.d.ts.map +0 -1
- package/dist/transport/websocket/index.js.map +0 -1
- package/dist/transport/websocket/session.d.ts.map +0 -1
- package/dist/transport/websocket/session.js.map +0 -1
- package/dist/transport/websocket/upgrade.d.ts.map +0 -1
- package/dist/transport/websocket/upgrade.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as exchangeProtocol from '@astrale-os/kernel-protocol/issuer/exchange';
|
|
2
2
|
import type { CorsPolicy } from '../cors/index.js';
|
|
3
3
|
import type { ActiveOperations } from '../lifecycle/index.js';
|
|
4
4
|
import type { ServerRouter } from '../transport/index.js';
|
|
@@ -6,8 +6,7 @@ export interface Context {
|
|
|
6
6
|
readonly signal: AbortSignal;
|
|
7
7
|
}
|
|
8
8
|
export interface Provider {
|
|
9
|
-
exchange(request:
|
|
9
|
+
exchange(request: exchangeProtocol.Request, context: Context): Promise<exchangeProtocol.Response>;
|
|
10
10
|
}
|
|
11
11
|
export declare function capture(input: Provider): Provider;
|
|
12
12
|
export declare function mount(app: ServerRouter, issuer: string, provider: Provider, cors: CorsPolicy, active: ActiveOperations, timeoutMs: number): void;
|
|
13
|
-
//# sourceMappingURL=exchange.d.ts.map
|
package/dist/issuer/exchange.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { inspect as inspectCredential } from '@astrale-os/kernel-core/auth/credential';
|
|
2
|
+
import * as errors from '@astrale-os/kernel-protocol/errors';
|
|
3
|
+
import * as exchangeProtocol from '@astrale-os/kernel-protocol/issuer/exchange';
|
|
4
|
+
import { paths as issuerPaths } from '@astrale-os/kernel-protocol/issuer/paths';
|
|
3
5
|
const PROVIDER_CODES = new Set([
|
|
4
6
|
errors.CODES.AUTH_INVALID,
|
|
5
7
|
errors.CODES.AUTH_EXPIRED,
|
|
@@ -16,7 +18,7 @@ export function capture(input) {
|
|
|
16
18
|
});
|
|
17
19
|
}
|
|
18
20
|
export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
19
|
-
const path =
|
|
21
|
+
const path = issuerPaths(issuer).tokenExchange;
|
|
20
22
|
if (cors.enabled) {
|
|
21
23
|
app.options(path, (context) => cors.preflight(context.req.raw, { methods: ['POST'], headers: ['authorization', 'accept'] }));
|
|
22
24
|
}
|
|
@@ -25,7 +27,7 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
25
27
|
const respond = (payload, extra) => json(payload, errors.httpStatusOf(payload.error), request, cors, extra);
|
|
26
28
|
let admitted;
|
|
27
29
|
try {
|
|
28
|
-
admitted =
|
|
30
|
+
admitted = exchangeProtocol.acceptHttpRequest({
|
|
29
31
|
method: request.method,
|
|
30
32
|
url: request.url,
|
|
31
33
|
authorization: request.headers.get('authorization'),
|
|
@@ -34,7 +36,7 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
34
36
|
}
|
|
35
37
|
catch (cause) {
|
|
36
38
|
if (cause instanceof errors.ProtocolError) {
|
|
37
|
-
return respond(
|
|
39
|
+
return respond(exchangeProtocol.acceptErrorResponse({ error: cause.payload }), cause.payload.code === errors.CODES.METHOD_NOT_ALLOWED ? { allow: 'POST' } : undefined);
|
|
38
40
|
}
|
|
39
41
|
throw cause;
|
|
40
42
|
}
|
|
@@ -54,7 +56,7 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
54
56
|
return respond(error('DEADLINE_EXCEEDED', 'Token-exchange deadline elapsed.'));
|
|
55
57
|
}
|
|
56
58
|
if (cause instanceof errors.ProtocolError) {
|
|
57
|
-
return respond(
|
|
59
|
+
return respond(exchangeProtocol.acceptErrorResponse({ error: cause.payload }));
|
|
58
60
|
}
|
|
59
61
|
throw cause;
|
|
60
62
|
}
|
|
@@ -67,15 +69,15 @@ export function mount(app, issuer, provider, cors, active, timeoutMs) {
|
|
|
67
69
|
return respond(error('DEADLINE_EXCEEDED', 'Token-exchange deadline elapsed.'));
|
|
68
70
|
}
|
|
69
71
|
if (cause instanceof errors.ProtocolError && PROVIDER_CODES.has(cause.payload.code)) {
|
|
70
|
-
return respond(
|
|
72
|
+
return respond(exchangeProtocol.acceptErrorResponse({ error: cause.payload }));
|
|
71
73
|
}
|
|
72
74
|
throw cause;
|
|
73
75
|
}
|
|
74
76
|
if (operation.timedOut) {
|
|
75
77
|
return respond(error('DEADLINE_EXCEEDED', 'Token-exchange deadline elapsed.'));
|
|
76
78
|
}
|
|
77
|
-
const response =
|
|
78
|
-
if (
|
|
79
|
+
const response = exchangeProtocol.acceptResponse(output);
|
|
80
|
+
if (inspectCredential(response.token).claims.exp !== response.expiresAt) {
|
|
79
81
|
throw new TypeError('Token-exchange provider returned inconsistent expiry evidence.');
|
|
80
82
|
}
|
|
81
83
|
return json(response, 200, request, cors);
|
|
@@ -118,12 +120,12 @@ function invalidRequest() {
|
|
|
118
120
|
});
|
|
119
121
|
}
|
|
120
122
|
function error(code, message) {
|
|
121
|
-
return
|
|
123
|
+
return exchangeProtocol.acceptErrorResponse({
|
|
122
124
|
error: { code: errors.CODES[code], message },
|
|
123
125
|
});
|
|
124
126
|
}
|
|
125
127
|
function json(value, status, request, cors, extra) {
|
|
126
|
-
const headers = new Headers(
|
|
128
|
+
const headers = new Headers(exchangeProtocol.responseHeaders());
|
|
127
129
|
for (const [name, value] of Object.entries(cors.response(request)))
|
|
128
130
|
headers.set(name, value);
|
|
129
131
|
if (extra !== undefined) {
|
|
@@ -132,4 +134,3 @@ function json(value, status, request, cors, extra) {
|
|
|
132
134
|
}
|
|
133
135
|
return new Response(JSON.stringify(value), { status, headers });
|
|
134
136
|
}
|
|
135
|
-
//# sourceMappingURL=exchange.js.map
|
package/dist/issuer/index.d.ts
CHANGED
package/dist/issuer/index.js
CHANGED
package/dist/issuer/routes.d.ts
CHANGED
|
@@ -11,4 +11,3 @@ export declare function issuerRouteReservations(input: Issuer, tokenExchange?: b
|
|
|
11
11
|
export declare function mountIssuer(app: ServerRouter, input: Issuer, cors: CorsPolicy, active: ActiveOperations, timeoutMs: number, tokenExchange?: Provider): void;
|
|
12
12
|
/** Admit static discovery configuration before Runtime Boot performs any durable work. */
|
|
13
13
|
export declare function admitIssuer(input: Issuer): Issuer;
|
|
14
|
-
//# sourceMappingURL=routes.d.ts.map
|
package/dist/issuer/routes.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { configuration } from '@astrale-os/kernel-protocol/issuer/configuration';
|
|
2
|
+
import { hosted } from '@astrale-os/kernel-protocol/issuer/hosted';
|
|
3
|
+
import { keySet } from '@astrale-os/kernel-protocol/issuer/key-set';
|
|
4
|
+
import { paths as issuerPaths } from '@astrale-os/kernel-protocol/issuer/paths';
|
|
2
5
|
import { IssuerKeysUnavailableError } from '../errors/index.js';
|
|
3
6
|
import { mount } from './exchange.js';
|
|
4
7
|
export function issuerRouteReservations(input, tokenExchange = false) {
|
|
5
|
-
const paths =
|
|
8
|
+
const paths = issuerPaths(input.issuer);
|
|
6
9
|
const reservations = [
|
|
7
10
|
Object.freeze({ path: paths.configuration, methods: Object.freeze(['GET']) }),
|
|
8
11
|
Object.freeze({ path: paths.keys, methods: Object.freeze(['GET']) }),
|
|
@@ -24,16 +27,16 @@ export function issuerRouteReservations(input, tokenExchange = false) {
|
|
|
24
27
|
}
|
|
25
28
|
export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange) {
|
|
26
29
|
const issuer = input.issuer;
|
|
27
|
-
const paths =
|
|
30
|
+
const paths = issuerPaths(issuer);
|
|
28
31
|
const headers = (request) => ({
|
|
29
32
|
...cors.response(request),
|
|
30
33
|
'cache-control': 'no-cache',
|
|
31
34
|
});
|
|
32
35
|
const algorithm = input.signingAlgorithm ?? 'ES256';
|
|
33
|
-
const
|
|
36
|
+
const discovery = configuration(issuer, [algorithm], {
|
|
34
37
|
tokenExchange: tokenExchange !== undefined,
|
|
35
38
|
});
|
|
36
|
-
app.get(paths.configuration, (context) => context.json(
|
|
39
|
+
app.get(paths.configuration, (context) => context.json(discovery, 200, headers(context.req.raw)));
|
|
37
40
|
if (cors.enabled) {
|
|
38
41
|
app.options(paths.configuration, (context) => cors.preflight(context.req.raw, { methods: ['GET'] }));
|
|
39
42
|
app.options(paths.keys, (context) => cors.preflight(context.req.raw, { methods: ['GET'] }));
|
|
@@ -45,7 +48,7 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
45
48
|
}
|
|
46
49
|
try {
|
|
47
50
|
const keys = await input.loadPublicKeys(operation.signal);
|
|
48
|
-
return context.json(
|
|
51
|
+
return context.json(keySet(keys, [algorithm]), 200, headers(context.req.raw));
|
|
49
52
|
}
|
|
50
53
|
catch (cause) {
|
|
51
54
|
if (operation.signal.aborted || cause instanceof IssuerKeysUnavailableError) {
|
|
@@ -68,7 +71,7 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
68
71
|
app.options(`${base}/iss/:thumbprint/.well-known/jwks.json`, (context) => cors.preflight(context.req.raw, { methods: ['GET'] }));
|
|
69
72
|
}
|
|
70
73
|
app.get(`${base}/iss/:thumbprint/.well-known/openid-configuration`, async (context) => {
|
|
71
|
-
const hostedIssuer =
|
|
74
|
+
const hostedIssuer = hosted(issuer, context.req.param('thumbprint'));
|
|
72
75
|
if (hostedIssuer === undefined)
|
|
73
76
|
return context.json({ error: 'Issuer not found.' }, 404, headers(context.req.raw));
|
|
74
77
|
const operation = active.begin(timeoutMs, context.req.raw.signal);
|
|
@@ -79,7 +82,7 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
79
82
|
const keys = await hostedKeys(loadIssuerPublicKeys, hostedIssuer, operation.signal, algorithm);
|
|
80
83
|
if (keys.length === 0)
|
|
81
84
|
return context.json({ error: 'Issuer not found.' }, 404, headers(context.req.raw));
|
|
82
|
-
return context.json(
|
|
85
|
+
return context.json(configuration(hostedIssuer, [algorithm]), 200, headers(context.req.raw));
|
|
83
86
|
}
|
|
84
87
|
catch (cause) {
|
|
85
88
|
if (operation.signal.aborted || cause instanceof IssuerKeysUnavailableError) {
|
|
@@ -92,7 +95,7 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
92
95
|
}
|
|
93
96
|
});
|
|
94
97
|
app.get(`${base}/iss/:thumbprint/.well-known/jwks.json`, async (context) => {
|
|
95
|
-
const hostedIssuer =
|
|
98
|
+
const hostedIssuer = hosted(issuer, context.req.param('thumbprint'));
|
|
96
99
|
if (hostedIssuer === undefined)
|
|
97
100
|
return context.json({ error: 'Issuer not found.' }, 404, headers(context.req.raw));
|
|
98
101
|
const operation = active.begin(timeoutMs, context.req.raw.signal);
|
|
@@ -118,12 +121,12 @@ export function mountIssuer(app, input, cors, active, timeoutMs, tokenExchange)
|
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
123
|
async function hostedKeys(load, issuer, signal, algorithm) {
|
|
121
|
-
return
|
|
124
|
+
return keySet(await load(issuer, signal), [algorithm]).keys;
|
|
122
125
|
}
|
|
123
126
|
/** Admit static discovery configuration before Runtime Boot performs any durable work. */
|
|
124
127
|
export function admitIssuer(input) {
|
|
125
128
|
const signingAlgorithm = input.signingAlgorithm ?? 'ES256';
|
|
126
|
-
const issuer =
|
|
129
|
+
const issuer = configuration(input.issuer, [signingAlgorithm]).issuer;
|
|
127
130
|
if (typeof input.loadPublicKeys !== 'function') {
|
|
128
131
|
throw new TypeError('Issuer public-key loader is invalid.');
|
|
129
132
|
}
|
|
@@ -144,4 +147,3 @@ export function admitIssuer(input) {
|
|
|
144
147
|
}),
|
|
145
148
|
});
|
|
146
149
|
}
|
|
147
|
-
//# sourceMappingURL=routes.js.map
|
package/dist/issuer/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { IssuerId
|
|
1
|
+
import type { IssuerId } from '@astrale-os/kernel-core/auth/issuer';
|
|
2
|
+
import type { JsonWebKey } from '@astrale-os/kernel-core/auth/jwk';
|
|
2
3
|
/** Public issuer material; Server never receives private signing material. */
|
|
3
4
|
export interface Issuer {
|
|
4
5
|
readonly issuer: IssuerId;
|
|
@@ -8,4 +9,3 @@ export interface Issuer {
|
|
|
8
9
|
/** Optional hosted-key discovery for issuers below `<issuer>/iss/:thumbprint`. */
|
|
9
10
|
readonly loadIssuerPublicKeys?: (issuer: IssuerId, signal: AbortSignal) => Promise<readonly JsonWebKey[]>;
|
|
10
11
|
}
|
|
11
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/issuer/types.js
CHANGED
|
@@ -26,6 +26,8 @@ export declare class ActiveOperations {
|
|
|
26
26
|
private changed;
|
|
27
27
|
constructor(maximumConcurrentOperations: number);
|
|
28
28
|
get isAccepting(): boolean;
|
|
29
|
+
/** Whether a newly arriving operation can be admitted without semantic dispatch. */
|
|
30
|
+
get isAvailable(): boolean;
|
|
29
31
|
begin(timeoutMs: number, externalSignal?: AbortSignal): ActiveOperation | undefined;
|
|
30
32
|
attachSocket(socket: ActiveSocket): boolean;
|
|
31
33
|
detachSocket(socket: ActiveSocket): void;
|
|
@@ -37,4 +39,3 @@ export declare class ActiveOperations {
|
|
|
37
39
|
private closeSockets;
|
|
38
40
|
}
|
|
39
41
|
export {};
|
|
40
|
-
//# sourceMappingURL=active.d.ts.map
|
package/dist/lifecycle/active.js
CHANGED
|
@@ -13,10 +13,13 @@ export class ActiveOperations {
|
|
|
13
13
|
get isAccepting() {
|
|
14
14
|
return this.accepting;
|
|
15
15
|
}
|
|
16
|
+
/** Whether a newly arriving operation can be admitted without semantic dispatch. */
|
|
17
|
+
get isAvailable() {
|
|
18
|
+
return this.accepting && this.operations.size < this.maximumConcurrentOperations;
|
|
19
|
+
}
|
|
16
20
|
begin(timeoutMs, externalSignal) {
|
|
17
|
-
if (!this.
|
|
21
|
+
if (!this.isAvailable)
|
|
18
22
|
return undefined;
|
|
19
|
-
}
|
|
20
23
|
const operation = new Operation(Date.now() + timeoutMs, () => {
|
|
21
24
|
this.operations.delete(operation);
|
|
22
25
|
this.changed?.();
|
|
@@ -197,4 +200,3 @@ async function settleCancellation(cancel, reason) {
|
|
|
197
200
|
function abortReason(signal) {
|
|
198
201
|
return signal.reason instanceof Error ? signal.reason.message : 'operation cancelled';
|
|
199
202
|
}
|
|
200
|
-
//# sourceMappingURL=active.js.map
|
package/dist/lifecycle/index.js
CHANGED
|
@@ -7,4 +7,3 @@ export interface Limits {
|
|
|
7
7
|
}
|
|
8
8
|
/** Serve one delivery request against the exact Publication snapshot that selected its URL. */
|
|
9
9
|
export declare function handleDelivery(request: Request, snapshot: PreparedPublicationSnapshot, provider: Provider | undefined, active: ActiveOperations, limits: Limits, cors: Readonly<Record<string, string>>): Promise<Response>;
|
|
10
|
-
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as codecs from '@astrale-os/kernel-protocol/codecs';
|
|
2
|
+
import * as protocolPublication from '@astrale-os/kernel-protocol/publication';
|
|
2
3
|
import { DeliveryUnavailableError } from '../../errors/index.js';
|
|
3
4
|
import { RequestBodyInvalidError, RequestBodyTooLargeError } from '../../errors/index.js';
|
|
4
5
|
import { readBoundedBody } from '../../transport/index.js';
|
|
@@ -124,4 +125,3 @@ function encodedSize(input) {
|
|
|
124
125
|
function toBody(input) {
|
|
125
126
|
return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength);
|
|
126
127
|
}
|
|
127
|
-
//# sourceMappingURL=handler.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type * as publication from '@astrale-os/kernel-protocol/publication';
|
|
2
2
|
export interface Context {
|
|
3
3
|
/** Omitted for a public endpoint; otherwise the exact admitted retrieval credential. */
|
|
4
4
|
readonly token?: publication.delivery.Token;
|
|
@@ -9,4 +9,3 @@ export interface Provider {
|
|
|
9
9
|
/** Throw DeliveryUnavailableError only for an expected dependency outage. */
|
|
10
10
|
create(request: publication.delivery.Request, context: Context): Promise<publication.delivery.Delivery>;
|
|
11
11
|
}
|
|
12
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { preparePublicationSnapshot, readPreparedPublicationSnapshot, type PreparedPublicationSnapshot, } from './snapshot.js';
|
|
2
2
|
export type { PublicationSnapshot, PublicationSnapshotInput, PublicationSource } from './types.js';
|
|
3
3
|
export * as delivery from './delivery/index.js';
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Domain } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import type * as publication from '@astrale-os/kernel-protocol/publication';
|
|
3
|
+
import type * as routes from '@astrale-os/kernel-protocol/routes';
|
|
2
4
|
import type { PublicationSnapshot, PublicationSnapshotInput } from './types.js';
|
|
3
5
|
export interface PreparedPublicationSnapshot {
|
|
4
6
|
readonly snapshot: PublicationSnapshot;
|
|
5
7
|
readonly publication: publication.Publication;
|
|
6
8
|
readonly publicationBytes: Uint8Array;
|
|
7
9
|
readonly bundle: Uint8Array;
|
|
8
|
-
readonly
|
|
10
|
+
readonly table: routes.Table;
|
|
11
|
+
readonly domain: Domain;
|
|
9
12
|
}
|
|
10
13
|
/** Admit and detach one revision-coherent serving snapshot before publication. */
|
|
11
14
|
export declare function preparePublicationSnapshot(input: PublicationSnapshotInput): PublicationSnapshot;
|
|
12
15
|
/** Internal proof that a PublicationSource returned a Server-prepared snapshot without cloning it. */
|
|
13
16
|
export declare function readPreparedPublicationSnapshot(input: unknown): PreparedPublicationSnapshot | undefined;
|
|
14
|
-
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { verifyBundleBytes } from '@astrale-os/kernel-protocol/publication/bundle-evidence';
|
|
2
|
+
import { accept as acceptPublication, encode as encodePublication, } from '@astrale-os/kernel-protocol/publication/publication';
|
|
3
|
+
import { admitTable } from './table.js';
|
|
2
4
|
const snapshots = new WeakMap();
|
|
3
5
|
/** Admit and detach one revision-coherent serving snapshot before publication. */
|
|
4
6
|
export function preparePublicationSnapshot(input) {
|
|
5
7
|
if (input === null || typeof input !== 'object' || !(input.bundle instanceof Uint8Array)) {
|
|
6
8
|
throw new TypeError('Publication snapshot input is invalid.');
|
|
7
9
|
}
|
|
8
|
-
const admittedPublication =
|
|
10
|
+
const admittedPublication = acceptPublication(input.publication);
|
|
9
11
|
const bundleBytes = new Uint8Array(input.bundle);
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
12
|
+
verifyBundleBytes(admittedPublication, bundleBytes);
|
|
13
|
+
const domain = input.domain;
|
|
14
|
+
if (domain.origin !== admittedPublication.origin ||
|
|
15
|
+
domain.revision !== admittedPublication.schema.revision) {
|
|
16
|
+
throw new TypeError('Publication snapshot Domain identity differs from its Publication.');
|
|
17
|
+
}
|
|
18
|
+
const table = admitTable(admittedPublication, input.table, domain);
|
|
19
|
+
const publicationBytes = encodePublication(admittedPublication);
|
|
13
20
|
const snapshot = Object.freeze({ publication: admittedPublication });
|
|
14
21
|
const prepared = Object.freeze({
|
|
15
22
|
snapshot,
|
|
16
23
|
publication: admittedPublication,
|
|
17
24
|
publicationBytes,
|
|
18
25
|
bundle: bundleBytes,
|
|
19
|
-
|
|
26
|
+
table,
|
|
27
|
+
domain,
|
|
20
28
|
});
|
|
21
29
|
snapshots.set(snapshot, prepared);
|
|
22
30
|
return snapshot;
|
|
@@ -27,4 +35,3 @@ export function readPreparedPublicationSnapshot(input) {
|
|
|
27
35
|
return undefined;
|
|
28
36
|
return snapshots.get(input);
|
|
29
37
|
}
|
|
30
|
-
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Domain } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import type * as publication from '@astrale-os/kernel-protocol/publication';
|
|
3
|
+
import type * as routes from '@astrale-os/kernel-protocol/routes';
|
|
4
|
+
export declare function admitTable(deployed: publication.Publication, input: routes.Table | undefined, domain: Domain): routes.Table;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { reference } from '@astrale-os/kernel-protocol/publication/reference';
|
|
2
|
+
import { acceptTable } from '@astrale-os/kernel-protocol/routes/admission';
|
|
3
|
+
import { verifyTable } from '@astrale-os/kernel-protocol/routes/evidence';
|
|
4
|
+
export function admitTable(deployed, input, domain) {
|
|
5
|
+
if (input === undefined) {
|
|
6
|
+
if (deployed.routes.length !== 0) {
|
|
7
|
+
throw new TypeError('A Publication with native routes requires a Route Table.');
|
|
8
|
+
}
|
|
9
|
+
return verifyTable(Object.freeze({
|
|
10
|
+
publication: reference(deployed),
|
|
11
|
+
entries: Object.freeze([]),
|
|
12
|
+
}), deployed, domain);
|
|
13
|
+
}
|
|
14
|
+
const table = acceptTable(input);
|
|
15
|
+
return verifyTable(table, deployed, domain);
|
|
16
|
+
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Domain } from '@astrale-os/kernel-dsl/v1';
|
|
2
|
+
import type * as publication from '@astrale-os/kernel-protocol/publication';
|
|
3
|
+
import type * as routes from '@astrale-os/kernel-protocol/routes';
|
|
2
4
|
declare const PUBLICATION_SNAPSHOT: unique symbol;
|
|
3
5
|
export interface PublicationSnapshotInput {
|
|
4
6
|
readonly publication: publication.Publication;
|
|
5
7
|
/** Exact artifact served at Publication.schema.bundle.href. */
|
|
6
8
|
readonly bundle: Uint8Array;
|
|
9
|
+
readonly table?: routes.Table;
|
|
10
|
+
readonly domain: Domain;
|
|
7
11
|
}
|
|
8
12
|
/** Immutable admitted serving identity; bundle and compiled routes remain Server-private. */
|
|
9
13
|
export interface PublicationSnapshot {
|
|
@@ -16,4 +20,3 @@ export interface PublicationSource {
|
|
|
16
20
|
current(): PublicationSnapshot | undefined;
|
|
17
21
|
}
|
|
18
22
|
export {};
|
|
19
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/routes/index.d.ts
CHANGED
package/dist/routes/index.js
CHANGED
package/dist/routes/routes.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { CorsPolicy } from '../cors/index.js';
|
|
2
|
+
import type { NextInvocationId } from '../invocation/index.js';
|
|
2
3
|
import type { ActiveOperations } from '../lifecycle/index.js';
|
|
3
4
|
import type { Provider as DeliveryProvider } from '../publication/delivery/index.js';
|
|
4
5
|
import type { PublicationSource } from '../publication/index.js';
|
|
5
6
|
import { type ApplicationHost, type Handler } from '../invocation/index.js';
|
|
6
7
|
import { type PreparedPublicationSnapshot } from '../publication/index.js';
|
|
7
|
-
import { type ServerRouter } from '../transport/
|
|
8
|
+
import { type ServerRouter } from '../transport/router.js';
|
|
8
9
|
export interface RouteLimits {
|
|
9
10
|
readonly maximumRequestBytes: number;
|
|
10
11
|
readonly maximumPublicationBytes: number;
|
|
@@ -16,10 +17,9 @@ export interface RouteReservation {
|
|
|
16
17
|
readonly path: string;
|
|
17
18
|
readonly methods: readonly string[];
|
|
18
19
|
}
|
|
19
|
-
export declare function mountRoutes(app: ServerRouter, source: PublicationSource, deliveryProvider: DeliveryProvider | undefined, handler: Handler, active: ActiveOperations, limits: RouteLimits, cors: CorsPolicy, hostFor: (request: Request) => ApplicationHost | undefined, reservations: readonly RouteReservation[], externalIssuer?: string): void;
|
|
20
|
+
export declare function mountRoutes(app: ServerRouter, source: PublicationSource, deliveryProvider: DeliveryProvider | undefined, handler: Handler, active: ActiveOperations, nextInvocation: NextInvocationId, limits: RouteLimits, cors: CorsPolicy, hostFor: (request: Request) => ApplicationHost | undefined, reservations: readonly RouteReservation[], externalIssuer?: string): void;
|
|
20
21
|
export declare function currentPublicationSnapshot(source: PublicationSource, limits: Pick<RouteLimits, 'maximumPublicationBytes' | 'maximumBundleBytes'>, serving?: {
|
|
21
22
|
readonly origin: string;
|
|
22
23
|
readonly issuer?: string;
|
|
23
24
|
readonly reservations: readonly RouteReservation[];
|
|
24
25
|
}): PreparedPublicationSnapshot | undefined;
|
|
25
|
-
//# sourceMappingURL=routes.d.ts.map
|