@astrale-domains/services 0.5.0 → 0.6.0
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 +149 -51
- package/dist/scaffold/create-service.mjs +94 -0
- package/dist/scaffold/template/.env.example +4 -0
- package/dist/scaffold/template/README.md +75 -0
- package/dist/scaffold/template/gitignore +6 -0
- package/dist/scaffold/template/scripts/build.mjs +20 -0
- package/dist/scaffold/template/scripts/deploy.mjs +65 -0
- package/dist/scaffold/template/scripts/service.mjs +69 -0
- package/dist/scaffold/template/src/account.js +31 -0
- package/dist/scaffold/template/src/index.js +50 -0
- package/dist/scaffold/template/src/job.js +22 -0
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.js +1 -1
- package/dist/schema/modules/deployment/classes/cloudflare-deployment.d.ts +41 -20
- package/dist/schema/modules/deployment/classes/deployment.d.ts +54 -25
- package/dist/schema/modules/deployment/classes/deployment.js +20 -9
- package/dist/schema/modules/deployment/functions/retire-deployment.d.ts +5 -5
- package/dist/schema/modules/deployment/index.d.ts +2 -2
- package/dist/schema/modules/deployment/index.js +1 -1
- package/dist/schema/modules/deployment/types/deployment-hosting.d.ts +19 -49
- package/dist/schema/modules/deployment/types/deployment-hosting.js +10 -10
- package/dist/schema/modules/deployment/types/deployment-request.d.ts +45 -93
- package/dist/schema/modules/deployment/types/deployment-request.js +60 -30
- package/dist/schema/modules/deployment/types/deployment-response.d.ts +14 -22
- package/dist/schema/modules/deployment/types/deployment-response.js +5 -2
- package/dist/schema/modules/deployment/types/deployment-secret.d.ts +2 -2
- package/dist/schema/modules/deployment/types/deployment-secret.js +2 -2
- package/dist/schema/modules/deployment/types/deployment-summary.d.ts +13 -112
- package/dist/schema/modules/deployment/types/deployment-summary.js +16 -18
- package/dist/schema/modules/deployment/types/index.d.ts +10 -12
- package/dist/schema/modules/deployment/types/index.js +5 -6
- package/dist/schema/modules/deployment/types/{frozen-configuration.d.ts → legacy-deployment.d.ts} +24 -11
- package/dist/schema/modules/deployment/types/{frozen-configuration.js → legacy-deployment.js} +34 -10
- package/dist/schema/modules/deployment/types/legacy-migration.d.ts +17 -0
- package/dist/schema/modules/deployment/types/legacy-migration.js +17 -0
- package/dist/schema/modules/deployment/types/worker-configuration.d.ts +21 -0
- package/dist/schema/modules/deployment/types/worker-configuration.js +21 -0
- package/dist/schema/modules/deployment/types/worker-record.d.ts +12 -0
- package/dist/schema/modules/deployment/types/worker-record.js +15 -0
- package/dist/schema/modules/service/classes/cloudflare-service.d.ts +72 -135
- package/dist/schema/modules/service/classes/cloudflare-service.js +6 -1
- package/dist/schema/modules/service/classes/service.d.ts +17 -7
- package/dist/schema/modules/service/classes/service.js +14 -8
- package/dist/schema/modules/service/functions/deploy-service.d.ts +44 -100
- package/dist/schema/modules/service/functions/deploy-service.js +6 -5
- package/dist/schema/modules/service/functions/describe-hosting.d.ts +0 -1
- package/dist/schema/modules/service/functions/index.d.ts +1 -0
- package/dist/schema/modules/service/functions/index.js +1 -0
- package/dist/schema/modules/service/functions/list-service-deployments.d.ts +12 -36
- package/dist/schema/modules/service/functions/migrate-legacy-deployments.d.ts +17 -0
- package/dist/schema/modules/service/functions/migrate-legacy-deployments.js +15 -0
- package/dist/schema/modules/service/functions/promote-service.d.ts +2 -2
- package/dist/schema/modules/service/functions/set-service-secret.d.ts +2 -2
- package/dist/schema/modules/service/functions/transfer-service.d.ts +2 -2
- package/dist/schema/modules/service/index.d.ts +1 -1
- package/dist/schema/modules/service/index.js +1 -1
- package/dist/schema/schema.d.ts +158 -177
- package/package.json +11 -7
- package/dist/schema/modules/deployment/types/content/index.d.ts +0 -1
- package/dist/schema/modules/deployment/types/content/index.js +0 -1
- package/dist/schema/modules/deployment/types/content/limits.d.ts +0 -7
- package/dist/schema/modules/deployment/types/content/limits.js +0 -7
- package/dist/schema/modules/deployment/types/deployment-record.d.ts +0 -35
- package/dist/schema/modules/deployment/types/deployment-record.js +0 -31
- package/dist/schema/modules/deployment/types/service-deployment-artifact-module.d.ts +0 -26
- package/dist/schema/modules/deployment/types/service-deployment-artifact-module.js +0 -10
- package/dist/schema/modules/deployment/types/service-deployment-assets.d.ts +0 -49
- package/dist/schema/modules/deployment/types/service-deployment-assets.js +0 -16
- package/dist/schema/modules/deployment/types/service-deployment-content.d.ts +0 -19
- package/dist/schema/modules/deployment/types/service-deployment-content.js +0 -24
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { issuer, jwk, register } from '@astrale-os/sdk/auth'
|
|
2
|
+
import { connect } from '@astrale-os/sdk/client/session'
|
|
3
|
+
import { importJWK, SignJWT } from 'jose'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A session on `kernel` as the Identity registered with this ES256 key: each call presents a
|
|
7
|
+
* short-lived self-signed credential. Register the key on a dedicated Identity of the target's
|
|
8
|
+
* Domain and grant it only the callables the job needs; never a Root or admin credential.
|
|
9
|
+
*/
|
|
10
|
+
export function openAccount(kernel, privateJwk) {
|
|
11
|
+
if (privateJwk.kty !== 'EC' || privateJwk.crv !== 'P-256' || !privateJwk.d) {
|
|
12
|
+
throw new TypeError('ACCOUNT_PRIVATE_JWK must be a registered ES256 private JWK.')
|
|
13
|
+
}
|
|
14
|
+
const publicKey = jwk.acceptPublic({ kty: 'EC', crv: 'P-256', x: privateJwk.x, y: privateJwk.y })
|
|
15
|
+
return connect({
|
|
16
|
+
url: kernel,
|
|
17
|
+
auth: {
|
|
18
|
+
ttlSeconds: 60,
|
|
19
|
+
resolve: async () => ({
|
|
20
|
+
credential: await new SignJWT({})
|
|
21
|
+
.setProtectedHeader({ alg: 'ES256', kid: privateJwk.kid, typ: 'JWT' })
|
|
22
|
+
.setIssuer(await register.selfIssuer(issuer.accept(kernel), publicKey))
|
|
23
|
+
.setSubject('self')
|
|
24
|
+
.setAudience(kernel)
|
|
25
|
+
.setIssuedAt()
|
|
26
|
+
.setExpirationTime('3m')
|
|
27
|
+
.sign(await importJWK(privateJwk, 'ES256')),
|
|
28
|
+
}),
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { runJob } from './job.js'
|
|
2
|
+
|
|
3
|
+
/** The call budget of one scheduled run, under the dispatcher's 10 s deadline. */
|
|
4
|
+
const JOB_BUDGET_MS = 9_000
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
/**
|
|
8
|
+
* Admin's Services serves this Worker at its deployment URL and at its Service's URL. A cron of
|
|
9
|
+
* the Service reaches it as `POST /__scheduled` from the Services dispatcher alone, with the cron
|
|
10
|
+
* in `x-astrale-cron` and the minute it fired for (epoch ms) in `x-astrale-scheduled-time`: the
|
|
11
|
+
* dispatcher refuses that path to the public, in every spelling.
|
|
12
|
+
*/
|
|
13
|
+
async fetch(request, env) {
|
|
14
|
+
const path = new URL(request.url).pathname
|
|
15
|
+
if (path === '/health' && request.method === 'GET') {
|
|
16
|
+
return new Response('ok', {
|
|
17
|
+
headers: { 'x-astrale-worker-version': env.ASTRALE_VERSION_METADATA?.id ?? '' },
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
if (path === '/__scheduled' && request.method === 'POST') return scheduled(request, env)
|
|
21
|
+
return new Response(null, { status: 404 })
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function scheduled(request, env) {
|
|
26
|
+
const cron = request.headers.get('x-astrale-cron')
|
|
27
|
+
const scheduledAt = Number(request.headers.get('x-astrale-scheduled-time'))
|
|
28
|
+
if (cron === null || !Number.isSafeInteger(scheduledAt) || scheduledAt <= 0) {
|
|
29
|
+
return new Response(null, { status: 400 })
|
|
30
|
+
}
|
|
31
|
+
const started = Date.now()
|
|
32
|
+
try {
|
|
33
|
+
await runJob({ cron, scheduledAt, env, signal: AbortSignal.timeout(JOB_BUDGET_MS) })
|
|
34
|
+
console.log(
|
|
35
|
+
JSON.stringify({ event: 'job.completed', cron, scheduledAt, ms: Date.now() - started }),
|
|
36
|
+
)
|
|
37
|
+
return Response.json({ status: 'completed' })
|
|
38
|
+
} catch (error) {
|
|
39
|
+
// Never log a credential, a provider envelope or a business value: only the error's code.
|
|
40
|
+
console.error(
|
|
41
|
+
JSON.stringify({
|
|
42
|
+
event: 'job.failed',
|
|
43
|
+
cron,
|
|
44
|
+
scheduledAt,
|
|
45
|
+
code: typeof error?.code === 'number' ? error.code : undefined,
|
|
46
|
+
}),
|
|
47
|
+
)
|
|
48
|
+
return Response.json({ status: 'failed' }, { status: 503 })
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Path } from '@astrale-os/sdk/graph/path'
|
|
2
|
+
|
|
3
|
+
import { openAccount } from './account.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The job one cron runs: call one callable of an Astrale Kernel as this Service's own account.
|
|
7
|
+
* Adapt its input to the target's contract; a repeated or uncertain run is the target's to absorb.
|
|
8
|
+
*/
|
|
9
|
+
export async function runJob({ cron, scheduledAt, env, signal }) {
|
|
10
|
+
if (!env.KERNEL || !env.TARGET || !env.ACCOUNT_PRIVATE_JWK) {
|
|
11
|
+
throw new Error('Configure KERNEL, TARGET and the ACCOUNT_PRIVATE_JWK secret.')
|
|
12
|
+
}
|
|
13
|
+
const session = openAccount(env.KERNEL, JSON.parse(env.ACCOUNT_PRIVATE_JWK))
|
|
14
|
+
try {
|
|
15
|
+
return await session.call(
|
|
16
|
+
{ target: Path.parse(env.TARGET), input: { cron, scheduledAt } },
|
|
17
|
+
{ signal },
|
|
18
|
+
)
|
|
19
|
+
} finally {
|
|
20
|
+
session.close()
|
|
21
|
+
}
|
|
22
|
+
}
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { schema } from './schema.js';
|
|
|
2
2
|
export type { ServicesDomain, ServicesSchema } from './schema.js';
|
|
3
3
|
export { ActAs, CloudflareService, OwnService, Service, TraverseOwnedService, serviceLifecycle, service_owned_by, } from './modules/service/index.js';
|
|
4
4
|
export type { ServiceLifecycle, ServiceLifecycleEvent } from './modules/service/index.js';
|
|
5
|
-
export {
|
|
6
|
-
export type {
|
|
5
|
+
export { CloudflareDeployment, Deployment, OwnDeployment, TraverseOwnedServiceDeployment, current_deployment, deployment_of, deploymentHosting, deploymentLifecycle, deploymentRejection, deploymentRequest, deploymentResponse, deploymentSecretDigests, deploymentSecretRejection, deploymentSummary, legacyDeploymentRecord, legacyFrozenConfiguration, retireDeploymentOutput, workerConfiguration, workerRecord, } from './modules/deployment/index.js';
|
|
6
|
+
export type { DeploymentHosting, DeploymentLifecycle, DeploymentLifecycleEvent, DeploymentRejection, DeploymentRejectionReason, DeploymentRequest, DeploymentResponse, DeploymentSecretDigest, DeploymentSecretRejection, DeploymentSummary, LegacyDeploymentRecord, LegacyFrozenConfiguration, MigrateLegacyResult, RetireDeploymentResult, WorkerConfiguration, WorkerRecordWire, } from './modules/deployment/index.js';
|
package/dist/schema/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { schema } from './schema.js';
|
|
2
2
|
export { ActAs, CloudflareService, OwnService, Service, TraverseOwnedService, serviceLifecycle, service_owned_by, } from './modules/service/index.js';
|
|
3
|
-
export {
|
|
3
|
+
export { CloudflareDeployment, Deployment, OwnDeployment, TraverseOwnedServiceDeployment, current_deployment, deployment_of, deploymentHosting, deploymentLifecycle, deploymentRejection, deploymentRequest, deploymentResponse, deploymentSecretDigests, deploymentSecretRejection, deploymentSummary, legacyDeploymentRecord, legacyFrozenConfiguration, retireDeploymentOutput, workerConfiguration, workerRecord, } from './modules/deployment/index.js';
|
|
@@ -29,26 +29,20 @@ export declare const CloudflareDeployment: import("@astrale-os/sdk/schema").Auth
|
|
|
29
29
|
required?: boolean;
|
|
30
30
|
description?: string;
|
|
31
31
|
}>;
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
buildDigest: import("@astrale-os/sdk/schema").AuthoredProperty<import("zod").ZodString, {
|
|
33
|
+
readonly required: false;
|
|
34
|
+
}>;
|
|
35
|
+
configuration: import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
36
|
+
format: import("zod").ZodLiteral<"astrale.worker.configuration">;
|
|
34
37
|
version: import("zod").ZodLiteral<1>;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
sha: import("zod").ZodString;
|
|
44
|
-
dirty: import("zod").ZodBoolean;
|
|
45
|
-
base: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
46
|
-
version: import("zod").ZodString;
|
|
47
|
-
distance: import("zod").ZodNumber;
|
|
48
|
-
}, import("zod/v4/core").$strict>>;
|
|
49
|
-
}, import("zod/v4/core").$strict>>;
|
|
50
|
-
}, import("zod/v4/core").$strict>;
|
|
51
|
-
configuration: import("zod").ZodObject<{
|
|
38
|
+
compatibilityDate: import("zod").ZodString;
|
|
39
|
+
compatibilityFlags: import("zod").ZodArray<import("zod").ZodString>;
|
|
40
|
+
vars: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>;
|
|
41
|
+
secrets: import("zod").ZodArray<import("zod").ZodString>;
|
|
42
|
+
record: import("zod").ZodBoolean;
|
|
43
|
+
signingIdentity: import("zod").ZodBoolean;
|
|
44
|
+
router: import("zod").ZodBoolean;
|
|
45
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
52
46
|
format: import("zod").ZodLiteral<"astrale.deployment.configuration">;
|
|
53
47
|
version: import("zod").ZodLiteral<1>;
|
|
54
48
|
vars: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>;
|
|
@@ -88,7 +82,34 @@ export declare const CloudflareDeployment: import("@astrale-os/sdk/schema").Auth
|
|
|
88
82
|
hostSuffix: import("zod").ZodString;
|
|
89
83
|
minLabels: import("zod").ZodNumber;
|
|
90
84
|
}, import("zod/v4/core").$strict>]>;
|
|
91
|
-
}, import("zod/v4/core").$strict>;
|
|
85
|
+
}, import("zod/v4/core").$strict>]>;
|
|
86
|
+
configurationDigest: import("@astrale-os/sdk/schema").AuthoredProperty<import("zod").ZodString, {
|
|
87
|
+
readonly required: false;
|
|
88
|
+
}>;
|
|
89
|
+
record: import("@astrale-os/sdk/schema").AuthoredProperty<import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
90
|
+
contentType: import("zod").ZodString;
|
|
91
|
+
contentBase64: import("zod").ZodString;
|
|
92
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
93
|
+
format: import("zod").ZodLiteral<"astrale.deployment-record">;
|
|
94
|
+
version: import("zod").ZodLiteral<1>;
|
|
95
|
+
origin: import("zod").ZodString;
|
|
96
|
+
environment: import("zod").ZodString;
|
|
97
|
+
releaseDigest: import("zod").ZodString;
|
|
98
|
+
buildDigest: import("zod").ZodString;
|
|
99
|
+
schemaRevision: import("zod").ZodString;
|
|
100
|
+
configuration: import("zod").ZodString;
|
|
101
|
+
providerScript: import("zod").ZodString;
|
|
102
|
+
commit: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
103
|
+
sha: import("zod").ZodString;
|
|
104
|
+
dirty: import("zod").ZodBoolean;
|
|
105
|
+
base: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
106
|
+
version: import("zod").ZodString;
|
|
107
|
+
distance: import("zod").ZodNumber;
|
|
108
|
+
}, import("zod/v4/core").$strict>>;
|
|
109
|
+
}, import("zod/v4/core").$strict>>;
|
|
110
|
+
}, import("zod/v4/core").$strict>]>, {
|
|
111
|
+
readonly required: false;
|
|
112
|
+
}>;
|
|
92
113
|
secretDigests: import("@astrale-os/sdk/schema").AuthoredProperty<import("zod").ZodArray<import("zod").ZodObject<{
|
|
93
114
|
name: import("zod").ZodString;
|
|
94
115
|
digest: import("zod").ZodString;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/**
|
|
3
|
-
* One immutable deployment of one Service: one build
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* One immutable deployment of one Service: one Worker build with its configuration, served by one
|
|
4
|
+
* script at its own URL. It never changes code; a new release is a new deployment of the
|
|
5
|
+
* same Service. Only its secrets rotate in place, under the names its configuration declares.
|
|
6
|
+
* Services knows nothing of what the Worker serves: the record it publishes is opaque bytes.
|
|
7
|
+
*
|
|
8
|
+
* LEGACY: a deployment created before Services hosted any Worker still stores the Domain's frozen
|
|
9
|
+
* configuration and record, and no build or configuration digest, until `CloudflareService.migrate`
|
|
10
|
+
* rewrites it; the next Schema revision admits the Worker form only.
|
|
7
11
|
*/
|
|
8
12
|
export declare const Deployment: import("@astrale-os/sdk/schema").AuthoredNodeClass<{
|
|
9
13
|
readonly abstract: true;
|
|
@@ -34,27 +38,22 @@ export declare const Deployment: import("@astrale-os/sdk/schema").AuthoredNodeCl
|
|
|
34
38
|
required?: boolean;
|
|
35
39
|
description?: string;
|
|
36
40
|
}>;
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
/** The build digest of the uploaded Worker, bound as `ASTRALE_BUILD_DIGEST`. */
|
|
42
|
+
buildDigest: import("@astrale-os/sdk/schema").AuthoredProperty<z.ZodString, {
|
|
43
|
+
readonly required: false;
|
|
44
|
+
}>;
|
|
45
|
+
/** The configuration frozen into this deployment. */
|
|
46
|
+
configuration: z.ZodUnion<readonly [z.ZodObject<{
|
|
47
|
+
format: z.ZodLiteral<"astrale.worker.configuration">;
|
|
39
48
|
version: z.ZodLiteral<1>;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
sha: z.ZodString;
|
|
49
|
-
dirty: z.ZodBoolean;
|
|
50
|
-
base: z.ZodOptional<z.ZodObject<{
|
|
51
|
-
version: z.ZodString;
|
|
52
|
-
distance: z.ZodNumber;
|
|
53
|
-
}, z.core.$strict>>;
|
|
54
|
-
}, z.core.$strict>>;
|
|
55
|
-
}, z.core.$strict>;
|
|
56
|
-
/** The configuration frozen into this deployment; its digest is `record.configuration`. */
|
|
57
|
-
configuration: z.ZodObject<{
|
|
49
|
+
compatibilityDate: z.ZodString;
|
|
50
|
+
compatibilityFlags: z.ZodArray<z.ZodString>;
|
|
51
|
+
vars: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
52
|
+
secrets: z.ZodArray<z.ZodString>;
|
|
53
|
+
record: z.ZodBoolean;
|
|
54
|
+
signingIdentity: z.ZodBoolean;
|
|
55
|
+
router: z.ZodBoolean;
|
|
56
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
58
57
|
format: z.ZodLiteral<"astrale.deployment.configuration">;
|
|
59
58
|
version: z.ZodLiteral<1>;
|
|
60
59
|
vars: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -94,7 +93,36 @@ export declare const Deployment: import("@astrale-os/sdk/schema").AuthoredNodeCl
|
|
|
94
93
|
hostSuffix: z.ZodString;
|
|
95
94
|
minLabels: z.ZodNumber;
|
|
96
95
|
}, z.core.$strict>]>;
|
|
97
|
-
}, z.core.$strict>;
|
|
96
|
+
}, z.core.$strict>]>;
|
|
97
|
+
/** The digest of `configuration` (`workerConfigurationDigest`). */
|
|
98
|
+
configurationDigest: import("@astrale-os/sdk/schema").AuthoredProperty<z.ZodString, {
|
|
99
|
+
readonly required: false;
|
|
100
|
+
}>;
|
|
101
|
+
/** The record the deployment publishes, when its configuration asks for one. */
|
|
102
|
+
record: import("@astrale-os/sdk/schema").AuthoredProperty<z.ZodUnion<readonly [z.ZodObject<{
|
|
103
|
+
contentType: z.ZodString;
|
|
104
|
+
contentBase64: z.ZodString;
|
|
105
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
106
|
+
format: z.ZodLiteral<"astrale.deployment-record">;
|
|
107
|
+
version: z.ZodLiteral<1>;
|
|
108
|
+
origin: z.ZodString;
|
|
109
|
+
environment: z.ZodString;
|
|
110
|
+
releaseDigest: z.ZodString;
|
|
111
|
+
buildDigest: z.ZodString;
|
|
112
|
+
schemaRevision: z.ZodString;
|
|
113
|
+
configuration: z.ZodString;
|
|
114
|
+
providerScript: z.ZodString;
|
|
115
|
+
commit: z.ZodNullable<z.ZodObject<{
|
|
116
|
+
sha: z.ZodString;
|
|
117
|
+
dirty: z.ZodBoolean;
|
|
118
|
+
base: z.ZodOptional<z.ZodObject<{
|
|
119
|
+
version: z.ZodString;
|
|
120
|
+
distance: z.ZodNumber;
|
|
121
|
+
}, z.core.$strict>>;
|
|
122
|
+
}, z.core.$strict>>;
|
|
123
|
+
}, z.core.$strict>]>, {
|
|
124
|
+
readonly required: false;
|
|
125
|
+
}>;
|
|
98
126
|
/** The keyed digest of each secret bound to this deployment, never a value. */
|
|
99
127
|
secretDigests: import("@astrale-os/sdk/schema").AuthoredProperty<z.ZodArray<z.ZodObject<{
|
|
100
128
|
name: z.ZodString;
|
|
@@ -109,6 +137,7 @@ export declare const Deployment: import("@astrale-os/sdk/schema").AuthoredNodeCl
|
|
|
109
137
|
scriptEtag: import("@astrale-os/sdk/schema").AuthoredProperty<z.ZodString, {
|
|
110
138
|
readonly required: false;
|
|
111
139
|
}>;
|
|
140
|
+
/** The thumbprint of the deployment's own key, when its configuration asks for one. */
|
|
112
141
|
signingKeyId: import("@astrale-os/sdk/schema").AuthoredProperty<z.ZodString, {
|
|
113
142
|
readonly required: false;
|
|
114
143
|
}>;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import { classIcon, K, nodeClass, property, schema as valueSchema, stateProperty, } from '@astrale-os/sdk/schema';
|
|
1
|
+
import { classIcon, fullMatch, K, nodeClass, property, schema as valueSchema, stateProperty, } from '@astrale-os/sdk/schema';
|
|
2
2
|
import { Rocket } from '@astrale-os/sdk/schema/icons';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { deploymentLifecycle } from '../states/index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { deploymentSecretDigests, legacyDeploymentRecord, legacyFrozenConfiguration, workerConfiguration, workerRecord, } from '../types/index.js';
|
|
6
|
+
const digest = z.string().check(fullMatch('sha256:[0-9a-f]{64}'));
|
|
6
7
|
/**
|
|
7
|
-
* One immutable deployment of one Service: one build
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* One immutable deployment of one Service: one Worker build with its configuration, served by one
|
|
9
|
+
* script at its own URL. It never changes code; a new release is a new deployment of the
|
|
10
|
+
* same Service. Only its secrets rotate in place, under the names its configuration declares.
|
|
11
|
+
* Services knows nothing of what the Worker serves: the record it publishes is opaque bytes.
|
|
12
|
+
*
|
|
13
|
+
* LEGACY: a deployment created before Services hosted any Worker still stores the Domain's frozen
|
|
14
|
+
* configuration and record, and no build or configuration digest, until `CloudflareService.migrate`
|
|
15
|
+
* rewrites it; the next Schema revision admits the Worker form only.
|
|
11
16
|
*/
|
|
12
17
|
export const Deployment = nodeClass({
|
|
13
18
|
abstract: true,
|
|
@@ -19,9 +24,14 @@ export const Deployment = nodeClass({
|
|
|
19
24
|
label: z.string().min(33).max(57),
|
|
20
25
|
url: z.string().min(1).max(2_048),
|
|
21
26
|
state: stateProperty(deploymentLifecycle),
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
configuration
|
|
27
|
+
/** The build digest of the uploaded Worker, bound as `ASTRALE_BUILD_DIGEST`. */
|
|
28
|
+
buildDigest: property(digest, { required: false }),
|
|
29
|
+
/** The configuration frozen into this deployment. */
|
|
30
|
+
configuration: z.union([workerConfiguration, legacyFrozenConfiguration]),
|
|
31
|
+
/** The digest of `configuration` (`workerConfigurationDigest`). */
|
|
32
|
+
configurationDigest: property(digest, { required: false }),
|
|
33
|
+
/** The record the deployment publishes, when its configuration asks for one. */
|
|
34
|
+
record: property(z.union([workerRecord, legacyDeploymentRecord]), { required: false }),
|
|
25
35
|
/** The keyed digest of each secret bound to this deployment, never a value. */
|
|
26
36
|
secretDigests: property(deploymentSecretDigests, { required: false }),
|
|
27
37
|
/**
|
|
@@ -29,6 +39,7 @@ export const Deployment = nodeClass({
|
|
|
29
39
|
* identifies the deployment; a secret rewritten in place keeps it, unlike a provider version.
|
|
30
40
|
*/
|
|
31
41
|
scriptEtag: property(z.string().min(1).max(128), { required: false }),
|
|
42
|
+
/** The thumbprint of the deployment's own key, when its configuration asks for one. */
|
|
32
43
|
signingKeyId: property(z.string().min(1).max(128), { required: false }),
|
|
33
44
|
activatedAt: property(valueSchema.values.instant, { required: false }),
|
|
34
45
|
retiredAt: property(valueSchema.values.instant, { required: false }),
|
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
export declare const retireDeployment: import("@astrale-os/sdk/schema").Method<import("@astrale-os/sdk/schema").CallableProjection<Record<string, never>, {
|
|
12
12
|
readonly mode: 'value';
|
|
13
13
|
readonly value: {
|
|
14
|
-
kind: "retired";
|
|
15
|
-
} | {
|
|
16
|
-
kind: "retiring";
|
|
17
|
-
retryAfterMs: number;
|
|
18
|
-
} | {
|
|
19
14
|
kind: "rejected";
|
|
20
15
|
reason: "address-mismatch" | "build-mismatch" | "deployment-conflict" | "deployment-retired" | "hosting-unavailable" | "invalid-deployment" | "service-owned-elsewhere" | "service-unavailable";
|
|
21
16
|
message: string;
|
|
22
17
|
retryAfter?: string | undefined;
|
|
18
|
+
} | {
|
|
19
|
+
kind: "retired";
|
|
20
|
+
} | {
|
|
21
|
+
kind: "retiring";
|
|
22
|
+
retryAfterMs: number;
|
|
23
23
|
};
|
|
24
24
|
}, "authenticated", false, false, undefined>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type {
|
|
1
|
+
export { deploymentHosting, deploymentRejection, deploymentRejectionReason, deploymentRequest, deploymentResponse, deploymentSecretDigest, deploymentSecretDigests, deploymentSecretRejection, deploymentSummary, legacyDeploymentRecord, legacyFrozenConfiguration, listDeploymentsInput, listDeploymentsOutput, migrateLegacyInput, migrateLegacyOutput, retireDeploymentInput, retireDeploymentOutput, workerConfiguration, workerRecord, } from './types/index.js';
|
|
2
|
+
export type { DeploymentHosting, DeploymentRejection, DeploymentRejectionReason, DeploymentRequest, DeploymentResponse, DeploymentSecretDigest, DeploymentSecretRejection, DeploymentSummary, LegacyDeploymentRecord, LegacyFrozenConfiguration, MigrateLegacyResult, RetireDeploymentResult, WorkerConfiguration, WorkerRecordWire, } from './types/index.js';
|
|
3
3
|
export { CloudflareDeployment, Deployment, current_deployment, deployment_of, } from './classes/index.js';
|
|
4
4
|
export { deploymentHostingUnavailable, deploymentNotFound } from './errors/index.js';
|
|
5
5
|
export { retireDeployment } from './functions/index.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Types first: the service module's Methods read them while this module's classes, which refer
|
|
2
2
|
// to the Service class, are still evaluating.
|
|
3
|
-
export {
|
|
3
|
+
export { deploymentHosting, deploymentRejection, deploymentRejectionReason, deploymentRequest, deploymentResponse, deploymentSecretDigest, deploymentSecretDigests, deploymentSecretRejection, deploymentSummary, legacyDeploymentRecord, legacyFrozenConfiguration, listDeploymentsInput, listDeploymentsOutput, migrateLegacyInput, migrateLegacyOutput, retireDeploymentInput, retireDeploymentOutput, workerConfiguration, workerRecord, } from './types/index.js';
|
|
4
4
|
export { CloudflareDeployment, Deployment, current_deployment, deployment_of, } from './classes/index.js';
|
|
5
5
|
export { deploymentHostingUnavailable, deploymentNotFound } from './errors/index.js';
|
|
6
6
|
export { retireDeployment } from './functions/index.js';
|
|
@@ -1,62 +1,27 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* `WorkerHostingV1`: the routing domain Services and deployments are addressed under. Every name is
|
|
4
|
+
* opaque: `https://<service>.<routing domain>` serves a Service, `https://<label>.<routing domain>`
|
|
5
|
+
* one deployment.
|
|
6
|
+
*/
|
|
3
7
|
export declare const deploymentHosting: z.ZodObject<{
|
|
4
8
|
routingDomain: z.ZodString;
|
|
5
|
-
addressing: z.ZodLiteral<"opaque">;
|
|
6
9
|
}, z.core.$strict>;
|
|
10
|
+
/** `WorkerDeploymentListRequestV1`: the caller's deployments, of one project or environment. */
|
|
7
11
|
export declare const listDeploymentsInput: z.ZodObject<{
|
|
8
|
-
|
|
12
|
+
project: z.ZodOptional<z.ZodString>;
|
|
9
13
|
environment: z.ZodOptional<z.ZodString>;
|
|
10
14
|
}, z.core.$strict>;
|
|
11
|
-
/**
|
|
12
|
-
* The deployments of the caller's Services. A deployment whose stored record or configuration this
|
|
13
|
-
* Services SDK no longer admits is listed from its facts with its record as stored, never dropped,
|
|
14
|
-
* and never fails the listing.
|
|
15
|
-
*/
|
|
15
|
+
/** The deployments of the caller's Services, by creation then label. */
|
|
16
16
|
export declare const listDeploymentsOutput: z.ZodObject<{
|
|
17
|
-
deployments: z.ZodArray<z.
|
|
18
|
-
id: z.ZodString;
|
|
19
|
-
url: z.ZodString;
|
|
20
|
-
label: z.ZodString;
|
|
21
|
-
serviceId: z.ZodString;
|
|
22
|
-
service: z.ZodString;
|
|
23
|
-
owner: z.ZodString;
|
|
24
|
-
state: z.ZodEnum<{
|
|
25
|
-
active: "active";
|
|
26
|
-
deploying: "deploying";
|
|
27
|
-
failed: "failed";
|
|
28
|
-
retired: "retired";
|
|
29
|
-
retiring: "retiring";
|
|
30
|
-
}>;
|
|
31
|
-
current: z.ZodBoolean;
|
|
32
|
-
createdAt: z.ZodString;
|
|
33
|
-
retiredAt: z.ZodOptional<z.ZodString>;
|
|
34
|
-
signingKeyId: z.ZodString;
|
|
35
|
-
record: z.ZodObject<{
|
|
36
|
-
format: z.ZodLiteral<"astrale.deployment-record">;
|
|
37
|
-
version: z.ZodLiteral<1>;
|
|
38
|
-
origin: z.ZodString;
|
|
39
|
-
environment: z.ZodString;
|
|
40
|
-
releaseDigest: z.ZodString;
|
|
41
|
-
buildDigest: z.ZodString;
|
|
42
|
-
schemaRevision: z.ZodString;
|
|
43
|
-
configuration: z.ZodString;
|
|
44
|
-
providerScript: z.ZodString;
|
|
45
|
-
commit: z.ZodNullable<z.ZodObject<{
|
|
46
|
-
sha: z.ZodString;
|
|
47
|
-
dirty: z.ZodBoolean;
|
|
48
|
-
base: z.ZodOptional<z.ZodObject<{
|
|
49
|
-
version: z.ZodString;
|
|
50
|
-
distance: z.ZodNumber;
|
|
51
|
-
}, z.core.$strict>>;
|
|
52
|
-
}, z.core.$strict>>;
|
|
53
|
-
}, z.core.$strict>;
|
|
54
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
17
|
+
deployments: z.ZodArray<z.ZodObject<{
|
|
55
18
|
id: z.ZodString;
|
|
56
19
|
url: z.ZodString;
|
|
57
20
|
label: z.ZodString;
|
|
58
21
|
serviceId: z.ZodString;
|
|
59
22
|
service: z.ZodString;
|
|
23
|
+
project: z.ZodString;
|
|
24
|
+
environment: z.ZodString;
|
|
60
25
|
owner: z.ZodString;
|
|
61
26
|
state: z.ZodEnum<{
|
|
62
27
|
active: "active";
|
|
@@ -68,8 +33,13 @@ export declare const listDeploymentsOutput: z.ZodObject<{
|
|
|
68
33
|
current: z.ZodBoolean;
|
|
69
34
|
createdAt: z.ZodString;
|
|
70
35
|
retiredAt: z.ZodOptional<z.ZodString>;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
36
|
+
buildDigest: z.ZodString;
|
|
37
|
+
configuration: z.ZodString;
|
|
38
|
+
signingKeyId: z.ZodOptional<z.ZodString>;
|
|
39
|
+
record: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
contentType: z.ZodString;
|
|
41
|
+
contentBase64: z.ZodString;
|
|
42
|
+
}, z.core.$strict>>;
|
|
43
|
+
}, z.core.$strict>>;
|
|
74
44
|
}, z.core.$strict>;
|
|
75
45
|
export type DeploymentHosting = z.output<typeof deploymentHosting>;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
/**
|
|
2
|
+
import { deploymentSummary } from './deployment-summary.js';
|
|
3
|
+
/**
|
|
4
|
+
* `WorkerHostingV1`: the routing domain Services and deployments are addressed under. Every name is
|
|
5
|
+
* opaque: `https://<service>.<routing domain>` serves a Service, `https://<label>.<routing domain>`
|
|
6
|
+
* one deployment.
|
|
7
|
+
*/
|
|
4
8
|
export const deploymentHosting = z.strictObject({
|
|
5
9
|
routingDomain: z.string().min(1).max(253),
|
|
6
|
-
addressing: z.literal('opaque'),
|
|
7
10
|
});
|
|
11
|
+
/** `WorkerDeploymentListRequestV1`: the caller's deployments, of one project or environment. */
|
|
8
12
|
export const listDeploymentsInput = z.strictObject({
|
|
9
|
-
|
|
13
|
+
project: z.string().min(1).max(253).optional(),
|
|
10
14
|
environment: z.string().min(1).max(63).optional(),
|
|
11
15
|
});
|
|
12
|
-
/**
|
|
13
|
-
* The deployments of the caller's Services. A deployment whose stored record or configuration this
|
|
14
|
-
* Services SDK no longer admits is listed from its facts with its record as stored, never dropped,
|
|
15
|
-
* and never fails the listing.
|
|
16
|
-
*/
|
|
16
|
+
/** The deployments of the caller's Services, by creation then label. */
|
|
17
17
|
export const listDeploymentsOutput = z.strictObject({
|
|
18
|
-
deployments: z.array(
|
|
18
|
+
deployments: z.array(deploymentSummary),
|
|
19
19
|
});
|