@astrale-os/kernel-server 0.5.0-beta.55 → 0.5.0-beta.57
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/routes/routes.d.ts +1 -1
- package/dist/routes/routes.js +7 -6
- package/dist/server.js +17 -2
- package/dist/types.d.ts +2 -0
- package/package.json +4 -4
package/dist/routes/routes.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface RouteReservation {
|
|
|
17
17
|
readonly path: string;
|
|
18
18
|
readonly methods: readonly string[];
|
|
19
19
|
}
|
|
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
|
+
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, publicOrigin?: string): void;
|
|
21
21
|
export declare function currentPublicationSnapshot(source: PublicationSource, limits: Pick<RouteLimits, 'maximumPublicationBytes' | 'maximumBundleBytes'>, serving?: {
|
|
22
22
|
readonly origin: string;
|
|
23
23
|
readonly issuer?: string;
|
package/dist/routes/routes.js
CHANGED
|
@@ -12,11 +12,11 @@ import { readPreparedPublicationSnapshot, } from '../publication/index.js';
|
|
|
12
12
|
import { readBoundedBody } from '../transport/body.js';
|
|
13
13
|
import {} from '../transport/router.js';
|
|
14
14
|
import { interruptedStreamError } from '../transport/stream-error.js';
|
|
15
|
-
export function mountRoutes(app, source, deliveryProvider, handler, active, nextInvocation, limits, cors, hostFor, reservations, externalIssuer) {
|
|
15
|
+
export function mountRoutes(app, source, deliveryProvider, handler, active, nextInvocation, limits, cors, hostFor, reservations, externalIssuer, publicOrigin) {
|
|
16
16
|
const publicationPath = externalIssuer === undefined
|
|
17
17
|
? PUBLICATION_PATH
|
|
18
18
|
: new URL(publicationUrl(externalIssuer)).pathname;
|
|
19
|
-
const externalOrigin = externalIssuer === undefined ? undefined : new URL(externalIssuer).origin;
|
|
19
|
+
const externalOrigin = publicOrigin ?? (externalIssuer === undefined ? undefined : new URL(externalIssuer).origin);
|
|
20
20
|
if (cors.enabled) {
|
|
21
21
|
app.options(publicationPath, (context) => cors.preflight(context.req.raw, {
|
|
22
22
|
methods: ['GET'],
|
|
@@ -27,7 +27,7 @@ export function mountRoutes(app, source, deliveryProvider, handler, active, next
|
|
|
27
27
|
const responseCors = cors.response(context.req.raw, ['etag']);
|
|
28
28
|
if (!active.isAccepting)
|
|
29
29
|
return response({ error: 'Publication is unavailable while draining.' }, 503, responseCors);
|
|
30
|
-
const snapshot = servingSnapshot(source, limits, context.req.raw, reservations, externalIssuer);
|
|
30
|
+
const snapshot = servingSnapshot(source, limits, context.req.raw, reservations, externalIssuer, externalOrigin);
|
|
31
31
|
if (snapshot === undefined)
|
|
32
32
|
return response({ error: 'Publication is not ready.' }, 503, responseCors);
|
|
33
33
|
const body = snapshot.publicationBytes;
|
|
@@ -52,7 +52,7 @@ export function mountRoutes(app, source, deliveryProvider, handler, active, next
|
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
54
|
app.all('*', async (context) => {
|
|
55
|
-
const snapshot = servingSnapshot(source, limits, context.req.raw, reservations, externalIssuer);
|
|
55
|
+
const snapshot = servingSnapshot(source, limits, context.req.raw, reservations, externalIssuer, externalOrigin);
|
|
56
56
|
if (snapshot === undefined)
|
|
57
57
|
return context.notFound();
|
|
58
58
|
const request = context.req.raw;
|
|
@@ -352,9 +352,10 @@ export function currentPublicationSnapshot(source, limits, serving) {
|
|
|
352
352
|
}
|
|
353
353
|
return prepared;
|
|
354
354
|
}
|
|
355
|
-
function servingSnapshot(source, limits, request, reservations, externalIssuer) {
|
|
355
|
+
function servingSnapshot(source, limits, request, reservations, externalIssuer, publicOrigin) {
|
|
356
356
|
return currentPublicationSnapshot(source, limits, {
|
|
357
|
-
origin:
|
|
357
|
+
origin: publicOrigin ??
|
|
358
|
+
(externalIssuer === undefined ? new URL(request.url).origin : new URL(externalIssuer).origin),
|
|
358
359
|
...(externalIssuer === undefined ? {} : { issuer: externalIssuer }),
|
|
359
360
|
reservations,
|
|
360
361
|
});
|
package/dist/server.js
CHANGED
|
@@ -26,7 +26,8 @@ function createPreparedServer(input, config) {
|
|
|
26
26
|
const app = createServerRouter();
|
|
27
27
|
const hosts = new WeakMap();
|
|
28
28
|
const externalIssuer = config.issuer?.issuer;
|
|
29
|
-
const externalOrigin =
|
|
29
|
+
const externalOrigin = config.publicOrigin ??
|
|
30
|
+
(externalIssuer === undefined ? undefined : new URL(externalIssuer).origin);
|
|
30
31
|
const handleHttp = createHttpHandler({
|
|
31
32
|
handler,
|
|
32
33
|
active,
|
|
@@ -82,7 +83,7 @@ function createPreparedServer(input, config) {
|
|
|
82
83
|
mountIssuer(app, config.issuer, config.cors, active, config.limits.invocationTimeoutMs, config.tokenExchange);
|
|
83
84
|
}
|
|
84
85
|
if (config.publication !== undefined) {
|
|
85
|
-
mountRoutes(app, config.publication, config.delivery, handler, active, config.invocation, config.limits, config.cors, (request) => hosts.get(request), config.routeReservations, externalIssuer);
|
|
86
|
+
mountRoutes(app, config.publication, config.delivery, handler, active, config.invocation, config.limits, config.cors, (request) => hosts.get(request), config.routeReservations, externalIssuer, externalOrigin);
|
|
86
87
|
}
|
|
87
88
|
app.onError((_error, context) => new Response('{"error":"Internal server error."}', {
|
|
88
89
|
status: 500,
|
|
@@ -131,6 +132,7 @@ function captureHandler(input) {
|
|
|
131
132
|
return Object.freeze({ dispatch });
|
|
132
133
|
}
|
|
133
134
|
function admitOptions(config) {
|
|
135
|
+
const publicOrigin = config.publicOrigin === undefined ? undefined : admitPublicOrigin(config.publicOrigin);
|
|
134
136
|
const invocation = captureInvocationSource(config.invocation);
|
|
135
137
|
const limits = admitLimits(config.limits);
|
|
136
138
|
const path = admitRoute(config.path ?? '/', 'invocation path');
|
|
@@ -180,6 +182,7 @@ function admitOptions(config) {
|
|
|
180
182
|
}
|
|
181
183
|
return Object.freeze({
|
|
182
184
|
invocation,
|
|
185
|
+
...(publicOrigin === undefined ? {} : { publicOrigin }),
|
|
183
186
|
limits,
|
|
184
187
|
path,
|
|
185
188
|
cors: prepareCors(config.cors),
|
|
@@ -264,3 +267,15 @@ function admitRoute(path, label) {
|
|
|
264
267
|
}
|
|
265
268
|
return path;
|
|
266
269
|
}
|
|
270
|
+
function admitPublicOrigin(input) {
|
|
271
|
+
const url = new URL(input);
|
|
272
|
+
if (!['http:', 'https:'].includes(url.protocol) ||
|
|
273
|
+
url.username !== '' ||
|
|
274
|
+
url.password !== '' ||
|
|
275
|
+
url.pathname !== '/' ||
|
|
276
|
+
url.search !== '' ||
|
|
277
|
+
url.hash !== '') {
|
|
278
|
+
throw new TypeError('Server publicOrigin must be an HTTP(S) origin.');
|
|
279
|
+
}
|
|
280
|
+
return url.origin;
|
|
281
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -37,6 +37,8 @@ export interface ServerOptions {
|
|
|
37
37
|
readonly probe: HealthProbe;
|
|
38
38
|
} | false;
|
|
39
39
|
readonly issuer?: Issuer;
|
|
40
|
+
/** Public HTTP origin for transport placement, independent of the stable issuer. */
|
|
41
|
+
readonly publicOrigin?: string;
|
|
40
42
|
/** Present only for the configured self issuer; owns verification and signing. */
|
|
41
43
|
readonly tokenExchange?: exchange.Provider;
|
|
42
44
|
readonly publication?: PublicationSource;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/kernel-server",
|
|
3
|
-
"version": "0.5.0-beta.
|
|
3
|
+
"version": "0.5.0-beta.57",
|
|
4
4
|
"description": "Portable HTTP and WebSocket boundary for Astrale invocation, publication, installation, and issuer protocols",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@astrale-os/kernel-core": "0.9.0-beta.
|
|
37
|
-
"@astrale-os/kernel-dsl": "0.2.0-beta.
|
|
38
|
-
"@astrale-os/kernel-protocol": "0.5.0-beta.
|
|
36
|
+
"@astrale-os/kernel-core": "0.9.0-beta.49",
|
|
37
|
+
"@astrale-os/kernel-dsl": "0.2.0-beta.34",
|
|
38
|
+
"@astrale-os/kernel-protocol": "0.5.0-beta.55",
|
|
39
39
|
"hono": "^4.6.20",
|
|
40
40
|
"msgpackr": "^2.0.5"
|
|
41
41
|
},
|