@astrale-os/sdk 0.6.0-beta.13 → 0.6.0-beta.15
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 +4 -0
- package/dist/deployment/adapter/adapter.d.ts +9 -11
- package/dist/deployment/adapter/legacy/adapter.d.ts +0 -10
- package/dist/deployment/adapter/legacy/deploy/context.d.ts +0 -2
- package/dist/deployment/adapter/legacy/deploy/result.d.ts +2 -3
- package/dist/deployment/adapter/legacy/index.d.ts +12 -12
- package/dist/deployment/adapter/legacy/prepare/context.d.ts +0 -2
- package/dist/deployment/adapter/release/context.d.ts +23 -3
- package/dist/deployment/adapter/release/index.d.ts +1 -0
- package/dist/deployment/adapter/release/list.d.ts +41 -0
- package/dist/deployment/adapter/release/list.js +1 -0
- package/dist/deployment/address/index.d.ts +1 -1
- package/dist/deployment/address/index.js +1 -0
- package/dist/deployment/address/summary.d.ts +31 -1
- package/dist/deployment/address/summary.js +117 -1
- package/dist/deployment/build/index.d.ts +1 -1
- package/dist/deployment/build/index.js +1 -1
- package/dist/deployment/build/manifest.d.ts +5 -0
- package/dist/deployment/build/manifest.js +10 -0
- package/dist/deployment/index.d.ts +1 -1
- package/dist/deployment/release/legacy/index.d.ts +17 -12
- package/dist/deployment/release/legacy/index.js +17 -12
- package/dist/deployment/verify/readiness/deployment.js +3 -13
- package/dist/deployment/verify/readiness/fetch.d.ts +13 -0
- package/dist/deployment/verify/readiness/fetch.js +26 -0
- package/dist/deployment/verify/readiness/identity.d.ts +3 -6
- package/dist/deployment/verify/readiness/identity.js +3 -3
- package/dist/deployment/verify/readiness/index.d.ts +12 -8
- package/dist/deployment/verify/readiness/index.js +15 -4
- package/dist/deployment/verify/readiness/legacy/index.d.ts +2 -0
- package/dist/deployment/verify/readiness/legacy/index.js +2 -0
- package/dist/deployment/verify/readiness/legacy/publication.d.ts +12 -0
- package/dist/deployment/verify/readiness/legacy/publication.js +23 -0
- package/dist/deployment/verify/readiness/release.d.ts +8 -0
- package/dist/deployment/verify/readiness/release.js +22 -0
- package/dist/execution/identity/authentication.d.ts +14 -3
- package/dist/execution/identity/authentication.js +16 -7
- package/dist/execution/identity/callback.d.ts +5 -2
- package/dist/execution/identity/callback.js +11 -5
- package/dist/execution/identity/delivery.d.ts +11 -4
- package/dist/execution/identity/delivery.js +47 -20
- package/dist/execution/identity/identity.d.ts +12 -6
- package/dist/execution/identity/identity.js +3 -3
- package/dist/execution/invocation/admission/authentication.d.ts +1 -2
- package/dist/execution/invocation/admission/authentication.js +1 -2
- package/dist/execution/invocation/admission/authority.d.ts +10 -4
- package/dist/execution/invocation/admission/authority.js +5 -1
- package/dist/execution/invocation/invocation.js +51 -14
- package/dist/execution/runtime/index.d.ts +1 -0
- package/dist/execution/runtime/index.js +1 -0
- package/dist/execution/runtime/load.d.ts +3 -3
- package/dist/execution/runtime/load.js +3 -2
- package/dist/execution/runtime/release.d.ts +22 -0
- package/dist/execution/runtime/release.js +14 -0
- package/dist/execution/serve.d.ts +2 -2
- package/dist/execution/service/create.js +9 -7
- package/dist/execution/service/release.d.ts +2 -2
- package/dist/execution/service/release.js +3 -2
- package/dist/execution/service/service.d.ts +9 -5
- package/dist/execution/service/serving/delivery.d.ts +6 -0
- package/dist/execution/service/{publication → serving}/delivery.js +5 -1
- package/dist/execution/service/{publication → serving}/index.d.ts +1 -1
- package/dist/execution/service/serving/installation.d.ts +4 -0
- package/dist/execution/service/serving/installation.js +9 -0
- package/dist/execution/service/serving/legacy/index.d.ts +15 -0
- package/dist/execution/service/serving/legacy/index.js +19 -0
- package/dist/execution/service/serving/source.d.ts +18 -0
- package/dist/execution/service/serving/source.js +19 -0
- package/dist/execution/workflows/run.js +1 -1
- package/dist/platform/versioning/name.d.ts +4 -3
- package/dist/platform/versioning/name.js +4 -3
- package/dist/project/define.js +58 -28
- package/dist/project/install-command.d.ts +10 -0
- package/dist/project/install-command.js +13 -0
- package/dist/project/project.d.ts +4 -2
- package/dist/tooling/cli/arguments.d.ts +1 -3
- package/dist/tooling/cli/arguments.js +51 -22
- package/dist/tooling/cli/commit.d.ts +23 -0
- package/dist/tooling/cli/commit.js +216 -0
- package/dist/tooling/cli/deploy-mode.d.ts +16 -13
- package/dist/tooling/cli/deploy-mode.js +45 -36
- package/dist/tooling/cli/deploy-result.d.ts +10 -7
- package/dist/tooling/cli/deploy-result.js +4 -3
- package/dist/tooling/cli/dotenv.d.ts +2 -2
- package/dist/tooling/cli/dotenv.js +3 -33
- package/dist/tooling/cli/help.js +73 -29
- package/dist/tooling/cli/immutable-deployment.d.ts +27 -0
- package/dist/tooling/cli/immutable-deployment.js +95 -0
- package/dist/tooling/cli/index.d.ts +3 -4
- package/dist/tooling/cli/index.js +2 -3
- package/dist/tooling/cli/legacy/deploy-result.d.ts +5 -3
- package/dist/tooling/cli/legacy/deploy-result.js +5 -3
- package/dist/tooling/cli/{development → legacy/development}/candidate.d.ts +3 -4
- package/dist/tooling/cli/{development → legacy/development}/candidate.js +7 -14
- package/dist/tooling/cli/legacy/development/deployment.d.ts +10 -0
- package/dist/tooling/cli/legacy/development/deployment.js +20 -0
- package/dist/tooling/cli/legacy/development/deprecation.d.ts +11 -0
- package/dist/tooling/cli/legacy/development/deprecation.js +13 -0
- package/dist/tooling/cli/legacy/development/develop.d.ts +15 -0
- package/dist/tooling/cli/legacy/development/develop.js +142 -0
- package/dist/tooling/cli/legacy/development/index.d.ts +21 -0
- package/dist/tooling/cli/legacy/development/index.js +21 -0
- package/dist/tooling/cli/legacy/development/report.d.ts +7 -0
- package/dist/tooling/cli/{development → legacy/development}/report.js +2 -5
- package/dist/tooling/cli/legacy/development/secrets-file.d.ts +2 -0
- package/dist/tooling/cli/legacy/development/secrets-file.js +33 -0
- package/dist/tooling/cli/legacy/stable-target-adapter.d.ts +5 -3
- package/dist/tooling/cli/legacy/stable-target-deploy.d.ts +40 -0
- package/dist/tooling/cli/legacy/stable-target-deploy.js +102 -0
- package/dist/tooling/cli/list.d.ts +114 -0
- package/dist/tooling/cli/list.js +297 -0
- package/dist/tooling/cli/orchestrate.d.ts +1 -1
- package/dist/tooling/cli/orchestrate.js +91 -95
- package/dist/tooling/cli/secrets.d.ts +9 -0
- package/dist/tooling/cli/secrets.js +19 -0
- package/package.json +7 -7
- package/dist/deployment/verify/readiness/publication.d.ts +0 -11
- package/dist/deployment/verify/readiness/publication.js +0 -41
- package/dist/execution/service/publication/delivery.d.ts +0 -2
- package/dist/execution/service/publication/installation.d.ts +0 -3
- package/dist/execution/service/publication/installation.js +0 -8
- package/dist/execution/service/publication/source.d.ts +0 -3
- package/dist/execution/service/publication/source.js +0 -11
- package/dist/tooling/cli/astrale/authority.d.ts +0 -5
- package/dist/tooling/cli/astrale/authority.js +0 -11
- package/dist/tooling/cli/astrale/executable.d.ts +0 -2
- package/dist/tooling/cli/astrale/executable.js +0 -47
- package/dist/tooling/cli/astrale/failure.d.ts +0 -6
- package/dist/tooling/cli/astrale/failure.js +0 -48
- package/dist/tooling/cli/astrale/instance.d.ts +0 -11
- package/dist/tooling/cli/astrale/instance.js +0 -52
- package/dist/tooling/cli/astrale/process.d.ts +0 -13
- package/dist/tooling/cli/astrale/process.js +0 -94
- package/dist/tooling/cli/astrale/version.d.ts +0 -18
- package/dist/tooling/cli/astrale/version.js +0 -55
- package/dist/tooling/cli/development/deployment.d.ts +0 -16
- package/dist/tooling/cli/development/deployment.js +0 -39
- package/dist/tooling/cli/development/develop.d.ts +0 -11
- package/dist/tooling/cli/development/develop.js +0 -243
- package/dist/tooling/cli/development/release-evidence.d.ts +0 -4
- package/dist/tooling/cli/development/release-evidence.js +0 -10
- package/dist/tooling/cli/development/report.d.ts +0 -9
- package/dist/tooling/cli/development/session-file.d.ts +0 -53
- package/dist/tooling/cli/development/session-file.js +0 -337
- package/dist/tooling/cli/development/target-lock.d.ts +0 -16
- package/dist/tooling/cli/development/target-lock.js +0 -68
- package/dist/tooling/cli/development/view.d.ts +0 -28
- package/dist/tooling/cli/development/view.js +0 -151
- package/dist/tooling/cli/environment-release.d.ts +0 -24
- package/dist/tooling/cli/environment-release.js +0 -46
- package/dist/tooling/cli/evidence.d.ts +0 -14
- package/dist/tooling/cli/evidence.js +0 -53
- package/dist/tooling/cli/installation/index.d.ts +0 -2
- package/dist/tooling/cli/installation/index.js +0 -1
- package/dist/tooling/cli/installation/observation.d.ts +0 -10
- package/dist/tooling/cli/installation/observation.js +0 -44
- package/dist/tooling/cli/installation/reconcile.d.ts +0 -32
- package/dist/tooling/cli/installation/reconcile.js +0 -122
- /package/dist/execution/service/{publication → serving}/index.js +0 -0
- /package/dist/tooling/cli/{credential.d.ts → legacy/development/credential.d.ts} +0 -0
- /package/dist/tooling/cli/{credential.js → legacy/development/credential.js} +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lease.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lease.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lifecycle.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lifecycle.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-imports.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-imports.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-lock.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-lock.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/rebuild.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/rebuild.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/source-watch.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/source-watch.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/sources.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/sources.js +0 -0
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import * as publication from '@astrale-os/kernel-protocol/release/legacy';
|
|
2
|
-
const MAXIMUM_PUBLICATION_BYTES = 1024 * 1024;
|
|
3
|
-
const MAXIMUM_BUNDLE_BYTES = 16 * 1024 * 1024;
|
|
4
|
-
/** Fetch and verify the exact live Publication and Bundle for one Release. */
|
|
5
|
-
export async function verifyPublication(release, options = {}) {
|
|
6
|
-
const fetcher = options.fetch ?? globalThis.fetch;
|
|
7
|
-
const publicationUrl = publication.url(release.addressing.publicUrl);
|
|
8
|
-
const response = await fetchRequired(fetcher, publicationUrl, options.signal);
|
|
9
|
-
const deployed = publication.accept(JSON.parse(await text(response, publicationUrl, MAXIMUM_PUBLICATION_BYTES)));
|
|
10
|
-
if (!publication.matchesReference(deployed, publication.reference(release.publication))) {
|
|
11
|
-
throw new Error('Live Publication differs from the expected Release.');
|
|
12
|
-
}
|
|
13
|
-
const bundleResponse = await fetchRequired(fetcher, deployed.schema.bundle.href, options.signal);
|
|
14
|
-
const bytes = new Uint8Array(await bounded(bundleResponse, deployed.schema.bundle.href, MAXIMUM_BUNDLE_BYTES));
|
|
15
|
-
publication.decodeBundle(deployed, bytes);
|
|
16
|
-
return deployed;
|
|
17
|
-
}
|
|
18
|
-
async function fetchRequired(fetcher, url, signal) {
|
|
19
|
-
const response = await fetcher(url, {
|
|
20
|
-
redirect: 'error',
|
|
21
|
-
...(signal === undefined ? {} : { signal }),
|
|
22
|
-
});
|
|
23
|
-
if (!response.ok)
|
|
24
|
-
throw new Error(`GET ${url} returned ${response.status}.`);
|
|
25
|
-
return response;
|
|
26
|
-
}
|
|
27
|
-
async function bounded(response, url, maximum) {
|
|
28
|
-
const bytes = await response.arrayBuffer();
|
|
29
|
-
if (bytes.byteLength > maximum)
|
|
30
|
-
throw new Error(`GET ${url} exceeded ${maximum} bytes.`);
|
|
31
|
-
return bytes;
|
|
32
|
-
}
|
|
33
|
-
async function text(response, url, maximum) {
|
|
34
|
-
const bytes = await bounded(response, url, maximum);
|
|
35
|
-
try {
|
|
36
|
-
return new TextDecoder('utf-8', { fatal: true, ignoreBOM: false }).decode(bytes);
|
|
37
|
-
}
|
|
38
|
-
catch (cause) {
|
|
39
|
-
throw new Error(`GET ${url} returned invalid UTF-8.`, { cause });
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export function installation(release, provider) {
|
|
2
|
-
const advertised = release.publication.delivery !== undefined;
|
|
3
|
-
if (advertised !== (provider !== undefined)) {
|
|
4
|
-
throw new TypeError(advertised
|
|
5
|
-
? 'Release advertises Publication delivery without a Provider.'
|
|
6
|
-
: 'Publication delivery Provider has no Release endpoint.');
|
|
7
|
-
}
|
|
8
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { preparePublicationSnapshot } from '@astrale-os/kernel-server';
|
|
2
|
-
export function source(runtime) {
|
|
3
|
-
const release = runtime.release;
|
|
4
|
-
const snapshot = preparePublicationSnapshot({
|
|
5
|
-
publication: release.publication,
|
|
6
|
-
bundle: release.build.schema.bundle.bytes(),
|
|
7
|
-
table: release.routes,
|
|
8
|
-
domain: runtime.domain,
|
|
9
|
-
});
|
|
10
|
-
return Object.freeze({ current: () => snapshot });
|
|
11
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/** Build one mutually exclusive authority argument set for an Astrale CLI operation. */
|
|
2
|
-
export function astraleAuthorityArguments(input) {
|
|
3
|
-
if (input.identity !== undefined && input.credential !== undefined) {
|
|
4
|
-
throw new TypeError('Astrale authority cannot combine an identity and a credential.');
|
|
5
|
-
}
|
|
6
|
-
return input.credential === undefined
|
|
7
|
-
? input.identity === undefined
|
|
8
|
-
? Object.freeze([])
|
|
9
|
-
: Object.freeze(['--as', input.identity])
|
|
10
|
-
: Object.freeze(['--creds', input.credential]);
|
|
11
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { constants } from 'node:fs';
|
|
2
|
-
import { access, readFile, realpath } from 'node:fs/promises';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
|
-
import { delimiter, isAbsolute, join } from 'node:path';
|
|
5
|
-
/** Resolve one exact executable for a complete sequence of Kernel CLI operations. */
|
|
6
|
-
export async function resolveAstraleExecutable(input = 'astrale') {
|
|
7
|
-
const candidates = isAbsolute(input) ? [input] : await executableCandidates(input);
|
|
8
|
-
for (const candidate of candidates) {
|
|
9
|
-
try {
|
|
10
|
-
await access(candidate, constants.X_OK);
|
|
11
|
-
return await realpath(candidate);
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
// Continue through the bounded recorded-install and PATH candidates.
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
throw new TypeError('Astrale CLI is unavailable. Install it with the official Astrale installer.');
|
|
18
|
-
}
|
|
19
|
-
async function executableCandidates(input) {
|
|
20
|
-
const path = (process.env.PATH ?? '')
|
|
21
|
-
.split(delimiter)
|
|
22
|
-
.filter(Boolean)
|
|
23
|
-
.map((directory) => join(directory, input));
|
|
24
|
-
if (input !== 'astrale')
|
|
25
|
-
return path;
|
|
26
|
-
const installed = await recordedInstallation();
|
|
27
|
-
return installed === undefined ? path : [installed, ...path];
|
|
28
|
-
}
|
|
29
|
-
async function recordedInstallation() {
|
|
30
|
-
const home = process.env.ASTRALE_HOME ?? join(homedir(), '.astrale');
|
|
31
|
-
try {
|
|
32
|
-
const decoded = JSON.parse(await readFile(join(home, 'install.json'), 'utf8'));
|
|
33
|
-
if (typeof decoded !== 'object' ||
|
|
34
|
-
decoded === null ||
|
|
35
|
-
!('method' in decoded) ||
|
|
36
|
-
decoded.method !== 'script' ||
|
|
37
|
-
!('bin' in decoded) ||
|
|
38
|
-
typeof decoded.bin !== 'string' ||
|
|
39
|
-
!isAbsolute(decoded.bin)) {
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
return decoded.bin;
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { AstraleProcessResult } from './process.js';
|
|
2
|
-
/** Only sanitized CLI diagnostics may be promoted through installation failures. */
|
|
3
|
-
export declare class AstraleCliError extends Error {
|
|
4
|
-
}
|
|
5
|
-
export declare function astraleFailure(command: string, result: AstraleProcessResult): Error;
|
|
6
|
-
export declare function isDomainNotInstalledFailure(stderr: string): boolean;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/** Only sanitized CLI diagnostics may be promoted through installation failures. */
|
|
2
|
-
export class AstraleCliError extends Error {
|
|
3
|
-
}
|
|
4
|
-
export function astraleFailure(command, result) {
|
|
5
|
-
let diagnostic;
|
|
6
|
-
try {
|
|
7
|
-
const failure = record(JSON.parse(result.stderr));
|
|
8
|
-
const error = admittedCode(failure.error);
|
|
9
|
-
const reason = recordOrUndefined(failure.reason);
|
|
10
|
-
const reasonCode = admittedCode(reason?.code);
|
|
11
|
-
diagnostic =
|
|
12
|
-
error === undefined ? undefined : reasonCode === undefined ? error : `${error}/${reasonCode}`;
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
// Never forward raw stderr because a credential-bearing command owns it.
|
|
16
|
-
}
|
|
17
|
-
return new AstraleCliError(`Astrale CLI ${command} failed${diagnostic === undefined ? '' : ` (${diagnostic})`}.`);
|
|
18
|
-
}
|
|
19
|
-
function admittedCode(input) {
|
|
20
|
-
return typeof input === 'string' && /^[A-Z][A-Z0-9_]{0,63}$/u.test(input) ? input : undefined;
|
|
21
|
-
}
|
|
22
|
-
function recordOrUndefined(input) {
|
|
23
|
-
return input !== null && typeof input === 'object' && !Array.isArray(input)
|
|
24
|
-
? input
|
|
25
|
-
: undefined;
|
|
26
|
-
}
|
|
27
|
-
export function isDomainNotInstalledFailure(stderr) {
|
|
28
|
-
try {
|
|
29
|
-
const failure = record(JSON.parse(stderr));
|
|
30
|
-
if (failure.error === 'DOMAIN_NOT_INSTALLED')
|
|
31
|
-
return true;
|
|
32
|
-
const reason = failure.reason;
|
|
33
|
-
return (failure.error === 'RESPONSE_ERROR' &&
|
|
34
|
-
reason !== null &&
|
|
35
|
-
typeof reason === 'object' &&
|
|
36
|
-
!Array.isArray(reason) &&
|
|
37
|
-
Reflect.get(reason, 'code') === 'SCHEMA_NOT_FOUND');
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function record(input) {
|
|
44
|
-
if (input === null || typeof input !== 'object' || Array.isArray(input)) {
|
|
45
|
-
throw new TypeError('Expected an object response.');
|
|
46
|
-
}
|
|
47
|
-
return input;
|
|
48
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { runAstrale } from './process.js';
|
|
2
|
-
/** Resolve and probe a bookmark through the pinned CLI, preserving its TLS trust. */
|
|
3
|
-
export declare function resolveAstraleInstanceIssuer(input: {
|
|
4
|
-
readonly executable: string;
|
|
5
|
-
readonly projectDir: string;
|
|
6
|
-
readonly instance: string;
|
|
7
|
-
readonly expectedIssuer?: string;
|
|
8
|
-
readonly signal: AbortSignal;
|
|
9
|
-
}, dependencies?: {
|
|
10
|
-
readonly run: typeof runAstrale;
|
|
11
|
-
}): Promise<string>;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { astraleFailure } from './failure.js';
|
|
2
|
-
import { runAstrale } from './process.js';
|
|
3
|
-
/** Resolve and probe a bookmark through the pinned CLI, preserving its TLS trust. */
|
|
4
|
-
export async function resolveAstraleInstanceIssuer(input, dependencies = { run: runAstrale }) {
|
|
5
|
-
const result = await dependencies.run({
|
|
6
|
-
executable: input.executable,
|
|
7
|
-
projectDir: input.projectDir,
|
|
8
|
-
signal: input.signal,
|
|
9
|
-
timeoutMs: 30_000,
|
|
10
|
-
args: ['--ci', '--no-prompt', 'instance', 'status', input.instance, '--bookmarked', '--json'],
|
|
11
|
-
});
|
|
12
|
-
if (result.code !== 0)
|
|
13
|
-
throw astraleFailure('instance status', result);
|
|
14
|
-
let value;
|
|
15
|
-
try {
|
|
16
|
-
value = JSON.parse(result.stdout);
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
throw new TypeError('Astrale instance status did not return one JSON value.');
|
|
20
|
-
}
|
|
21
|
-
if (value === null ||
|
|
22
|
-
typeof value !== 'object' ||
|
|
23
|
-
Array.isArray(value) ||
|
|
24
|
-
!('kind' in value) ||
|
|
25
|
-
value.kind !== 'bookmark' ||
|
|
26
|
-
!('state' in value) ||
|
|
27
|
-
value.state !== 'ready' ||
|
|
28
|
-
!('issuer' in value) ||
|
|
29
|
-
typeof value.issuer !== 'string') {
|
|
30
|
-
throw new TypeError('Astrale instance status returned invalid Kernel identity evidence.');
|
|
31
|
-
}
|
|
32
|
-
let issuer;
|
|
33
|
-
try {
|
|
34
|
-
issuer = new URL(value.issuer);
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
throw new TypeError('Astrale instance status returned an invalid Kernel issuer.');
|
|
38
|
-
}
|
|
39
|
-
if (!['https:', 'http:'].includes(issuer.protocol) ||
|
|
40
|
-
issuer.username ||
|
|
41
|
-
issuer.password ||
|
|
42
|
-
issuer.search ||
|
|
43
|
-
issuer.hash) {
|
|
44
|
-
throw new TypeError('Astrale instance status returned an invalid Kernel issuer.');
|
|
45
|
-
}
|
|
46
|
-
// Child Kernels share an origin, but their path-qualified identities remain distinct.
|
|
47
|
-
const canonical = issuer.href.replace(/\/$/u, '');
|
|
48
|
-
if (input.expectedIssuer !== undefined && canonical !== input.expectedIssuer) {
|
|
49
|
-
throw new Error('Installation bookmark changed Kernel; restart pnpm dev to apply it.');
|
|
50
|
-
}
|
|
51
|
-
return canonical;
|
|
52
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export interface AstraleProcessResult {
|
|
2
|
-
readonly code: number;
|
|
3
|
-
readonly stdout: string;
|
|
4
|
-
readonly stderr: string;
|
|
5
|
-
}
|
|
6
|
-
/** Run one exact Kernel CLI executable with bounded output, time, and termination. */
|
|
7
|
-
export declare function runAstrale(input: {
|
|
8
|
-
readonly executable: string;
|
|
9
|
-
readonly args: readonly string[];
|
|
10
|
-
readonly projectDir: string;
|
|
11
|
-
readonly signal: AbortSignal;
|
|
12
|
-
readonly timeoutMs: number;
|
|
13
|
-
}): Promise<AstraleProcessResult>;
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
const OUTPUT_LIMIT = 256 * 1024;
|
|
3
|
-
const TERMINATION_GRACE_MS = 1_000;
|
|
4
|
-
/** Run one exact Kernel CLI executable with bounded output, time, and termination. */
|
|
5
|
-
export function runAstrale(input) {
|
|
6
|
-
if (input.signal.aborted)
|
|
7
|
-
return Promise.reject(abortError(input.signal));
|
|
8
|
-
return new Promise((resolve, reject) => {
|
|
9
|
-
let child;
|
|
10
|
-
try {
|
|
11
|
-
child = spawn(input.executable, [...input.args], {
|
|
12
|
-
cwd: input.projectDir,
|
|
13
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
14
|
-
shell: false,
|
|
15
|
-
// This owner already forwards cancellation and enforces a deadline. Keep
|
|
16
|
-
// terminal group signals from killing installation observation/View cleanup.
|
|
17
|
-
detached: process.platform !== 'win32',
|
|
18
|
-
});
|
|
19
|
-
child.stdin.end();
|
|
20
|
-
}
|
|
21
|
-
catch (cause) {
|
|
22
|
-
reject(new Error('Astrale CLI is unavailable.', { cause }));
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
let stdout = '';
|
|
26
|
-
let stderr = '';
|
|
27
|
-
let stdoutBytes = 0;
|
|
28
|
-
let stderrBytes = 0;
|
|
29
|
-
let settled = false;
|
|
30
|
-
let termination;
|
|
31
|
-
let escalation;
|
|
32
|
-
const abort = () => terminate(input.signal.reason instanceof Error
|
|
33
|
-
? input.signal.reason
|
|
34
|
-
: new Error('Project operation interrupted.'));
|
|
35
|
-
input.signal.addEventListener('abort', abort, { once: true });
|
|
36
|
-
const cleanup = () => {
|
|
37
|
-
clearTimeout(timeout);
|
|
38
|
-
if (escalation !== undefined)
|
|
39
|
-
clearTimeout(escalation);
|
|
40
|
-
input.signal.removeEventListener('abort', abort);
|
|
41
|
-
};
|
|
42
|
-
const terminate = (cause) => {
|
|
43
|
-
if (settled || termination !== undefined)
|
|
44
|
-
return;
|
|
45
|
-
termination = cause;
|
|
46
|
-
child.stdin.destroy();
|
|
47
|
-
child.kill('SIGTERM');
|
|
48
|
-
escalation = setTimeout(() => {
|
|
49
|
-
if (child.exitCode === null && child.signalCode === null)
|
|
50
|
-
child.kill('SIGKILL');
|
|
51
|
-
}, TERMINATION_GRACE_MS);
|
|
52
|
-
};
|
|
53
|
-
const timeout = setTimeout(() => terminate(new Error('Astrale CLI command timed out.')), input.timeoutMs);
|
|
54
|
-
child.stdout.on('data', (chunk) => {
|
|
55
|
-
stdoutBytes += chunk.byteLength;
|
|
56
|
-
if (stdoutBytes > OUTPUT_LIMIT) {
|
|
57
|
-
terminate(new Error('Astrale CLI stdout exceeded the supported limit.'));
|
|
58
|
-
}
|
|
59
|
-
else
|
|
60
|
-
stdout += chunk.toString('utf8');
|
|
61
|
-
});
|
|
62
|
-
child.stderr.on('data', (chunk) => {
|
|
63
|
-
stderrBytes += chunk.byteLength;
|
|
64
|
-
if (stderrBytes > OUTPUT_LIMIT) {
|
|
65
|
-
terminate(new Error('Astrale CLI stderr exceeded the supported limit.'));
|
|
66
|
-
}
|
|
67
|
-
else
|
|
68
|
-
stderr += chunk.toString('utf8');
|
|
69
|
-
});
|
|
70
|
-
child.once('error', (cause) => {
|
|
71
|
-
if (settled)
|
|
72
|
-
return;
|
|
73
|
-
settled = true;
|
|
74
|
-
cleanup();
|
|
75
|
-
reject(new Error('Astrale CLI could not be started.', { cause }));
|
|
76
|
-
});
|
|
77
|
-
child.once('close', (code) => {
|
|
78
|
-
if (settled)
|
|
79
|
-
return;
|
|
80
|
-
settled = true;
|
|
81
|
-
cleanup();
|
|
82
|
-
if (termination !== undefined) {
|
|
83
|
-
reject(termination);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
resolve(Object.freeze({ code: code ?? 1, stdout, stderr }));
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
function abortError(signal) {
|
|
91
|
-
return signal.reason instanceof Error
|
|
92
|
-
? signal.reason
|
|
93
|
-
: new Error('Project operation interrupted.');
|
|
94
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { AstraleProcessResult } from './process.js';
|
|
2
|
-
import { resolveAstraleExecutable } from './executable.js';
|
|
3
|
-
export declare const MINIMUM_KERNEL_CLI_VERSION = "1.0.0-beta.48";
|
|
4
|
-
export interface CompatibleAstraleDependencies {
|
|
5
|
-
readonly resolveExecutable: typeof resolveAstraleExecutable;
|
|
6
|
-
readonly run: (input: {
|
|
7
|
-
readonly executable: string;
|
|
8
|
-
readonly args: readonly string[];
|
|
9
|
-
readonly projectDir: string;
|
|
10
|
-
readonly signal: AbortSignal;
|
|
11
|
-
readonly timeoutMs: number;
|
|
12
|
-
}) => Promise<AstraleProcessResult>;
|
|
13
|
-
}
|
|
14
|
-
/** Pin and admit one compatible CLI before any configured Kernel installation effect. */
|
|
15
|
-
export declare function resolveCompatibleAstrale(input: {
|
|
16
|
-
readonly projectDir: string;
|
|
17
|
-
readonly signal: AbortSignal;
|
|
18
|
-
}, dependencies?: CompatibleAstraleDependencies): Promise<string>;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { resolveAstraleExecutable } from './executable.js';
|
|
2
|
-
import { astraleFailure } from './failure.js';
|
|
3
|
-
import { runAstrale } from './process.js';
|
|
4
|
-
export const MINIMUM_KERNEL_CLI_VERSION = '1.0.0-beta.48';
|
|
5
|
-
/** Pin and admit one compatible CLI before any configured Kernel installation effect. */
|
|
6
|
-
export async function resolveCompatibleAstrale(input, dependencies = {
|
|
7
|
-
resolveExecutable: resolveAstraleExecutable,
|
|
8
|
-
run: runAstrale,
|
|
9
|
-
}) {
|
|
10
|
-
const executable = await dependencies.resolveExecutable();
|
|
11
|
-
const result = await dependencies.run({
|
|
12
|
-
executable,
|
|
13
|
-
projectDir: input.projectDir,
|
|
14
|
-
args: ['--version'],
|
|
15
|
-
signal: input.signal,
|
|
16
|
-
timeoutMs: 10_000,
|
|
17
|
-
});
|
|
18
|
-
if (result.code !== 0)
|
|
19
|
-
throw astraleFailure('version', result);
|
|
20
|
-
const version = result.stdout.trim().replace(/^v/u, '');
|
|
21
|
-
if (!isCompatible(version)) {
|
|
22
|
-
const diagnostic = semver(version) === undefined ? '<invalid>' : version;
|
|
23
|
-
throw new TypeError(`Astrale CLI ${diagnostic} is incompatible; ${MINIMUM_KERNEL_CLI_VERSION} or newer is required.`);
|
|
24
|
-
}
|
|
25
|
-
return executable;
|
|
26
|
-
}
|
|
27
|
-
function isCompatible(input) {
|
|
28
|
-
const value = semver(input);
|
|
29
|
-
const minimum = semver(MINIMUM_KERNEL_CLI_VERSION);
|
|
30
|
-
if (value === undefined)
|
|
31
|
-
return false;
|
|
32
|
-
for (let index = 0; index < 3; index += 1) {
|
|
33
|
-
if (value.core[index] > minimum.core[index])
|
|
34
|
-
return true;
|
|
35
|
-
if (value.core[index] < minimum.core[index])
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
if (value.prerelease === undefined)
|
|
39
|
-
return true;
|
|
40
|
-
if (minimum.prerelease === undefined)
|
|
41
|
-
return false;
|
|
42
|
-
if (value.prerelease.name !== minimum.prerelease.name) {
|
|
43
|
-
return value.prerelease.name.localeCompare(minimum.prerelease.name) > 0;
|
|
44
|
-
}
|
|
45
|
-
return value.prerelease.number >= minimum.prerelease.number;
|
|
46
|
-
}
|
|
47
|
-
function semver(input) {
|
|
48
|
-
const match = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z]+)\.(\d+))?$/u.exec(input);
|
|
49
|
-
if (match === null)
|
|
50
|
-
return undefined;
|
|
51
|
-
return {
|
|
52
|
-
core: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
53
|
-
...(match[4] === undefined ? {} : { prerelease: { name: match[4], number: Number(match[5]) } }),
|
|
54
|
-
};
|
|
55
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { ReadyDeployResult } from '../../../deployment/adapter/index.js';
|
|
2
|
-
import type { InstallationEvidence } from '../installation/index.js';
|
|
3
|
-
import type { DevelopmentCandidate } from './candidate.js';
|
|
4
|
-
export interface DevelopmentDeploymentInput {
|
|
5
|
-
readonly projectDir: string;
|
|
6
|
-
readonly environment: string;
|
|
7
|
-
readonly deployOnly: boolean;
|
|
8
|
-
readonly identity?: string;
|
|
9
|
-
readonly credential?: string;
|
|
10
|
-
readonly installationExecutable?: string;
|
|
11
|
-
}
|
|
12
|
-
/** Commit and verify one complete remote candidate, then reconcile its optional installation. */
|
|
13
|
-
export declare function deployDevelopmentCandidate(candidate: DevelopmentCandidate, input: DevelopmentDeploymentInput, signal: AbortSignal): Promise<{
|
|
14
|
-
readonly deployment: ReadyDeployResult;
|
|
15
|
-
readonly installation?: InstallationEvidence;
|
|
16
|
-
}>;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { verifyDeployment } from '../../../deployment/index.js';
|
|
2
|
-
import { reconcileEnvironmentRelease } from '../environment-release.js';
|
|
3
|
-
/** Commit and verify one complete remote candidate, then reconcile its optional installation. */
|
|
4
|
-
export async function deployDevelopmentCandidate(candidate, input, signal) {
|
|
5
|
-
const deployed = await candidate.adapter.deploy(candidate.parameters, {
|
|
6
|
-
projectDir: input.projectDir,
|
|
7
|
-
environment: input.environment,
|
|
8
|
-
...(candidate.installation === undefined ? {} : { installation: candidate.installation }),
|
|
9
|
-
...(input.identity === undefined ? {} : { identity: input.identity }),
|
|
10
|
-
...(input.credential === undefined ? {} : { credential: input.credential }),
|
|
11
|
-
secrets: candidate.secrets,
|
|
12
|
-
artifact: candidate.artifact,
|
|
13
|
-
signal,
|
|
14
|
-
});
|
|
15
|
-
const verified = verifyDeployment(candidate.artifact, deployed);
|
|
16
|
-
if (verified.status === 'failed') {
|
|
17
|
-
throw new Error(`Deployment failed during ${verified.phase}: ${verified.error.message}`, {
|
|
18
|
-
cause: verified.error,
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
const installation = await reconcileEnvironmentRelease({
|
|
22
|
-
projectDir: input.projectDir,
|
|
23
|
-
environment: input.environment,
|
|
24
|
-
adapter: candidate.adapter,
|
|
25
|
-
deployment: verified,
|
|
26
|
-
...(candidate.installation === undefined ? {} : { installation: candidate.installation }),
|
|
27
|
-
deployOnly: input.deployOnly,
|
|
28
|
-
...(input.installationExecutable === undefined
|
|
29
|
-
? {}
|
|
30
|
-
: { installationExecutable: input.installationExecutable }),
|
|
31
|
-
...(input.identity === undefined ? {} : { identity: input.identity }),
|
|
32
|
-
...(input.credential === undefined ? {} : { credential: input.credential }),
|
|
33
|
-
signal,
|
|
34
|
-
});
|
|
35
|
-
return Object.freeze({
|
|
36
|
-
deployment: verified,
|
|
37
|
-
...(installation === undefined ? {} : { installation }),
|
|
38
|
-
});
|
|
39
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/** Watch one Project Environment and serialize complete remote deployment generations. */
|
|
2
|
-
export declare function develop(input: {
|
|
3
|
-
readonly configPath: string;
|
|
4
|
-
readonly projectDir: string;
|
|
5
|
-
readonly environment: string;
|
|
6
|
-
readonly deployOnly: boolean;
|
|
7
|
-
readonly identity?: string;
|
|
8
|
-
readonly credentialFile?: string;
|
|
9
|
-
readonly sessionFile?: string;
|
|
10
|
-
readonly secretsFile?: string;
|
|
11
|
-
}): Promise<number>;
|