@astrale-os/sdk 0.5.0-beta.142 → 0.5.0-beta.143
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 +23 -0
- package/dist/application/index.d.ts +1 -1
- package/dist/application/view/index.d.ts +1 -1
- package/dist/application/view/route.d.ts +4 -0
- package/dist/application/view/route.js +5 -1
- package/dist/deployment/build/frontend/compilation.d.ts +2 -1
- package/dist/deployment/build/frontend/compilation.js +1 -0
- package/dist/deployment/release/publication/views.js +1 -0
- package/dist/deployment/verify/readiness/identity.js +1 -1
- package/dist/deployment/verify/readiness/publication.js +1 -1
- package/dist/execution/identity/jwks.js +1 -1
- package/dist/execution/service/create.js +1 -1
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -224,3 +224,26 @@ coherent Publication, bundle, and View catalog observation.
|
|
|
224
224
|
## License
|
|
225
225
|
|
|
226
226
|
Apache License 2.0 — see [LICENSE](LICENSE) for details.
|
|
227
|
+
|
|
228
|
+
## View host requirements
|
|
229
|
+
|
|
230
|
+
A frontend route can declare the exact external origins its View needs to open:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
routes: {
|
|
234
|
+
application: {
|
|
235
|
+
path: '/',
|
|
236
|
+
host: {
|
|
237
|
+
navigation: {
|
|
238
|
+
external: { origins: ['https://provider.example'] },
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
These requirements are publication metadata, so changing them updates the publication ETag without
|
|
246
|
+
changing the Application's business Schema. They require the `shell` handshake. Origins must use
|
|
247
|
+
HTTPS without credentials, paths, queries, fragments, or wildcards; authoring normalizes and sorts
|
|
248
|
+
them. Supporting hosts admit them per mount and execute the existing `browser.openExternal`
|
|
249
|
+
intent. Nested Views cannot expand their parent's grant.
|
|
@@ -5,5 +5,5 @@ export type { AuthorityRequirements, AuthorityRequirementsInput, ClassOperation,
|
|
|
5
5
|
export { route, routes } from './routes/index.js';
|
|
6
6
|
export type { Route, RouteInput, RouteTarget, Routes } from './routes/index.js';
|
|
7
7
|
export { defineFrontend, external, vite } from './view/index.js';
|
|
8
|
-
export type { Frontend, FrontendInput, FrontendSource, IframeRequirements } from './view/index.js';
|
|
8
|
+
export type { Frontend, FrontendInput, FrontendSource, IframeRequirements, ViewHostRequirements, } from './view/index.js';
|
|
9
9
|
export type { Application, ApplicationIdentity, RuntimeOfApplication, SchemaOfApplication, SchemaOfRuntime, } from './application.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { isFrontend } from './admission.js';
|
|
2
2
|
export { defineFrontend } from './define.js';
|
|
3
3
|
export type { Frontend, FrontendInput, FrontendRouteInputs, FrontendRoutes, ViewName, } from './frontend.js';
|
|
4
|
-
export type { FrontendHandshake, FrontendRoute, FrontendRouteInput, IframeRequirements, } from './route.js';
|
|
4
|
+
export type { FrontendHandshake, FrontendRoute, FrontendRouteInput, IframeRequirements, ViewHostRequirements, } from './route.js';
|
|
5
5
|
export { external, isFrontendSource, vite } from './source.js';
|
|
6
6
|
export type { ExternalSource, FrontendSource, ViteSource } from './source.js';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type ViewHostRequirements } from '@astrale-os/kernel-core/schema/kernel/syscalls/view-resolution';
|
|
2
|
+
export type { ViewHostRequirements } from '@astrale-os/kernel-core/schema/kernel/syscalls/view-resolution';
|
|
1
3
|
export type FrontendHandshake = 'shell' | 'none';
|
|
2
4
|
export interface IframeRequirements {
|
|
3
5
|
readonly sandbox?: readonly string[];
|
|
@@ -8,12 +10,14 @@ export type FrontendRouteInput = string | {
|
|
|
8
10
|
readonly document?: string;
|
|
9
11
|
readonly handshake?: FrontendHandshake;
|
|
10
12
|
readonly iframe?: IframeRequirements;
|
|
13
|
+
readonly host?: ViewHostRequirements;
|
|
11
14
|
};
|
|
12
15
|
export interface FrontendRoute {
|
|
13
16
|
readonly path: string;
|
|
14
17
|
readonly document: string;
|
|
15
18
|
readonly handshake: FrontendHandshake;
|
|
16
19
|
readonly iframe?: IframeRequirements;
|
|
20
|
+
readonly host?: ViewHostRequirements;
|
|
17
21
|
}
|
|
18
22
|
export declare function normalizeRoute(input: FrontendRouteInput | undefined, fallback: string): FrontendRoute;
|
|
19
23
|
export declare function defaultRoute(name: string): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { acceptViewHostRequirements, } from '@astrale-os/kernel-core/schema/kernel/syscalls/view-resolution';
|
|
1
2
|
const TOKEN = /^[a-z][a-z0-9-]*$/u;
|
|
2
3
|
const BASELINES = Object.freeze({
|
|
3
4
|
none: iframeRequirements(['allow-scripts'], []),
|
|
@@ -8,7 +9,8 @@ export function normalizeRoute(input, fallback) {
|
|
|
8
9
|
return Object.freeze({ path: routePath(input), document: 'index.html', handshake: 'shell' });
|
|
9
10
|
}
|
|
10
11
|
const value = plainRecord(input ?? {});
|
|
11
|
-
if (Reflect.ownKeys(value).some((key) => typeof key !== 'string' ||
|
|
12
|
+
if (Reflect.ownKeys(value).some((key) => typeof key !== 'string' ||
|
|
13
|
+
!['path', 'document', 'handshake', 'iframe', 'host'].includes(key))) {
|
|
12
14
|
invalid();
|
|
13
15
|
}
|
|
14
16
|
const authoredHandshake = dataValue(value, 'handshake');
|
|
@@ -19,11 +21,13 @@ export function normalizeRoute(input, fallback) {
|
|
|
19
21
|
}
|
|
20
22
|
const handshake = authoredHandshake ?? 'shell';
|
|
21
23
|
const iframe = normalizeIframeRequirements(dataValue(value, 'iframe'), handshake);
|
|
24
|
+
const host = acceptViewHostRequirements(dataValue(value, 'host'), handshake, true);
|
|
22
25
|
return Object.freeze({
|
|
23
26
|
path: routePath(dataValue(value, 'path') ?? fallback),
|
|
24
27
|
document: filePath(dataValue(value, 'document') ?? 'index.html'),
|
|
25
28
|
handshake,
|
|
26
29
|
...(iframe === undefined ? {} : { iframe }),
|
|
30
|
+
...(host === undefined ? {} : { host }),
|
|
27
31
|
});
|
|
28
32
|
}
|
|
29
33
|
function normalizeIframeRequirements(input, handshake) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Frontend, FrontendSource } from '../../../application/view/index.js';
|
|
2
|
-
import type { FrontendHandshake, IframeRequirements } from '../../../application/view/index.js';
|
|
2
|
+
import type { FrontendHandshake, IframeRequirements, ViewHostRequirements } from '../../../application/view/index.js';
|
|
3
3
|
import type { Key, ViewRef } from '../../../platform/schema/index.js';
|
|
4
4
|
import type { Domain } from '../../../platform/schema/index.js';
|
|
5
5
|
export interface CompiledFrontendRoute {
|
|
@@ -8,6 +8,7 @@ export interface CompiledFrontendRoute {
|
|
|
8
8
|
readonly document: string;
|
|
9
9
|
readonly handshake: FrontendHandshake;
|
|
10
10
|
readonly iframe?: IframeRequirements;
|
|
11
|
+
readonly host?: ViewHostRequirements;
|
|
11
12
|
}
|
|
12
13
|
export interface FrontendCompilation {
|
|
13
14
|
readonly source: FrontendSource;
|
|
@@ -16,6 +16,7 @@ export function compileFrontend(frontend, domain) {
|
|
|
16
16
|
document: route.document,
|
|
17
17
|
handshake: route.handshake,
|
|
18
18
|
...(route.iframe === undefined ? {} : { iframe: route.iframe }),
|
|
19
|
+
...(route.host === undefined ? {} : { host: route.host }),
|
|
19
20
|
});
|
|
20
21
|
});
|
|
21
22
|
const entrypoint = domain.views[frontend.entrypoint];
|
|
@@ -9,5 +9,6 @@ export function views(build, addressing) {
|
|
|
9
9
|
href: new URL(route.path.replace(/^\//u, ''), base).href,
|
|
10
10
|
handshake: route.handshake,
|
|
11
11
|
...(route.iframe === undefined ? {} : { iframe: route.iframe }),
|
|
12
|
+
...(route.host === undefined ? {} : { host: route.host }),
|
|
12
13
|
})));
|
|
13
14
|
}
|
|
@@ -21,7 +21,7 @@ async function json(fetcher, url, signal) {
|
|
|
21
21
|
throw new Error(`GET ${url} exceeded ${MAXIMUM_IDENTITY_BYTES} bytes.`);
|
|
22
22
|
}
|
|
23
23
|
try {
|
|
24
|
-
return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
|
|
24
|
+
return JSON.parse(new TextDecoder('utf-8', { fatal: true, ignoreBOM: false }).decode(bytes));
|
|
25
25
|
}
|
|
26
26
|
catch (cause) {
|
|
27
27
|
throw new Error(`GET ${url} returned invalid JSON.`, { cause });
|
|
@@ -33,7 +33,7 @@ async function bounded(response, url, maximum) {
|
|
|
33
33
|
async function text(response, url, maximum) {
|
|
34
34
|
const bytes = await bounded(response, url, maximum);
|
|
35
35
|
try {
|
|
36
|
-
return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
36
|
+
return new TextDecoder('utf-8', { fatal: true, ignoreBOM: false }).decode(bytes);
|
|
37
37
|
}
|
|
38
38
|
catch (cause) {
|
|
39
39
|
throw new Error(`GET ${url} returned invalid UTF-8.`, { cause });
|
|
@@ -244,7 +244,7 @@ async function json(response, signal) {
|
|
|
244
244
|
throw new CredentialRejected('Issuer discovery document exceeds its byte limit.');
|
|
245
245
|
}
|
|
246
246
|
try {
|
|
247
|
-
return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
|
|
247
|
+
return JSON.parse(new TextDecoder('utf-8', { fatal: true, ignoreBOM: false }).decode(bytes));
|
|
248
248
|
}
|
|
249
249
|
catch (cause) {
|
|
250
250
|
throw new CredentialRejected('Issuer discovery document is invalid.', cause);
|
|
@@ -35,7 +35,7 @@ export function createService(input) {
|
|
|
35
35
|
path: invocationPath(),
|
|
36
36
|
invocation: {
|
|
37
37
|
source: selectedIdentity.issuer,
|
|
38
|
-
next: () =>
|
|
38
|
+
next: () => crypto.randomUUID(),
|
|
39
39
|
},
|
|
40
40
|
issuer: selectedIdentity,
|
|
41
41
|
...(selectedIdentity.tokenExchange === undefined
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/sdk",
|
|
3
|
-
"version": "0.5.0-beta.
|
|
3
|
+
"version": "0.5.0-beta.143",
|
|
4
4
|
"description": "Schema-first SDK for defining, composing, and deploying Astrale domains",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"astrale",
|
|
@@ -237,11 +237,11 @@
|
|
|
237
237
|
"registry": "https://registry.npmjs.org/"
|
|
238
238
|
},
|
|
239
239
|
"dependencies": {
|
|
240
|
-
"@astrale-os/kernel-client": "0.6.0-beta.
|
|
241
|
-
"@astrale-os/kernel-core": "0.9.0-beta.
|
|
240
|
+
"@astrale-os/kernel-client": "0.6.0-beta.62",
|
|
241
|
+
"@astrale-os/kernel-core": "0.9.0-beta.47",
|
|
242
242
|
"@astrale-os/kernel-dsl": "0.2.0-beta.33",
|
|
243
|
-
"@astrale-os/kernel-protocol": "0.5.0-beta.
|
|
244
|
-
"@astrale-os/kernel-server": "0.5.0-beta.
|
|
243
|
+
"@astrale-os/kernel-protocol": "0.5.0-beta.53",
|
|
244
|
+
"@astrale-os/kernel-server": "0.5.0-beta.55",
|
|
245
245
|
"@lucide/icons": "1.34.0",
|
|
246
246
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
247
247
|
"cross-spawn": "7.0.6",
|
|
@@ -253,6 +253,7 @@
|
|
|
253
253
|
"@astrale-os/ox": "0.1.3",
|
|
254
254
|
"@astrale/commitlint-config": "npm:@jsr/astrale__commitlint-config@~2.0.5",
|
|
255
255
|
"@astrale/typescript-config": "npm:@jsr/astrale__typescript-config@~1.1.3",
|
|
256
|
+
"@cloudflare/workers-types": "^5.20260820.1",
|
|
256
257
|
"@commitlint/cli": "~21.2.2",
|
|
257
258
|
"@commitlint/config-conventional": "~21.2.2",
|
|
258
259
|
"@hono/node-server": "^2.1.1",
|
|
@@ -310,7 +311,8 @@
|
|
|
310
311
|
"scripts": {
|
|
311
312
|
"build": "node scripts/clean-dist.mjs && tsgo && node scripts/verify-no-source-maps.mjs dist && pnpm run verify:package",
|
|
312
313
|
"e2e": "node __e2e__/flagship/runner.mjs",
|
|
313
|
-
"typecheck": "tsgo --noEmit && pnpm run typecheck:specs && pnpm run typecheck:types && pnpm run typecheck:tests && pnpm run typecheck:e2e && pnpm run typecheck:knowledge",
|
|
314
|
+
"typecheck": "tsgo --noEmit && pnpm run typecheck:workers && pnpm run typecheck:specs && pnpm run typecheck:types && pnpm run typecheck:tests && pnpm run typecheck:e2e && pnpm run typecheck:knowledge",
|
|
315
|
+
"typecheck:workers": "tsgo --noEmit -p tsconfig.workers.json",
|
|
314
316
|
"typecheck:specs": "tsgo --noEmit -p src/application/query/.spec/tsconfig.json && tsgo --noEmit -p src/platform/schema/.spec/tsconfig.json && tsgo --noEmit -p src/application/mutation/.spec/tsconfig.json && tsgo --noEmit -p src/tooling/cli/.spec/tsconfig.json",
|
|
315
317
|
"typecheck:types": "tsgo --noEmit -p __tests__/tsconfig.types.json",
|
|
316
318
|
"typecheck:tests": "tsgo --noEmit -p tsconfig.test.json",
|