@astrale-os/sdk 0.6.0-beta.22 → 0.6.0-beta.24
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 +30 -36
- package/dist/application/define.d.ts +3 -1
- package/dist/application/define.js +16 -2
- package/dist/application/domain.d.ts +3 -1
- package/dist/application/index.d.ts +1 -1
- package/dist/application/mutation/index.d.ts +1 -1
- package/dist/application/query/composite/plan.d.ts +0 -4
- package/dist/application/query/composite/plan.js +0 -2
- package/dist/application/view/define.js +4 -6
- package/dist/application/view/frontend.d.ts +2 -2
- package/dist/application/view/index.d.ts +1 -1
- package/dist/application/view/route.d.ts +0 -14
- package/dist/application/view/route.js +1 -64
- package/dist/deployment/adapter/adapter.d.ts +11 -24
- package/dist/deployment/adapter/bundle/file.d.ts +1 -1
- package/dist/deployment/adapter/define.d.ts +4 -25
- package/dist/deployment/adapter/define.js +12 -44
- package/dist/deployment/adapter/index.d.ts +0 -2
- package/dist/deployment/adapter/release/context.d.ts +3 -4
- package/dist/deployment/adapter/release/list.d.ts +1 -2
- package/dist/deployment/address/configuration.d.ts +12 -0
- package/dist/deployment/address/configuration.js +11 -0
- package/dist/deployment/address/index.d.ts +2 -2
- package/dist/deployment/address/index.js +2 -2
- package/dist/deployment/address/label.d.ts +5 -5
- package/dist/deployment/address/label.js +5 -5
- package/dist/deployment/address/record.d.ts +21 -0
- package/dist/deployment/address/record.js +34 -0
- package/dist/deployment/address/summary.d.ts +3 -7
- package/dist/deployment/authoring.d.ts +0 -2
- package/dist/deployment/authoring.js +0 -1
- package/dist/deployment/build/build.d.ts +6 -0
- package/dist/deployment/build/compile.js +2 -0
- package/dist/deployment/build/frontend/compilation.d.ts +2 -4
- package/dist/deployment/build/frontend/compilation.js +0 -5
- package/dist/deployment/build/frontend/digest.js +1 -5
- package/dist/deployment/build/material.d.ts +2 -2
- package/dist/deployment/build/material.js +28 -13
- package/dist/deployment/deployment.d.ts +4 -8
- package/dist/deployment/index.d.ts +3 -5
- package/dist/deployment/index.js +1 -2
- package/dist/deployment/release/addressing.d.ts +2 -9
- package/dist/deployment/release/addressing.js +2 -3
- package/dist/deployment/release/index.d.ts +0 -2
- package/dist/deployment/release/index.js +0 -2
- package/dist/deployment/release/release.d.ts +1 -1
- package/dist/deployment/release/runtime.d.ts +0 -2
- package/dist/deployment/release/runtime.js +0 -2
- package/dist/deployment/release/served/index.d.ts +1 -2
- package/dist/deployment/release/served/index.js +7 -3
- package/dist/deployment/release/served/views.js +0 -1
- package/dist/deployment/verify/index.d.ts +2 -4
- package/dist/deployment/verify/index.js +1 -3
- package/dist/deployment/verify/preflight/index.d.ts +0 -12
- package/dist/deployment/verify/preflight/index.js +0 -12
- package/dist/deployment/verify/readiness/index.d.ts +9 -6
- package/dist/deployment/verify/readiness/index.js +20 -12
- package/dist/deployment/worker/address.d.ts +26 -0
- package/dist/deployment/worker/address.js +43 -0
- package/dist/deployment/worker/build.d.ts +60 -0
- package/dist/deployment/worker/build.js +172 -0
- package/dist/deployment/worker/configuration.d.ts +73 -0
- package/dist/deployment/worker/configuration.js +165 -0
- package/dist/deployment/worker/content.d.ts +38 -0
- package/dist/deployment/worker/content.js +169 -0
- package/dist/deployment/worker/index.d.ts +29 -0
- package/dist/deployment/worker/index.js +29 -0
- package/dist/deployment/worker/limits.d.ts +30 -0
- package/dist/deployment/worker/limits.js +30 -0
- package/dist/deployment/worker/record.d.ts +29 -0
- package/dist/deployment/worker/record.js +69 -0
- package/dist/deployment/worker/request.d.ts +118 -0
- package/dist/deployment/worker/request.js +280 -0
- package/dist/deployment/worker/response.d.ts +101 -0
- package/dist/deployment/worker/response.js +207 -0
- package/dist/execution/identity/delivery.d.ts +2 -7
- package/dist/execution/identity/delivery.js +1 -23
- package/dist/execution/identity/identity.d.ts +2 -3
- package/dist/execution/index.d.ts +1 -3
- package/dist/execution/index.js +1 -2
- package/dist/execution/invocation/admission/authority.d.ts +4 -5
- package/dist/execution/invocation/admission/authority.js +1 -2
- package/dist/execution/invocation/index.d.ts +2 -2
- package/dist/execution/invocation/index.js +1 -1
- package/dist/execution/invocation/invocation.js +3 -12
- package/dist/execution/invocation/result/errors.d.ts +0 -10
- package/dist/execution/invocation/result/errors.js +0 -17
- package/dist/execution/invocation/result/index.d.ts +2 -2
- package/dist/execution/invocation/result/index.js +1 -1
- package/dist/execution/runtime/release.d.ts +6 -11
- package/dist/execution/runtime/release.js +2 -9
- package/dist/execution/service/create.js +3 -1
- package/dist/execution/service/service.d.ts +2 -3
- package/dist/execution/service/serving/delivery.d.ts +1 -2
- package/dist/execution/service/serving/delivery.js +1 -2
- package/dist/execution/service/serving/source.d.ts +3 -10
- package/dist/execution/service/serving/source.js +1 -5
- package/dist/execution/workflows/index.d.ts +1 -1
- package/dist/execution/workflows/index.js +1 -1
- package/dist/execution/workflows/options.d.ts +0 -6
- package/dist/execution/workflows/options.js +0 -18
- package/dist/execution/workflows/receiver.d.ts +1 -2
- package/dist/execution/workflows/receiver.js +13 -20
- package/dist/execution/workflows/route.d.ts +1 -3
- package/dist/execution/workflows/route.js +4 -9
- package/dist/execution/workflows/run.d.ts +1 -1
- package/dist/execution/workflows/run.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/platform/graph/alias.d.ts +1 -5
- package/dist/platform/graph/alias.js +1 -5
- package/dist/platform/graph/document/index.d.ts +1 -1
- package/dist/platform/graph/document/index.js +1 -1
- package/dist/platform/graph/index.d.ts +1 -1
- package/dist/platform/graph/index.js +1 -1
- package/dist/platform/release/index.d.ts +1 -26
- package/dist/platform/release/index.js +1 -26
- package/dist/platform/schema/class-icon-svg.d.ts +9 -0
- package/dist/platform/schema/class-icon-svg.js +29 -0
- package/dist/platform/schema/class-icon.d.ts +3 -8
- package/dist/platform/schema/class-icon.js +2 -29
- package/dist/platform/schema/index.d.ts +1 -1
- package/dist/platform/schema/schema-authoring.d.ts +14 -7
- package/dist/platform/schema/schema-authoring.js +5 -1
- package/dist/project/admit.js +0 -4
- package/dist/project/install-command.d.ts +0 -4
- package/dist/project/install-command.js +1 -5
- package/dist/tooling/cli/deploy-mode.d.ts +3 -59
- package/dist/tooling/cli/deploy-mode.js +46 -122
- package/dist/tooling/cli/deploy-result.d.ts +10 -15
- package/dist/tooling/cli/help.js +9 -16
- package/dist/tooling/cli/immutable-deployment.d.ts +5 -5
- package/dist/tooling/cli/index.d.ts +1 -1
- package/dist/tooling/cli/list.d.ts +5 -7
- package/dist/tooling/cli/list.js +9 -61
- package/dist/tooling/cli/orchestrate.js +6 -16
- package/dist/tooling/cli/publish/index.d.ts +2 -2
- package/dist/tooling/cli/registry/client.js +1 -1
- package/dist/tooling/cli/secrets.d.ts +2 -2
- package/dist/tooling/linter/implementations/source/global.js +0 -1
- package/dist/tooling/linter/implementations/source/verifiers.js +0 -2
- package/dist/tooling/linter/policy/generated.js +2 -51
- package/dist/tooling/linter/requirements/registry.js +0 -6
- package/package.json +10 -6
- package/dist/application/query/execution/projection.d.ts +0 -3
- package/dist/application/query/execution/projection.js +0 -3
- package/dist/deployment/adapter/legacy/adapter.d.ts +0 -40
- package/dist/deployment/adapter/legacy/adapter.js +0 -1
- package/dist/deployment/adapter/legacy/deploy/context.d.ts +0 -19
- package/dist/deployment/adapter/legacy/deploy/context.js +0 -1
- package/dist/deployment/adapter/legacy/deploy/index.d.ts +0 -2
- package/dist/deployment/adapter/legacy/deploy/index.js +0 -1
- package/dist/deployment/adapter/legacy/deploy/result.d.ts +0 -89
- package/dist/deployment/adapter/legacy/deploy/result.js +0 -1
- package/dist/deployment/adapter/legacy/index.d.ts +0 -24
- package/dist/deployment/adapter/legacy/index.js +0 -1
- package/dist/deployment/adapter/legacy/prepare/artifact.d.ts +0 -43
- package/dist/deployment/adapter/legacy/prepare/artifact.js +0 -1
- package/dist/deployment/adapter/legacy/prepare/context.d.ts +0 -33
- package/dist/deployment/adapter/legacy/prepare/context.js +0 -1
- package/dist/deployment/adapter/legacy/prepare/index.d.ts +0 -2
- package/dist/deployment/adapter/legacy/prepare/index.js +0 -1
- package/dist/deployment/deploy.d.ts +0 -20
- package/dist/deployment/deploy.js +0 -31
- package/dist/deployment/release/legacy/admission.d.ts +0 -3
- package/dist/deployment/release/legacy/admission.js +0 -8
- package/dist/deployment/release/legacy/assemble.d.ts +0 -5
- package/dist/deployment/release/legacy/assemble.js +0 -20
- package/dist/deployment/release/legacy/index.d.ts +0 -35
- package/dist/deployment/release/legacy/index.js +0 -34
- package/dist/deployment/release/legacy/release.d.ts +0 -12
- package/dist/deployment/release/legacy/release.js +0 -1
- package/dist/deployment/release/legacy/seal.d.ts +0 -10
- package/dist/deployment/release/legacy/seal.js +0 -17
- package/dist/deployment/verify/preflight/artifact.d.ts +0 -6
- package/dist/deployment/verify/preflight/artifact.js +0 -122
- package/dist/deployment/verify/preflight/publication.d.ts +0 -4
- package/dist/deployment/verify/preflight/publication.js +0 -15
- package/dist/deployment/verify/readiness/deployment.d.ts +0 -3
- package/dist/deployment/verify/readiness/deployment.js +0 -143
- package/dist/deployment/verify/readiness/legacy/index.d.ts +0 -2
- package/dist/deployment/verify/readiness/legacy/index.js +0 -2
- package/dist/deployment/verify/readiness/legacy/publication.d.ts +0 -12
- package/dist/deployment/verify/readiness/legacy/publication.js +0 -23
- package/dist/execution/service/errors.d.ts +0 -3
- package/dist/execution/service/errors.js +0 -3
- package/dist/execution/service/serving/legacy/index.d.ts +0 -15
- package/dist/execution/service/serving/legacy/index.js +0 -19
- package/dist/tooling/cli/deprecations.d.ts +0 -9
- package/dist/tooling/cli/deprecations.js +0 -15
- package/dist/tooling/cli/legacy/deploy-result.d.ts +0 -28
- package/dist/tooling/cli/legacy/deploy-result.js +0 -37
- package/dist/tooling/cli/legacy/stable-target-adapter.d.ts +0 -21
- package/dist/tooling/cli/legacy/stable-target-adapter.js +0 -14
- package/dist/tooling/cli/legacy/stable-target-deploy.d.ts +0 -40
- package/dist/tooling/cli/legacy/stable-target-deploy.js +0 -102
- package/dist/tooling/cli/legacy/uploaded-build.d.ts +0 -11
- package/dist/tooling/cli/legacy/uploaded-build.js +0 -22
- package/dist/tooling/linter/implementations/source/migrations.d.ts +0 -2
- package/dist/tooling/linter/implementations/source/migrations.js +0 -113
- package/dist/tooling/linter/qualification/index.d.ts +0 -10
- package/dist/tooling/linter/qualification/index.js +0 -2
- package/dist/tooling/linter/qualification/query-fixtures.d.ts +0 -2
- package/dist/tooling/linter/qualification/query-fixtures.js +0 -68
- package/dist/tooling/linter/qualification/runner.d.ts +0 -3
- package/dist/tooling/linter/qualification/runner.js +0 -6
package/README.md
CHANGED
|
@@ -5,6 +5,11 @@ single-step Actions, explicit multi-step Workflows, provider-neutral Integration
|
|
|
5
5
|
authoring, Domain composition, Deployment, and Execution without exposing DSL callable
|
|
6
6
|
topology in implementation files.
|
|
7
7
|
|
|
8
|
+
This draft moves the Domain name and entrypoint into its root Schema. The source is rebased on
|
|
9
|
+
current SDK main, but the required canonical Kernel Schema contract is not yet published in the
|
|
10
|
+
pinned dependency cohort. See [the migration and qualification boundary](docs/domain-schema-migration.md)
|
|
11
|
+
before using or releasing this branch.
|
|
12
|
+
|
|
8
13
|
[](https://github.com/astrale-os/sdk/actions/workflows/ci.yml)
|
|
9
14
|
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
10
15
|
|
|
@@ -46,31 +51,12 @@ Run the project's checks and validate on development.
|
|
|
46
51
|
Nothing is committed or deployed. A Shell update also requires checking the installed Shell revision.
|
|
47
52
|
Rerunning an upgrade synchronizes installation even when the manifest versions are already current.
|
|
48
53
|
|
|
49
|
-
##
|
|
50
|
-
|
|
51
|
-
A Domain issuer is retained across installation upgrades. To deploy a new Cloudflare runtime for
|
|
52
|
-
selected instances, keep the existing signing identity and issuer while selecting a new public origin:
|
|
53
|
-
|
|
54
|
-
```ts
|
|
55
|
-
cloudflare({
|
|
56
|
-
route: 'services-v2.example.com',
|
|
57
|
-
workerName: 'services-v2',
|
|
58
|
-
identityIssuer: 'https://services.example.com',
|
|
59
|
-
signingIdentity: '.astrale/identity.json',
|
|
60
|
-
})
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
The new Publication places its Bundle, Delivery, callables, Views and routes at the new origin.
|
|
64
|
-
Install that public URL on each intended instance. The Kernel verifies its Delivery against the
|
|
65
|
-
retained issuer's keys and preserves the Domain installation identity and owned data. Keep the
|
|
66
|
-
original issuer discovery endpoints and keys available; unadopted instances continue to use their
|
|
67
|
-
previous bindings. Deployment readiness checks the exact new Worker version separately from issuer
|
|
68
|
-
discovery. No uninstall or identity rotation is involved.
|
|
54
|
+
## Immutable deployments
|
|
69
55
|
|
|
70
|
-
|
|
71
|
-
`
|
|
72
|
-
|
|
73
|
-
|
|
56
|
+
A deployment serves one `DomainRelease` v4 at its immutable URL, which is also its issuer.
|
|
57
|
+
`assemble(build, buildDigest, url)` seals the document from the exact Build and running bytes.
|
|
58
|
+
Cloudflare deployments require a dispatch namespace; `astrale()` hosts them on Admin's Services.
|
|
59
|
+
Install the URL printed by `astrale-domain deploy` on each intended instance.
|
|
74
60
|
|
|
75
61
|
## Handler authority and dependencies
|
|
76
62
|
|
|
@@ -141,11 +127,8 @@ for an Identity in the Domain's local Core. `subject` is the resolved Core Node;
|
|
|
141
127
|
must request at least one capability. The top-level `functions`, `classes`, and `authority` members
|
|
142
128
|
describe capabilities for the Domain principal.
|
|
143
129
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
`CoreRequirementInput`. Builds emit `requirements.capabilities.core`; new releases use Publication
|
|
147
|
-
v3 and require a Kernel that supports it. That Kernel can restore historical v2 Publications and
|
|
148
|
-
installation ledgers without changing their existing authority or integrity evidence.
|
|
130
|
+
Builds emit `requirements.capabilities.core`; the release declares those requirements for the
|
|
131
|
+
Domain principal and local Core identities. Installation verifies the Release and its exact Bundle.
|
|
149
132
|
|
|
150
133
|
### Prerequisites
|
|
151
134
|
|
|
@@ -262,13 +245,12 @@ NodePath and its Dataset Node ID through encoding and decoding. Matching propert
|
|
|
262
245
|
not create that association. Studio uses it when simulating `sameNode` and reference endpoints;
|
|
263
246
|
a missing association makes that simulation unavailable.
|
|
264
247
|
|
|
265
|
-
## Kernel
|
|
248
|
+
## Kernel release discovery
|
|
266
249
|
|
|
267
|
-
Use `session.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
coherent Publication, bundle, and View catalog observation.
|
|
250
|
+
Use `session.release()` for the intrinsic Kernel's Release without its schema bundle or Views.
|
|
251
|
+
It revalidates issuer, URL, size and ETag. Concurrent release and snapshot observations share
|
|
252
|
+
acquisition; cancelling one observer does not cancel another. `session.snapshot()` returns one
|
|
253
|
+
coherent Release, Bundle and View catalog observation.
|
|
272
254
|
|
|
273
255
|
## Headless scripts and Domain callables
|
|
274
256
|
|
|
@@ -366,6 +348,18 @@ recomputes an address tests against them.
|
|
|
366
348
|
|
|
367
349
|
Apache License 2.0 — see [LICENSE](LICENSE) for details.
|
|
368
350
|
|
|
351
|
+
## Domain icon
|
|
352
|
+
|
|
353
|
+
```ts
|
|
354
|
+
import { classIcon } from '@astrale-os/sdk/schema'
|
|
355
|
+
import { Building2 } from '@astrale-os/sdk/schema/icons'
|
|
356
|
+
|
|
357
|
+
export const domain = defineDomain({ schema, runtime, icon: classIcon.lucide(Building2) })
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
The release publishes the icon as `manifest.logo`. Use `classIcon.svg(...)` for a self-contained
|
|
361
|
+
inline SVG, or omit `icon` and the release carries no manifest.
|
|
362
|
+
|
|
369
363
|
## View host requirements
|
|
370
364
|
|
|
371
365
|
A frontend route can declare the exact external origins its View needs to open:
|
|
@@ -383,7 +377,7 @@ routes: {
|
|
|
383
377
|
}
|
|
384
378
|
```
|
|
385
379
|
|
|
386
|
-
These requirements
|
|
380
|
+
These requirements belong to the Release, so changing them updates its digest without
|
|
387
381
|
changing the Domain's business Schema. They require the `shell` handshake. Origins must use
|
|
388
382
|
HTTPS without credentials, paths, queries, fragments, or wildcards; authoring normalizes and sorts
|
|
389
383
|
them. Supporting hosts admit them per mount and execute the existing `browser.openExternal`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { schema } from '../platform/schema/index.js';
|
|
1
|
+
import type { ClassIcon, schema } from '../platform/schema/index.js';
|
|
2
2
|
import type { DomainDefinition } from './domain.js';
|
|
3
3
|
import type { Requirements } from './requirements/index.js';
|
|
4
4
|
import type { Routes } from './routes/index.js';
|
|
@@ -10,6 +10,8 @@ export interface DomainDefinitionInput<Schema extends schema.DomainSchema, Runti
|
|
|
10
10
|
readonly frontend?: FrontendValue;
|
|
11
11
|
readonly routes?: RoutesValue;
|
|
12
12
|
readonly requirements?: RequirementsValue;
|
|
13
|
+
/** The application's icon, made with `classIcon.svg(...)` or `classIcon.lucide(...)`. */
|
|
14
|
+
readonly icon?: ClassIcon;
|
|
13
15
|
}
|
|
14
16
|
/** Capture one inert authored Domain without resolving, compiling, loading, or deploying it. */
|
|
15
17
|
export declare function defineDomain<const Schema extends schema.DomainSchema, const RuntimeValue extends Runtime<Schema>, const FrontendValue extends Frontend<Schema> | undefined = undefined, const RoutesValue extends Routes | undefined = undefined, const RequirementsValue extends Requirements | undefined = undefined>(input: DomainDefinitionInput<Schema, RuntimeValue, FrontendValue, RoutesValue, RequirementsValue>): DomainDefinition<Schema, RuntimeValue, FrontendValue, RoutesValue, RequirementsValue>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { admitClassIconSvg } from '../platform/schema/class-icon-svg.js';
|
|
1
2
|
import { isRequirements } from './requirements/index.js';
|
|
2
3
|
import { isRoutes } from './routes/index.js';
|
|
3
4
|
import { isRuntime } from './runtime/index.js';
|
|
@@ -7,9 +8,19 @@ const admittedDomainDefinitions = new WeakSet();
|
|
|
7
8
|
export function defineDomain(input) {
|
|
8
9
|
if (input === null || typeof input !== 'object' || Array.isArray(input))
|
|
9
10
|
invalid();
|
|
10
|
-
const allowed = new Set([
|
|
11
|
+
const allowed = new Set([
|
|
12
|
+
'schema',
|
|
13
|
+
'runtime',
|
|
14
|
+
'frontend',
|
|
15
|
+
'routes',
|
|
16
|
+
'requirements',
|
|
17
|
+
'icon',
|
|
18
|
+
]);
|
|
11
19
|
if (Reflect.ownKeys(input).some((key) => !allowed.has(key)))
|
|
12
20
|
invalid();
|
|
21
|
+
if (typeof input.schema?.name !== 'string') {
|
|
22
|
+
throw new TypeError(`Domain Schema ${String(input.schema?.origin)} must declare its name: defineSchema(origin, { name, ... }).`);
|
|
23
|
+
}
|
|
13
24
|
if (!isRuntime(input.runtime))
|
|
14
25
|
throw new TypeError('Domain Runtime is not admitted.');
|
|
15
26
|
if (input.frontend !== undefined &&
|
|
@@ -22,12 +33,15 @@ export function defineDomain(input) {
|
|
|
22
33
|
if (input.requirements !== undefined && !isRequirements(input.requirements)) {
|
|
23
34
|
throw new TypeError('Domain requirements are not admitted.');
|
|
24
35
|
}
|
|
36
|
+
// The same admission as a Node Class icon: one self-contained inline SVG.
|
|
37
|
+
const icon = input.icon === undefined ? undefined : admitClassIconSvg(input.icon);
|
|
25
38
|
const domain = Object.freeze({
|
|
26
39
|
schema: input.schema,
|
|
27
40
|
runtime: input.runtime,
|
|
28
41
|
...(input.frontend === undefined ? {} : { frontend: input.frontend }),
|
|
29
42
|
...(input.routes === undefined ? {} : { routes: input.routes }),
|
|
30
43
|
...(input.requirements === undefined ? {} : { requirements: input.requirements }),
|
|
44
|
+
...(icon === undefined ? {} : { icon }),
|
|
31
45
|
});
|
|
32
46
|
admittedDomainDefinitions.add(domain);
|
|
33
47
|
return domain;
|
|
@@ -36,5 +50,5 @@ export function isDomainDefinition(input) {
|
|
|
36
50
|
return input !== null && typeof input === 'object' && admittedDomainDefinitions.has(input);
|
|
37
51
|
}
|
|
38
52
|
function invalid() {
|
|
39
|
-
throw new TypeError('Domain definition may contain only schema, runtime, frontend, routes, and
|
|
53
|
+
throw new TypeError('Domain definition may contain only schema, runtime, frontend, routes, requirements, and icon.');
|
|
40
54
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { schema } from '../platform/schema/index.js';
|
|
1
|
+
import type { ClassIcon, schema } from '../platform/schema/index.js';
|
|
2
2
|
import type { Requirements } from './requirements/index.js';
|
|
3
3
|
import type { Routes } from './routes/index.js';
|
|
4
4
|
import type { Runtime, SchemaOfRuntime as RuntimeSchemaOf } from './runtime/index.js';
|
|
@@ -16,6 +16,8 @@ export interface DomainDefinition<Schema extends schema.DomainSchema = schema.Do
|
|
|
16
16
|
readonly frontend?: FrontendValue;
|
|
17
17
|
readonly routes?: RoutesValue;
|
|
18
18
|
readonly requirements?: RequirementsValue;
|
|
19
|
+
/** The application's icon. */
|
|
20
|
+
readonly icon?: ClassIcon;
|
|
19
21
|
readonly [DOMAIN_DEFINITION_SCHEMA]: (schema: Schema) => Schema;
|
|
20
22
|
}
|
|
21
23
|
export type SchemaOfDomainDefinition<Value> = Value extends {
|
|
@@ -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,
|
|
8
|
+
export type { Frontend, FrontendInput, FrontendSource, ViewHostRequirements } from './view/index.js';
|
|
9
9
|
export type { DomainDefinition, DomainDefinitionIdentity, RuntimeOfDomainDefinition, SchemaOfDomainDefinition, SchemaOfRuntime, } from './domain.js';
|
|
@@ -5,4 +5,4 @@ export type { Mutation, MutationDefinition, MutationInputOf, MutationOutputOf }
|
|
|
5
5
|
export type { CreatedNode, EdgeSelector, ExistingEndpoint, MutationEndpoint, QueryPrecondition, RichMutationBuilder, RichPropertyConditions, RichPropertyDelta, RichPropertyInput, RichPropertyName, } from './authoring/index.js';
|
|
6
6
|
/** Canonical low-level Mutation documents remain available as the explicit escape hatch. */
|
|
7
7
|
export * from '@astrale-os/kernel-core/graph/mutate';
|
|
8
|
-
export type { LocalAlias
|
|
8
|
+
export type { LocalAlias } from '../../platform/graph/alias.js';
|
|
@@ -7,10 +7,6 @@ export declare const QUERY_COMPOSITION_LIMITS: Readonly<{
|
|
|
7
7
|
maximumDependencyDepth: 8;
|
|
8
8
|
}>;
|
|
9
9
|
export interface QueryPlanAnalysis {
|
|
10
|
-
/** @deprecated Use physicalQueries. */
|
|
11
|
-
readonly queries: number;
|
|
12
|
-
/** @deprecated Use dependencyDepth. */
|
|
13
|
-
readonly depth: number;
|
|
14
10
|
readonly logicalQueries: number;
|
|
15
11
|
readonly physicalQueries: number;
|
|
16
12
|
readonly dependencyDepth: number;
|
|
@@ -53,8 +53,6 @@ export function analyzeQueryPlan(plan) {
|
|
|
53
53
|
throw new QueryCompositionError('QUERY_COMPOSITION_LIMIT', `Composite Query exceeds ${QUERY_COMPOSITION_LIMITS.maximumPhysicalQueries} physical Queries or dependency depth ${QUERY_COMPOSITION_LIMITS.maximumDependencyDepth}.`);
|
|
54
54
|
}
|
|
55
55
|
return Object.freeze({
|
|
56
|
-
queries: physicalKeys.size,
|
|
57
|
-
depth: maximumDepth,
|
|
58
56
|
logicalQueries,
|
|
59
57
|
physicalQueries: physicalKeys.size,
|
|
60
58
|
dependencyDepth: maximumDepth,
|
|
@@ -5,7 +5,10 @@ import { isFrontendSource } from './source.js';
|
|
|
5
5
|
export function defineFrontend(input) {
|
|
6
6
|
if (input === null || typeof input !== 'object' || Array.isArray(input))
|
|
7
7
|
invalid();
|
|
8
|
-
if (
|
|
8
|
+
if (Object.hasOwn(input, 'entrypoint')) {
|
|
9
|
+
throw new TypeError('Frontend entrypoint is removed: declare it with defineSchema(origin, { entrypoint }).');
|
|
10
|
+
}
|
|
11
|
+
if (Reflect.ownKeys(input).some((key) => key !== 'schema' && key !== 'source' && key !== 'routes')) {
|
|
9
12
|
invalid();
|
|
10
13
|
}
|
|
11
14
|
const names = Object.keys(input.schema.views).sort(compare);
|
|
@@ -18,10 +21,6 @@ export function defineFrontend(input) {
|
|
|
18
21
|
const unknown = Reflect.ownKeys(authored).find((name) => typeof name !== 'string' || !names.includes(name));
|
|
19
22
|
if (unknown !== undefined)
|
|
20
23
|
throw new TypeError(`Frontend route ${String(unknown)} is unknown.`);
|
|
21
|
-
const entrypoint = input.entrypoint ?? (names.length === 1 ? names[0] : undefined);
|
|
22
|
-
if (entrypoint === undefined || !names.includes(entrypoint)) {
|
|
23
|
-
throw new TypeError('Frontend entrypoint must name one Schema View.');
|
|
24
|
-
}
|
|
25
24
|
const paths = new Set();
|
|
26
25
|
const routes = {};
|
|
27
26
|
for (const name of names) {
|
|
@@ -36,7 +35,6 @@ export function defineFrontend(input) {
|
|
|
36
35
|
schema: input.schema,
|
|
37
36
|
source,
|
|
38
37
|
routes: Object.freeze(routes),
|
|
39
|
-
entrypoint: entrypoint,
|
|
40
38
|
}));
|
|
41
39
|
}
|
|
42
40
|
function admitSource(input) {
|
|
@@ -8,12 +8,12 @@ export interface FrontendInput<Schema extends schema.DomainSchema> {
|
|
|
8
8
|
readonly schema: Schema;
|
|
9
9
|
readonly source: FrontendSource;
|
|
10
10
|
readonly routes?: FrontendRouteInputs<Schema>;
|
|
11
|
-
|
|
11
|
+
/** Removed: the Schema declares its entrypoint with `defineSchema(origin, { entrypoint })`. */
|
|
12
|
+
readonly entrypoint?: never;
|
|
12
13
|
}
|
|
13
14
|
export interface Frontend<Schema extends schema.DomainSchema = schema.DomainSchema> {
|
|
14
15
|
readonly kind: 'frontend';
|
|
15
16
|
readonly schema: Schema;
|
|
16
17
|
readonly source: FrontendSource;
|
|
17
18
|
readonly routes: FrontendRoutes<Schema>;
|
|
18
|
-
readonly entrypoint: ViewName<Schema>;
|
|
19
19
|
}
|
|
@@ -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,
|
|
4
|
+
export type { FrontendHandshake, FrontendRoute, FrontendRouteInput, ViewHostRequirements, } from './route.js';
|
|
5
5
|
export { external, isFrontendSource, vite } from './source.js';
|
|
6
6
|
export type { ExternalSource, FrontendSource, ViteSource } from './source.js';
|
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
import { type ViewHostRequirements } from '@astrale-os/kernel-core/schema/kernel/syscalls/view-resolution';
|
|
2
2
|
export type { ViewHostRequirements } from '@astrale-os/kernel-core/schema/kernel/syscalls/view-resolution';
|
|
3
3
|
export type FrontendHandshake = 'shell' | 'none';
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated Every trusted View receives the Shell's shared browser profile: requirements within
|
|
6
|
-
* it are redundant, and Astrale hosts refuse any beyond it. Declare none.
|
|
7
|
-
*/
|
|
8
|
-
export interface IframeRequirements {
|
|
9
|
-
readonly sandbox?: readonly string[];
|
|
10
|
-
readonly allow?: readonly string[];
|
|
11
|
-
}
|
|
12
4
|
export type FrontendRouteInput = string | {
|
|
13
5
|
readonly path?: string;
|
|
14
6
|
readonly document?: string;
|
|
15
7
|
readonly handshake?: FrontendHandshake;
|
|
16
|
-
/**
|
|
17
|
-
* @deprecated Every trusted View receives the Shell's shared browser profile: requirements
|
|
18
|
-
* within it are redundant, and Astrale hosts refuse any beyond it. Remove this field.
|
|
19
|
-
*/
|
|
20
|
-
readonly iframe?: IframeRequirements;
|
|
21
8
|
readonly host?: ViewHostRequirements;
|
|
22
9
|
};
|
|
23
10
|
export interface FrontendRoute {
|
|
24
11
|
readonly path: string;
|
|
25
12
|
readonly document: string;
|
|
26
13
|
readonly handshake: FrontendHandshake;
|
|
27
|
-
readonly iframe?: IframeRequirements;
|
|
28
14
|
readonly host?: ViewHostRequirements;
|
|
29
15
|
}
|
|
30
16
|
export declare function normalizeRoute(input: FrontendRouteInput | undefined, fallback: string): FrontendRoute;
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { acceptViewHostRequirements, } from '@astrale-os/kernel-core/schema/kernel/syscalls/view-resolution';
|
|
2
|
-
const TOKEN = /^[a-z][a-z0-9-]*$/u;
|
|
3
|
-
const BASELINES = Object.freeze({
|
|
4
|
-
none: iframeRequirements(['allow-scripts'], []),
|
|
5
|
-
shell: iframeRequirements(['allow-same-origin', 'allow-scripts'], ['clipboard-write']),
|
|
6
|
-
});
|
|
7
2
|
export function normalizeRoute(input, fallback) {
|
|
8
3
|
if (typeof input === 'string') {
|
|
9
4
|
return Object.freeze({ path: routePath(input), document: 'index.html', handshake: 'shell' });
|
|
10
5
|
}
|
|
11
6
|
const value = plainRecord(input ?? {});
|
|
12
|
-
if (Reflect.ownKeys(value).some((key) => typeof key !== 'string' ||
|
|
13
|
-
!['path', 'document', 'handshake', 'iframe', 'host'].includes(key))) {
|
|
7
|
+
if (Reflect.ownKeys(value).some((key) => typeof key !== 'string' || !['path', 'document', 'handshake', 'host'].includes(key))) {
|
|
14
8
|
invalid();
|
|
15
9
|
}
|
|
16
10
|
const authoredHandshake = dataValue(value, 'handshake');
|
|
@@ -20,59 +14,14 @@ export function normalizeRoute(input, fallback) {
|
|
|
20
14
|
invalid();
|
|
21
15
|
}
|
|
22
16
|
const handshake = authoredHandshake ?? 'shell';
|
|
23
|
-
const iframe = normalizeIframeRequirements(dataValue(value, 'iframe'), handshake);
|
|
24
17
|
const host = acceptViewHostRequirements(dataValue(value, 'host'), handshake, true);
|
|
25
18
|
return Object.freeze({
|
|
26
19
|
path: routePath(dataValue(value, 'path') ?? fallback),
|
|
27
20
|
document: filePath(dataValue(value, 'document') ?? 'index.html'),
|
|
28
21
|
handshake,
|
|
29
|
-
...(iframe === undefined ? {} : { iframe }),
|
|
30
22
|
...(host === undefined ? {} : { host }),
|
|
31
23
|
});
|
|
32
24
|
}
|
|
33
|
-
function normalizeIframeRequirements(input, handshake) {
|
|
34
|
-
if (input === undefined)
|
|
35
|
-
return undefined;
|
|
36
|
-
const value = plainRecord(input);
|
|
37
|
-
if (Reflect.ownKeys(value).some((key) => key !== 'sandbox' && key !== 'allow'))
|
|
38
|
-
invalid();
|
|
39
|
-
const authored = iframeRequirements(tokenArray(dataValue(value, 'sandbox')), tokenArray(dataValue(value, 'allow')));
|
|
40
|
-
assertSandboxRelationships(authored.sandbox);
|
|
41
|
-
const baseline = BASELINES[handshake];
|
|
42
|
-
const sandbox = authored.sandbox.filter((token) => !baseline.sandbox.includes(token));
|
|
43
|
-
const allow = authored.allow.filter((feature) => !baseline.allow.includes(feature));
|
|
44
|
-
return sandbox.length === 0 && allow.length === 0 ? undefined : iframeRequirements(sandbox, allow);
|
|
45
|
-
}
|
|
46
|
-
function iframeRequirements(sandbox, allow) {
|
|
47
|
-
return Object.freeze({
|
|
48
|
-
sandbox: Object.freeze([...new Set(sandbox)].sort()),
|
|
49
|
-
allow: Object.freeze([...new Set(allow)].sort()),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
function tokenArray(input) {
|
|
53
|
-
if (input === undefined)
|
|
54
|
-
return [];
|
|
55
|
-
if (!Array.isArray(input))
|
|
56
|
-
invalid();
|
|
57
|
-
const descriptors = Object.getOwnPropertyDescriptors(input);
|
|
58
|
-
const result = [];
|
|
59
|
-
for (let index = 0; index < input.length; index += 1) {
|
|
60
|
-
const descriptor = descriptors[String(index)];
|
|
61
|
-
if (descriptor === undefined || !('value' in descriptor))
|
|
62
|
-
invalid();
|
|
63
|
-
if (typeof descriptor.value !== 'string' || !TOKEN.test(descriptor.value))
|
|
64
|
-
invalid();
|
|
65
|
-
result.push(descriptor.value);
|
|
66
|
-
}
|
|
67
|
-
for (const key of Reflect.ownKeys(descriptors)) {
|
|
68
|
-
if (key === 'length')
|
|
69
|
-
continue;
|
|
70
|
-
if (typeof key !== 'string' || !/^(0|[1-9][0-9]*)$/u.test(key) || Number(key) >= input.length) {
|
|
71
|
-
invalid();
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
25
|
function plainRecord(input) {
|
|
77
26
|
if (typeof input !== 'object' || input === null || Array.isArray(input))
|
|
78
27
|
invalid();
|
|
@@ -89,18 +38,6 @@ function dataValue(input, key) {
|
|
|
89
38
|
invalid();
|
|
90
39
|
return descriptor.value;
|
|
91
40
|
}
|
|
92
|
-
function assertSandboxRelationships(sandbox) {
|
|
93
|
-
const tokens = new Set(sandbox);
|
|
94
|
-
if (tokens.has('allow-popups-to-escape-sandbox') && !tokens.has('allow-popups'))
|
|
95
|
-
invalid();
|
|
96
|
-
if (tokens.has('allow-top-navigation') && tokens.has('allow-top-navigation-by-user-activation')) {
|
|
97
|
-
invalid();
|
|
98
|
-
}
|
|
99
|
-
if (tokens.has('allow-top-navigation-to-custom-protocols') &&
|
|
100
|
-
(tokens.has('allow-top-navigation') || tokens.has('allow-popups'))) {
|
|
101
|
-
invalid();
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
41
|
export function defaultRoute(name) {
|
|
105
42
|
return routePath(`/${name
|
|
106
43
|
.replace(/([a-z0-9])([A-Z])/gu, '$1-$2')
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DeploymentConfiguration } from '../address/index.js';
|
|
2
2
|
import type { Bundler } from './bundle/index.js';
|
|
3
|
-
import type { ArtifactSource, DeployContext, DeployResult, PrepareContext } from './legacy/index.js';
|
|
4
3
|
import type { AdapterCommand, ConfigureContext, ListContext, ListedDeployment, Placement, PlacementContext, ReleaseDeployContext, ReleaseDeployResult, RetainContext } from './release/index.js';
|
|
5
4
|
/** What `admit` receives when `defineProject` binds an adapter to one Environment. */
|
|
6
5
|
export interface AdapterEnvironmentContext {
|
|
@@ -12,8 +11,6 @@ export interface AdapterEnvironmentContext {
|
|
|
12
11
|
* deploys one sealed release as one immutable deployment, created or reused. It never installs:
|
|
13
12
|
* `astrale domain install <url>` installs a deployment by its URL.
|
|
14
13
|
*
|
|
15
|
-
* `prepare` and `deploy` remain only for an adapter that also serves Environments on the legacy
|
|
16
|
-
* direct-mode path (CT33); an adapter declares both or neither.
|
|
17
14
|
*/
|
|
18
15
|
export interface Adapter<Parameters extends object = object> {
|
|
19
16
|
readonly kind: 'adapter';
|
|
@@ -26,8 +23,12 @@ export interface Adapter<Parameters extends object = object> {
|
|
|
26
23
|
readonly bundler: Bundler;
|
|
27
24
|
/** Refuse parameters that cannot serve this Environment, before any effect. */
|
|
28
25
|
admit?(parameters: Parameters, context: AdapterEnvironmentContext): void;
|
|
29
|
-
/**
|
|
30
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Freeze what a deployment of this Environment binds beside its build: a `FrozenConfigurationV1`
|
|
28
|
+
* for a host that binds a generated Worker's settings itself, a `WorkerConfigurationV1` for a
|
|
29
|
+
* Worker host that binds only what it is asked (Admin's Services). Pure.
|
|
30
|
+
*/
|
|
31
|
+
configure(parameters: Parameters, context: ConfigureContext): DeploymentConfiguration;
|
|
31
32
|
/** Where the host places this Environment's deployments. No effect at the host. */
|
|
32
33
|
placement(parameters: Parameters, context: PlacementContext): Promise<Placement>;
|
|
33
34
|
/** Create, or reuse, the immutable deployment of one sealed release. */
|
|
@@ -39,7 +40,7 @@ export interface Adapter<Parameters extends object = object> {
|
|
|
39
40
|
list?(parameters: Parameters, context: ListContext): Promise<readonly ListedDeployment[]>;
|
|
40
41
|
/**
|
|
41
42
|
* Keep one published deployment where the host has no registry principal to mark it (a platform
|
|
42
|
-
* namespace). Called only after its
|
|
43
|
+
* namespace). Called only after its registry publication commits. Rejects with a `RetainRefusal` when the
|
|
43
44
|
* host can no longer keep it (absent or retired), which no rerun changes; any other rejection is
|
|
44
45
|
* transient. Absent: the registry marks it (Admin's Services).
|
|
45
46
|
*/
|
|
@@ -50,17 +51,7 @@ export interface Adapter<Parameters extends object = object> {
|
|
|
50
51
|
* host on the operator's own account). Every effect is the adapter's; the CLI only routes.
|
|
51
52
|
*/
|
|
52
53
|
readonly commands?: Readonly<Record<string, AdapterCommand<Parameters>>>;
|
|
53
|
-
|
|
54
|
-
* @deprecated Legacy direct-mode path (CT33) only: place a build at a stable target. Replacement:
|
|
55
|
-
* `bundler`, `configure` and `placement`. Deleted with the legacy path (D10).
|
|
56
|
-
*/
|
|
57
|
-
prepare?(parameters: Parameters, context: PrepareContext): Promise<ArtifactSource>;
|
|
58
|
-
/**
|
|
59
|
-
* @deprecated Legacy direct-mode path (CT33) only: replace a stable target's code in place.
|
|
60
|
-
* Replacement: `deployRelease`. Deleted with the legacy path (D10).
|
|
61
|
-
*/
|
|
62
|
-
deploy?(parameters: Parameters, context: DeployContext): Promise<DeployResult>;
|
|
63
|
-
readonly secretsFile?: (parameters: Parameters) => string | undefined;
|
|
54
|
+
secretsFile?(parameters: Parameters): string | undefined;
|
|
64
55
|
}
|
|
65
56
|
/** What `defineAdapter` admits for an `Adapter` (adapter interface v2). */
|
|
66
57
|
export interface AdapterInput<Parameters extends object> {
|
|
@@ -68,15 +59,11 @@ export interface AdapterInput<Parameters extends object> {
|
|
|
68
59
|
readonly version: string;
|
|
69
60
|
readonly bundler: Bundler;
|
|
70
61
|
admit?(parameters: Parameters, context: AdapterEnvironmentContext): void;
|
|
71
|
-
configure(parameters: Parameters, context: ConfigureContext):
|
|
62
|
+
configure(parameters: Parameters, context: ConfigureContext): DeploymentConfiguration;
|
|
72
63
|
placement(parameters: Parameters, context: PlacementContext): Promise<Placement>;
|
|
73
64
|
deployRelease(parameters: Parameters, context: ReleaseDeployContext): Promise<ReleaseDeployResult>;
|
|
74
65
|
list?(parameters: Parameters, context: ListContext): Promise<readonly ListedDeployment[]>;
|
|
75
66
|
retain?(parameters: Parameters, context: RetainContext): Promise<void>;
|
|
76
67
|
readonly commands?: Readonly<Record<string, AdapterCommand<Parameters>>>;
|
|
77
|
-
|
|
78
|
-
prepare?(parameters: Parameters, context: PrepareContext): Promise<ArtifactSource>;
|
|
79
|
-
/** @deprecated Legacy direct-mode path (CT33) only. Replacement: `deployRelease`. */
|
|
80
|
-
deploy?(parameters: Parameters, context: DeployContext): Promise<DeployResult>;
|
|
81
|
-
readonly secretsFile?: (parameters: Parameters) => string | undefined;
|
|
68
|
+
secretsFile?(parameters: Parameters): string | undefined;
|
|
82
69
|
}
|
|
@@ -1,29 +1,8 @@
|
|
|
1
1
|
import type { Deployment } from '../deployment.js';
|
|
2
2
|
import type { Adapter, AdapterInput } from './adapter.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Capture one receiver-bound provider adapter (adapter interface v2): a required `bundler`,
|
|
6
|
-
* `configure`, `placement` and `deployRelease`, optionally `list`, `retain` and provider `commands`, and `prepare` with
|
|
7
|
-
* `deploy` only while it also serves the legacy direct-mode path.
|
|
8
|
-
*/
|
|
3
|
+
/** Capture one receiver-bound adapter that deploys immutable DomainRelease v4 deployments. */
|
|
9
4
|
export declare function defineAdapter<Parameters extends object>(input: AdapterInput<Parameters>): Adapter<Parameters>;
|
|
10
|
-
/**
|
|
11
|
-
* Capture one receiver-bound adapter on the contract before interface v2: its required `bundler`,
|
|
12
|
-
* `prepare` and `deploy`.
|
|
13
|
-
*
|
|
14
|
-
* @deprecated Every Environment such an adapter deploys is on the legacy direct-mode path (CT33).
|
|
15
|
-
* Declare adapter interface v2 instead: `configure`, `placement` and `deployRelease` beside the
|
|
16
|
-
* same `bundler`.
|
|
17
|
-
*/
|
|
18
|
-
export declare function defineAdapter<Parameters extends object>(input: LegacyAdapterInput<Parameters>): LegacyAdapter<Parameters>;
|
|
19
|
-
/** Bind one provider adapter to the parameters of one Project Environment. */
|
|
5
|
+
/** Bind one admitted adapter to the parameters of one Project Environment. */
|
|
20
6
|
export declare function defineDeployment<const Parameters extends object>(adapter: Adapter<Parameters>, parameters: Parameters): Deployment<Parameters, Adapter<Parameters>>;
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
*
|
|
24
|
-
* @deprecated The Environment is on the legacy direct-mode path (CT33). Replacement: an adapter
|
|
25
|
-
* that implements adapter interface v2.
|
|
26
|
-
*/
|
|
27
|
-
export declare function defineDeployment<const Parameters extends object>(adapter: LegacyAdapter<Parameters>, parameters: Parameters): Deployment<Parameters, LegacyAdapter<Parameters>>;
|
|
28
|
-
/** Whether `defineAdapter` admitted this value, on either contract. */
|
|
29
|
-
export declare function isAdapter(input: unknown): input is Adapter | LegacyAdapter;
|
|
7
|
+
/** Whether defineAdapter admitted this immutable-deployment adapter. */
|
|
8
|
+
export declare function isAdapter(input: unknown): input is Adapter;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { captureDeployment } from '../deployment.js';
|
|
2
2
|
const admittedAdapters = new WeakSet();
|
|
3
3
|
const admittedBundlers = new WeakMap();
|
|
4
|
-
/** Every field an adapter
|
|
4
|
+
/** Every field an immutable-deployment adapter may declare. */
|
|
5
5
|
const FIELDS = [
|
|
6
6
|
'name',
|
|
7
7
|
'version',
|
|
@@ -13,46 +13,29 @@ const FIELDS = [
|
|
|
13
13
|
'list',
|
|
14
14
|
'retain',
|
|
15
15
|
'commands',
|
|
16
|
-
'prepare',
|
|
17
|
-
'deploy',
|
|
18
16
|
'secretsFile',
|
|
19
17
|
];
|
|
20
|
-
/** The operations that make a definition adapter interface v2. */
|
|
21
18
|
const RELEASE_OPERATIONS = ['configure', 'placement', 'deployRelease'];
|
|
22
|
-
const
|
|
23
|
-
/** The operations of the legacy direct-mode path. */
|
|
24
|
-
const STABLE_TARGET_OPERATIONS = ['prepare', 'deploy'];
|
|
25
|
-
/** Every operation an adapter may declare, in the order an admitted adapter lists them. */
|
|
26
|
-
const OPERATIONS = FIELDS.filter((key) => key !== 'name' && key !== 'version' && key !== 'bundler' && key !== 'commands');
|
|
27
|
-
/** A provider command name, `astrale-domain <adapter> <command>`, and an option name. */
|
|
19
|
+
const OPERATIONS = ['admit', ...RELEASE_OPERATIONS, 'list', 'retain', 'secretsFile'];
|
|
28
20
|
const COMMAND_NAME = /^[a-z][a-z0-9-]{0,31}$/u;
|
|
21
|
+
/** Capture one receiver-bound adapter that deploys immutable DomainRelease v4 deployments. */
|
|
29
22
|
export function defineAdapter(input) {
|
|
30
23
|
const value = record(input, 'Adapter definition');
|
|
31
24
|
if (Reflect.ownKeys(value).some((key) => !FIELDS.includes(key))) {
|
|
32
25
|
invalidFields();
|
|
33
26
|
}
|
|
34
|
-
const declared = (key) => value[key] !== undefined;
|
|
35
|
-
const release = [...RELEASE_OPERATIONS, ...OPTIONAL_RELEASE_OPERATIONS].some(declared);
|
|
36
|
-
// A legacy definition names both operations, as it always had to; v2 treats undefined as absent.
|
|
37
|
-
const stableTarget = STABLE_TARGET_OPERATIONS.filter((key) => release ? declared(key) : Object.hasOwn(value, key));
|
|
38
|
-
if (!release && stableTarget.length !== STABLE_TARGET_OPERATIONS.length)
|
|
39
|
-
invalidFields();
|
|
40
27
|
const name = stableName(input.name);
|
|
41
28
|
const version = stableName(input.version);
|
|
42
|
-
|
|
43
|
-
|
|
29
|
+
const missing = RELEASE_OPERATIONS.filter((key) => value[key] === undefined);
|
|
30
|
+
if (missing.length > 0) {
|
|
31
|
+
throw new TypeError(`Adapter ${name} must declare ${missing.join(', ')} to deploy immutable releases.`);
|
|
32
|
+
}
|
|
44
33
|
if (value.bundler === undefined)
|
|
45
34
|
missingBundler(name);
|
|
46
35
|
const bundler = admitBundler(input.bundler);
|
|
47
36
|
const receiver = Object.freeze({ ...input });
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
key,
|
|
51
|
-
capture(receiver, key),
|
|
52
|
-
]));
|
|
53
|
-
if (value.commands !== undefined && !release) {
|
|
54
|
-
throw new TypeError(`Adapter ${name} declares commands without adapter interface v2.`);
|
|
55
|
-
}
|
|
37
|
+
const operations = Object.fromEntries(OPERATIONS.filter((key) => RELEASE_OPERATIONS.includes(key) ||
|
|
38
|
+
value[key] !== undefined).map((key) => [key, capture(receiver, key)]));
|
|
56
39
|
const adapter = Object.freeze({
|
|
57
40
|
kind: 'adapter',
|
|
58
41
|
name,
|
|
@@ -64,22 +47,7 @@ export function defineAdapter(input) {
|
|
|
64
47
|
admittedAdapters.add(adapter);
|
|
65
48
|
return adapter;
|
|
66
49
|
}
|
|
67
|
-
/**
|
|
68
|
-
* An adapter interface v2 definition implements configure, placement and deployRelease, and keeps
|
|
69
|
-
* prepare with deploy, or neither.
|
|
70
|
-
*/
|
|
71
|
-
function admitRelease(name, value, stableTargetOperations) {
|
|
72
|
-
const missing = RELEASE_OPERATIONS.filter((key) => value[key] === undefined);
|
|
73
|
-
if (missing.length > 0) {
|
|
74
|
-
throw new TypeError(`Adapter ${name} declares part of adapter interface v2 without ${missing.join(', ')}: ` +
|
|
75
|
-
'an adapter that deploys immutable deployments implements configure, placement and ' +
|
|
76
|
-
'deployRelease.');
|
|
77
|
-
}
|
|
78
|
-
if (stableTargetOperations === 1) {
|
|
79
|
-
throw new TypeError(`Adapter ${name} declares only one of prepare and deploy: an adapter that keeps the legacy ` +
|
|
80
|
-
'direct-mode path declares both.');
|
|
81
|
-
}
|
|
82
|
-
}
|
|
50
|
+
/** Bind one admitted adapter to the parameters of one Project Environment. */
|
|
83
51
|
export function defineDeployment(adapter, parameters) {
|
|
84
52
|
if (!isAdapter(adapter))
|
|
85
53
|
throw new TypeError('Deployment Adapter is not admitted.');
|
|
@@ -88,7 +56,7 @@ export function defineDeployment(adapter, parameters) {
|
|
|
88
56
|
}
|
|
89
57
|
return captureDeployment(adapter, Object.freeze({ ...parameters }));
|
|
90
58
|
}
|
|
91
|
-
/** Whether
|
|
59
|
+
/** Whether defineAdapter admitted this immutable-deployment adapter. */
|
|
92
60
|
export function isAdapter(input) {
|
|
93
61
|
return input !== null && typeof input === 'object' && admittedAdapters.has(input);
|
|
94
62
|
}
|
|
@@ -130,7 +98,7 @@ function record(input, label) {
|
|
|
130
98
|
}
|
|
131
99
|
return input;
|
|
132
100
|
}
|
|
133
|
-
/** Every adapter
|
|
101
|
+
/** Every adapter declares the bundler of the bytes it deploys. */
|
|
134
102
|
function missingBundler(name) {
|
|
135
103
|
throw new TypeError(`Adapter ${name} declares no bundler. ` +
|
|
136
104
|
'Every adapter declares `bundler`: the bundler of the environment-free bytes ' +
|