@astrale-os/sdk 0.6.0-beta.19 → 0.6.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import type { DeploymentSummaryV1 } from '../../address/index.js';
|
|
2
2
|
/**
|
|
3
|
-
* Where one listed deployment is called on its host, so that an operator can act on
|
|
4
|
-
* deployment alone, such as rotating one of its secrets in place (AM-4'):
|
|
3
|
+
* Where one listed deployment is called on its host, so that an operator can act on it:
|
|
5
4
|
*
|
|
6
5
|
* - `services`: a deployment Admin's Services hosts, called on the Admin instance with
|
|
7
|
-
* `astrale call "<
|
|
8
|
-
* Admin bookmark). `path` is the deployment's node, `@<id>`, qualified by its class
|
|
9
|
-
* `@<id>::services.astrale.ai:class.CloudflareDeployment`.
|
|
6
|
+
* `astrale call "<node>.method.<method>" --admin` (`--admin=<admin>` when `admin` names the
|
|
7
|
+
* Admin bookmark). `path` is the deployment's node, `@<id>`, qualified by its class,
|
|
8
|
+
* `@<id>::services.astrale.ai:class.CloudflareDeployment`, whose only Method is `retire`.
|
|
9
|
+
* `service` is the node of the Service it is a version of,
|
|
10
|
+
* `@<serviceId>::services.astrale.ai:class.CloudflareService`, whose Methods act on the Service
|
|
11
|
+
* and the deployment it currently serves: `promote` (this deployment's label rolls the Service
|
|
12
|
+
* back or forward to it), `setSecret` and `secrets`, `setSchedule` and `schedules`, `logs`,
|
|
13
|
+
* `transfer` and `delete`.
|
|
10
14
|
* - `namespace`: a deployment of a platform dispatch namespace, which has no Services node: the
|
|
11
15
|
* namespace and the script the per-script tooling of that namespace takes.
|
|
12
16
|
*/
|
|
13
17
|
export type DeploymentCallTarget = {
|
|
14
18
|
readonly kind: 'services';
|
|
15
19
|
readonly path: string;
|
|
20
|
+
readonly service: string;
|
|
16
21
|
/** The Admin bookmark the deployment is reached through; the CLI's own Admin target when absent. */
|
|
17
22
|
readonly admin?: string;
|
|
18
23
|
} | {
|
|
@@ -25,6 +30,8 @@ export type DeploymentCallTarget = {
|
|
|
25
30
|
* host stores it, and where it is called. `lastCallAt`, and a preview's `expiresAt`, are as of the
|
|
26
31
|
* listing: an adapter whose host records calls only now and then reads the calls counted since, and
|
|
27
32
|
* one that cannot read them for want of a permission omits both rather than print stale values.
|
|
33
|
+
* Admin's Services keeps every deployment until it is retired and counts no call: its deployments
|
|
34
|
+
* are `published`, `withdrawn` once retiring, and carry neither clock.
|
|
28
35
|
*
|
|
29
36
|
* The adapter does not admit the record. The listing admits it with `acceptDeploymentRecord`, and a
|
|
30
37
|
* record it refuses (one a host on an older SDK still admits, say) never fails the listing: that
|
|
@@ -37,5 +44,10 @@ export interface ListedDeployment extends Omit<DeploymentSummaryV1, 'record'> {
|
|
|
37
44
|
* it activates the deployment.
|
|
38
45
|
*/
|
|
39
46
|
readonly record?: unknown;
|
|
47
|
+
/**
|
|
48
|
+
* Whether the stable URL of the deployment's Service serves it. Present only where the host has
|
|
49
|
+
* Services (Admin's Services); a platform namespace has none.
|
|
50
|
+
*/
|
|
51
|
+
readonly current?: boolean;
|
|
40
52
|
readonly callTarget: DeploymentCallTarget;
|
|
41
53
|
}
|
package/dist/project/define.js
CHANGED
|
@@ -4,10 +4,6 @@ import { ENVIRONMENT_NAME } from '../deployment/environment.js';
|
|
|
4
4
|
import { isTests } from '../testing/index.js';
|
|
5
5
|
import { installCommand } from './install-command.js';
|
|
6
6
|
const admittedProjects = new WeakSet();
|
|
7
|
-
/** The adapter name of adapter-astrale, whose removed instance mode once read `installation`. */
|
|
8
|
-
const ASTRALE_ADAPTER = 'astrale';
|
|
9
|
-
/** The one Environment adapter-astrale deploys without an explicit organisation (AM-7). */
|
|
10
|
-
const ASTRALE_DEFAULT_ORGANIZATION_ENVIRONMENT = 'development';
|
|
11
7
|
/** Capture one inert Project definition without loading entrypoints or performing effects. */
|
|
12
8
|
export function defineProject(input) {
|
|
13
9
|
const value = record(input, 'Project definition');
|
|
@@ -82,10 +78,8 @@ function admitEntrypoints(input) {
|
|
|
82
78
|
* `installation` is refused before any effect, with the commands that replace it. Its only
|
|
83
79
|
* consumer pins an SDK older than this refusal.
|
|
84
80
|
*
|
|
85
|
-
* adapter-astrale deploys on Admin's Services, never through the installation's instance
|
|
86
|
-
*
|
|
87
|
-
* which the guidance adds when the adapter names none. The installation's instance and identity
|
|
88
|
-
* move to the install command.
|
|
81
|
+
* adapter-astrale deploys on Admin's Services, never through the installation's instance. The
|
|
82
|
+
* installation's instance and identity move to the install command.
|
|
89
83
|
*/
|
|
90
84
|
function installationRefusal(environment, name) {
|
|
91
85
|
const declared = environment.installation;
|
|
@@ -98,15 +92,8 @@ function installationRefusal(environment, name) {
|
|
|
98
92
|
: {};
|
|
99
93
|
const instance = stable(installation.instance);
|
|
100
94
|
const identity = stable(installation.identity);
|
|
101
|
-
const deployment = environment.deployment;
|
|
102
|
-
const organization = isDeployment(deployment) &&
|
|
103
|
-
deployment.adapter.name === ASTRALE_ADAPTER &&
|
|
104
|
-
name !== ASTRALE_DEFAULT_ORGANIZATION_ENVIRONMENT &&
|
|
105
|
-
deployment.parameters.organization === undefined
|
|
106
|
-
? ", name the organisation that holds its deployment line in `astrale({ organization: '<Identity id>' })`"
|
|
107
|
-
: '';
|
|
108
95
|
return (`Project Environment ${name} declares installation, and a deploy no longer installs. ` +
|
|
109
|
-
`Remove \`installation
|
|
96
|
+
`Remove \`installation\`, run \`astrale-domain deploy ${name}\`, ` +
|
|
110
97
|
`then install the URL it prints with \`${installCommand(instance, identity)}\`.`);
|
|
111
98
|
}
|
|
112
99
|
/** A declared coordinate worth repeating in guidance: a non-empty single-line trimmed string. */
|
|
@@ -2,8 +2,6 @@ import { installCommand } from '../../project/install-command.js';
|
|
|
2
2
|
/** The adapter names of the first-party adapters whose parameters CT33 classifies. */
|
|
3
3
|
const CLOUDFLARE = 'cloudflare';
|
|
4
4
|
const ASTRALE = 'astrale';
|
|
5
|
-
/** The one Environment adapter-astrale deploys without an explicit organisation (AM-7). */
|
|
6
|
-
const DEVELOPMENT = 'development';
|
|
7
5
|
/** The parameters that named the stable Service of adapter-astrale's removed instance mode. */
|
|
8
6
|
const ASTRALE_SERVICE_PARAMETERS = ['serviceKey', 'name'];
|
|
9
7
|
const CLOUDFLARE_DIRECT_PARAMETERS = [
|
|
@@ -48,10 +46,7 @@ export function selectDeployMode(input) {
|
|
|
48
46
|
refusals.push({
|
|
49
47
|
reason: 'astrale-signing-identity',
|
|
50
48
|
guidance: 'astrale({ signingIdentity }) is no longer accepted: each deployment gets a signing key ' +
|
|
51
|
-
'generated when it is deployed. Remove `signingIdentity
|
|
52
|
-
// With `instance`, its own refusal already names the organisation.
|
|
53
|
-
(declares(parameters, 'instance') ? '' : organizationGuidance(parameters, environment)) +
|
|
54
|
-
'.',
|
|
49
|
+
'generated when it is deployed. Remove `signingIdentity`.',
|
|
55
50
|
});
|
|
56
51
|
}
|
|
57
52
|
}
|
|
@@ -98,8 +93,8 @@ export function selectDeployMode(input) {
|
|
|
98
93
|
}
|
|
99
94
|
/**
|
|
100
95
|
* How an adapter-astrale Environment of the removed instance mode deploys now: without `instance`
|
|
101
|
-
* (nor `serviceKey` and `name`, which named its stable Service),
|
|
102
|
-
*
|
|
96
|
+
* (nor `serviceKey` and `name`, which named its stable Service), then installed by URL on the
|
|
97
|
+
* instance it used to deploy through.
|
|
103
98
|
*/
|
|
104
99
|
function astraleInstanceGuidance(parameters, environment) {
|
|
105
100
|
const instance = String(parameters.instance);
|
|
@@ -108,18 +103,11 @@ function astraleInstanceGuidance(parameters, environment) {
|
|
|
108
103
|
? 'Remove `instance`'
|
|
109
104
|
: `Remove \`instance\` with ${service.map((name) => `\`${name}\``).join(' and ')}, ` +
|
|
110
105
|
`which named its stable Service`;
|
|
111
|
-
const organization = organizationGuidance(parameters, environment);
|
|
112
106
|
return (`astrale({ instance: '${instance}' }) deployed through that instance's Services, which no ` +
|
|
113
|
-
`longer hosts deployments. ${removed}
|
|
107
|
+
`longer hosts deployments. ${removed}: \`astrale-domain deploy ${environment}\` ` +
|
|
114
108
|
`makes an immutable deployment on Admin's Services, and \`${installCommand(instance)}\` ` +
|
|
115
109
|
'installs it.');
|
|
116
110
|
}
|
|
117
|
-
/** Outside development, an adapter-astrale Environment names the organisation of its line (AM-7). */
|
|
118
|
-
function organizationGuidance(parameters, environment) {
|
|
119
|
-
return environment === DEVELOPMENT || declares(parameters, 'organization')
|
|
120
|
-
? ''
|
|
121
|
-
: ", and name the organisation that holds the deployment line in `astrale({ organization: '<Identity id>' })`";
|
|
122
|
-
}
|
|
123
111
|
/**
|
|
124
112
|
* Why a legacy direct-mode Environment cannot be published, and the configuration that makes it
|
|
125
113
|
* publishable: a version names an immutable deployment's release, which a stable target never
|
|
@@ -27,9 +27,10 @@ export interface ListResultV1 {
|
|
|
27
27
|
/**
|
|
28
28
|
* One deployment: what its host knows (`DeploymentSummaryV1`), the Environment it was listed for
|
|
29
29
|
* and its adapter, its computed name, and its call target. `lastCallAt` and a preview's `expiresAt`
|
|
30
|
-
* are as of the listing:
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* are as of the listing: a platform namespace (adapter-cloudflare) reads every call from its calls
|
|
31
|
+
* dataset, and omits both without Account Analytics Read. Admin's Services (adapter-astrale) keeps
|
|
32
|
+
* every deployment until it is retired and counts no call: its rows are `published`, with neither
|
|
33
|
+
* clock, and say whether their Service serves them (`current`).
|
|
33
34
|
*/
|
|
34
35
|
export type ListedDeploymentV1 = Omit<DeploymentSummaryV1, 'record'> & {
|
|
35
36
|
/** The Project Environment whose line holds the deployment, as its host listed it. */
|
|
@@ -64,7 +65,12 @@ export type ListedDeploymentV1 = Omit<DeploymentSummaryV1, 'record'> & {
|
|
|
64
65
|
* present exactly when `record` is `null`.
|
|
65
66
|
*/
|
|
66
67
|
readonly recordRefusal?: string;
|
|
67
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Whether the stable URL of the deployment's Service serves it; present only for a host with
|
|
70
|
+
* Services (Admin's Services).
|
|
71
|
+
*/
|
|
72
|
+
readonly current?: boolean;
|
|
73
|
+
/** Where to call this deployment, and on Admin's Services its Service. */
|
|
68
74
|
readonly callTarget: DeploymentCallTarget;
|
|
69
75
|
};
|
|
70
76
|
/**
|
|
@@ -111,8 +117,8 @@ export type DeploymentRegistry = Pick<DomainRegistry, 'index' | 'instance'>;
|
|
|
111
117
|
* Only an Environment that deploys immutable deployments (CT33 canonical) is listed; the others are
|
|
112
118
|
* `unlisted`, with the reason. A record the host returns but `acceptDeploymentRecord` refuses never
|
|
113
119
|
* fails the listing: that deployment is listed from what its host knows, its record `null`. This
|
|
114
|
-
* covers a host whose SDK still admits a record this SDK refuses
|
|
115
|
-
*
|
|
120
|
+
* covers a host whose SDK still admits a record this SDK refuses, and a host that lists a record
|
|
121
|
+
* its own SDK no longer admits as it is stored (Admin's Services does). An Environment whose host
|
|
116
122
|
* cannot be listed, or whose adapter answers anything but deployments, is a failure, and the others
|
|
117
123
|
* are still listed.
|
|
118
124
|
*
|
|
@@ -140,9 +146,9 @@ export declare function listDeployments(input: {
|
|
|
140
146
|
}): Promise<DeploymentListing>;
|
|
141
147
|
/**
|
|
142
148
|
* The listing as a table for a person, at `now`: each deployment's release, its name as computed
|
|
143
|
-
* (never shortened, AM-57), its Environment and state
|
|
144
|
-
* source could not tell, AM-198), its
|
|
145
|
-
* install` takes. Without deployments, it says so only for what was listed: nothing when a host
|
|
149
|
+
* (never shortened, AM-57), its Environment and state (`active (current)` for the deployment its
|
|
150
|
+
* Service serves), the instances known to pin it (`?` when a source could not tell, AM-198), its
|
|
151
|
+
* last call and its expiry, and the URL `astrale domain install` takes. Without deployments, it says so only for what was listed: nothing when a host
|
|
146
152
|
* `failed` (stderr says which), and that some Environments were not listed when any was not.
|
|
147
153
|
*/
|
|
148
154
|
export declare function renderDeploymentList(result: ListResultV1, now: number, failed?: boolean): readonly string[];
|
package/dist/tooling/cli/list.js
CHANGED
|
@@ -10,8 +10,8 @@ import { installationNotices, installedOn, installedOnCell, readInstallations, s
|
|
|
10
10
|
* Only an Environment that deploys immutable deployments (CT33 canonical) is listed; the others are
|
|
11
11
|
* `unlisted`, with the reason. A record the host returns but `acceptDeploymentRecord` refuses never
|
|
12
12
|
* fails the listing: that deployment is listed from what its host knows, its record `null`. This
|
|
13
|
-
* covers a host whose SDK still admits a record this SDK refuses
|
|
14
|
-
*
|
|
13
|
+
* covers a host whose SDK still admits a record this SDK refuses, and a host that lists a record
|
|
14
|
+
* its own SDK no longer admits as it is stored (Admin's Services does). An Environment whose host
|
|
15
15
|
* cannot be listed, or whose adapter answers anything but deployments, is a failure, and the others
|
|
16
16
|
* are still listed.
|
|
17
17
|
*
|
|
@@ -198,6 +198,7 @@ function listedDeployment(hosted, publications, installations) {
|
|
|
198
198
|
signingKeyId: deployment.signingKeyId,
|
|
199
199
|
record,
|
|
200
200
|
...(recordRefusal === undefined ? {} : { recordRefusal }),
|
|
201
|
+
...(deployment.current === undefined ? {} : { current: deployment.current }),
|
|
201
202
|
callTarget: deployment.callTarget,
|
|
202
203
|
});
|
|
203
204
|
}
|
|
@@ -275,9 +276,13 @@ function admitListed(deployment, adapter) {
|
|
|
275
276
|
value.retirement !== 'withdrawn') {
|
|
276
277
|
invalid('retirement');
|
|
277
278
|
}
|
|
279
|
+
if (value.current !== undefined && typeof value.current !== 'boolean')
|
|
280
|
+
invalid('current');
|
|
278
281
|
const target = members(value.callTarget) ?? invalid('callTarget');
|
|
279
282
|
if (target.kind === 'services') {
|
|
280
|
-
if (!text(target.path) ||
|
|
283
|
+
if (!text(target.path) ||
|
|
284
|
+
!text(target.service) ||
|
|
285
|
+
(target.admin !== undefined && !text(target.admin))) {
|
|
281
286
|
invalid('callTarget');
|
|
282
287
|
}
|
|
283
288
|
}
|
|
@@ -308,9 +313,9 @@ const HOUR = 60 * MINUTE;
|
|
|
308
313
|
const DAY = 24 * HOUR;
|
|
309
314
|
/**
|
|
310
315
|
* The listing as a table for a person, at `now`: each deployment's release, its name as computed
|
|
311
|
-
* (never shortened, AM-57), its Environment and state
|
|
312
|
-
* source could not tell, AM-198), its
|
|
313
|
-
* install` takes. Without deployments, it says so only for what was listed: nothing when a host
|
|
316
|
+
* (never shortened, AM-57), its Environment and state (`active (current)` for the deployment its
|
|
317
|
+
* Service serves), the instances known to pin it (`?` when a source could not tell, AM-198), its
|
|
318
|
+
* last call and its expiry, and the URL `astrale domain install` takes. Without deployments, it says so only for what was listed: nothing when a host
|
|
314
319
|
* `failed` (stderr says which), and that some Environments were not listed when any was not.
|
|
315
320
|
*/
|
|
316
321
|
export function renderDeploymentList(result, now, failed = false) {
|
|
@@ -328,7 +333,7 @@ export function renderDeploymentList(result, now, failed = false) {
|
|
|
328
333
|
deployment.record === null ? '?' : shortDigest(deployment.record.releaseDigest),
|
|
329
334
|
deployment.name,
|
|
330
335
|
deployment.environment,
|
|
331
|
-
deployment.state,
|
|
336
|
+
deployment.current === true ? `${deployment.state} (current)` : deployment.state,
|
|
332
337
|
installedOnCell(deployment.installedOn, result.installations),
|
|
333
338
|
deployment.lastCallAt === undefined
|
|
334
339
|
? '—'
|
|
@@ -299,8 +299,8 @@ function described(cause) {
|
|
|
299
299
|
}
|
|
300
300
|
/**
|
|
301
301
|
* Keep the published deployment where its host has no registry principal to mark it: the adapter
|
|
302
|
-
* declares `retain` for the platform namespace only (CT36). Admin
|
|
303
|
-
*
|
|
302
|
+
* declares `retain` for the platform namespace only (CT36). Admin's Services keeps every
|
|
303
|
+
* deployment until it is retired, so adapter-astrale declares none. A `RetainRefusal` (absent or
|
|
304
304
|
* retired) is `refused`, which no rerun changes; any other rejection `failed`, which a rerun
|
|
305
305
|
* retries.
|
|
306
306
|
*/
|