@hs-x/cli 0.3.0 → 0.3.7
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 +6 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +20 -49
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/kit.d.ts.map +1 -1
- package/dist/cli/kit.js +1 -1
- package/dist/cli/kit.js.map +1 -1
- package/dist/cloudflare-auth.d.ts +19 -0
- package/dist/cloudflare-auth.d.ts.map +1 -1
- package/dist/cloudflare-auth.js +83 -2
- package/dist/cloudflare-auth.js.map +1 -1
- package/dist/cloudflare-oauth.d.ts.map +1 -1
- package/dist/cloudflare-oauth.js +18 -19
- package/dist/cloudflare-oauth.js.map +1 -1
- package/dist/cloudflare-scoped-resource.d.ts +41 -0
- package/dist/cloudflare-scoped-resource.d.ts.map +1 -0
- package/dist/cloudflare-scoped-resource.js +74 -0
- package/dist/cloudflare-scoped-resource.js.map +1 -0
- package/dist/command-catalog.d.ts +13 -0
- package/dist/command-catalog.d.ts.map +1 -0
- package/dist/command-catalog.js +49 -0
- package/dist/command-catalog.js.map +1 -0
- package/dist/commands/account.d.ts +6 -6
- package/dist/commands/api.js +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +22 -34
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +97 -18
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/control-plane-read.d.ts +8 -8
- package/dist/commands/control-plane-read.d.ts.map +1 -1
- package/dist/commands/control-plane-read.js +2 -9
- package/dist/commands/control-plane-read.js.map +1 -1
- package/dist/commands/deploy-promote.d.ts +1 -1
- package/dist/commands/deploy-retry.d.ts +20 -0
- package/dist/commands/deploy-retry.d.ts.map +1 -0
- package/dist/commands/deploy-retry.js +106 -0
- package/dist/commands/deploy-retry.js.map +1 -0
- package/dist/commands/deploy.d.ts +14 -9
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +603 -294
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +43 -5
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/flags.d.ts +10 -5
- package/dist/commands/flags.d.ts.map +1 -1
- package/dist/commands/flags.js +208 -80
- package/dist/commands/flags.js.map +1 -1
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +41 -60
- package/dist/commands/help-command.js.map +1 -1
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +34 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/link.d.ts +1 -1
- package/dist/commands/link.d.ts.map +1 -1
- package/dist/commands/link.js +74 -15
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/migrate.d.ts +1 -1
- package/dist/commands/rollback.d.ts +1 -1
- package/dist/commands/secrets.d.ts +2 -2
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/validate.d.ts +2 -2
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/control-plane-tenant-provisioning.d.ts +24 -0
- package/dist/control-plane-tenant-provisioning.d.ts.map +1 -0
- package/dist/control-plane-tenant-provisioning.js +85 -0
- package/dist/control-plane-tenant-provisioning.js.map +1 -0
- package/dist/deploy-targets.d.ts +24 -0
- package/dist/deploy-targets.d.ts.map +1 -0
- package/dist/deploy-targets.js +38 -0
- package/dist/deploy-targets.js.map +1 -0
- package/dist/dev/compat-shim.d.ts +3 -3
- package/dist/dev/compat-shim.d.ts.map +1 -1
- package/dist/dev/compat-shim.js +28 -4
- package/dist/dev/compat-shim.js.map +1 -1
- package/dist/dev/invoke.d.ts +3 -4
- package/dist/dev/invoke.d.ts.map +1 -1
- package/dist/dev/invoke.js +9 -4
- package/dist/dev/invoke.js.map +1 -1
- package/dist/dev/loopback-http-listener.d.ts +18 -0
- package/dist/dev/loopback-http-listener.d.ts.map +1 -0
- package/dist/dev/loopback-http-listener.js +91 -0
- package/dist/dev/loopback-http-listener.js.map +1 -0
- package/dist/dev/session-manager.d.ts.map +1 -1
- package/dist/dev/session-manager.js +3 -2
- package/dist/dev/session-manager.js.map +1 -1
- package/dist/errors-registry.d.ts.map +1 -1
- package/dist/errors-registry.js +33 -0
- package/dist/errors-registry.js.map +1 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +20 -3
- package/dist/help.js.map +1 -1
- package/dist/init/templates.d.ts +1 -1
- package/dist/init/templates.d.ts.map +1 -1
- package/dist/init/templates.js +71 -1
- package/dist/init/templates.js.map +1 -1
- package/dist/machine-artifact.d.ts +16 -0
- package/dist/machine-artifact.d.ts.map +1 -0
- package/dist/machine-artifact.js +18 -0
- package/dist/machine-artifact.js.map +1 -0
- package/dist/machine-id.d.ts +15 -0
- package/dist/machine-id.d.ts.map +1 -1
- package/dist/machine-id.js +53 -0
- package/dist/machine-id.js.map +1 -1
- package/dist/mutation-consent.d.ts +20 -0
- package/dist/mutation-consent.d.ts.map +1 -0
- package/dist/mutation-consent.js +9 -0
- package/dist/mutation-consent.js.map +1 -0
- package/dist/output-context.d.ts +3 -0
- package/dist/output-context.d.ts.map +1 -1
- package/dist/output-context.js +6 -0
- package/dist/output-context.js.map +1 -1
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +123 -48
- package/dist/prompt.js.map +1 -1
- package/dist/reporter/index.js +1 -1
- package/dist/reporter/index.js.map +1 -1
- package/dist/reporter/style.d.ts.map +1 -1
- package/dist/reporter/style.js +5 -0
- package/dist/reporter/style.js.map +1 -1
- package/dist/services/live.d.ts +1 -1
- package/dist/services/telemetry.d.ts +1 -2
- package/dist/services/telemetry.d.ts.map +1 -1
- package/dist/services/telemetry.js +1 -10
- package/dist/services/telemetry.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +1 -7
- package/dist/telemetry.js.map +1 -1
- package/dist/tenant-data-plane-provisioning.d.ts +35 -0
- package/dist/tenant-data-plane-provisioning.d.ts.map +1 -0
- package/dist/tenant-data-plane-provisioning.js +38 -0
- package/dist/tenant-data-plane-provisioning.js.map +1 -0
- package/package.json +11 -11
- package/dist/cloudflare-worker-versions.d.ts +0 -184
- package/dist/cloudflare-worker-versions.d.ts.map +0 -1
- package/dist/cloudflare-worker-versions.js +0 -360
- package/dist/cloudflare-worker-versions.js.map +0 -1
- package/dist/rollback-traffic.d.ts +0 -85
- package/dist/rollback-traffic.d.ts.map +0 -1
- package/dist/rollback-traffic.js +0 -204
- package/dist/rollback-traffic.js.map +0 -1
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cloudflare Worker Versions/Deployments adapter (ADR-021).
|
|
3
|
-
*
|
|
4
|
-
* Rollback = point traffic at a retained Worker version via Cloudflare's
|
|
5
|
-
* native Versions/Deployments API. This module is the single place HS-X
|
|
6
|
-
* talks to that API surface: deploy capture (R03) records version ids from
|
|
7
|
-
* it, and rollback (R04) creates 100% deployments through it.
|
|
8
|
-
*
|
|
9
|
-
* API references (shapes confirmed 2026-07-14):
|
|
10
|
-
* - Versions: https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/versions/
|
|
11
|
-
* - List: GET /accounts/{account_id}/workers/scripts/{script_name}/versions
|
|
12
|
-
* response `result.items` (latest first; `?deployable=true` filter, `page`/`per_page`)
|
|
13
|
-
* https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/versions/methods/list/
|
|
14
|
-
* - Get: GET .../versions/{version_id} (full metadata + annotations + resources)
|
|
15
|
-
* - Deployments: https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/deployments/
|
|
16
|
-
* - List: GET .../deployments — response `result.deployments`, first entry is the
|
|
17
|
-
* ACTIVE deployment
|
|
18
|
-
* https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/deployments/methods/list/
|
|
19
|
-
* - Create: POST .../deployments (optional `?force=true`) with body
|
|
20
|
-
* `{ strategy: "percentage", versions: [{ percentage, version_id }], annotations? }`
|
|
21
|
-
* - Get: GET .../deployments/{deployment_id}
|
|
22
|
-
* - Concepts: https://developers.cloudflare.com/workers/configuration/versions-and-deployments/
|
|
23
|
-
*
|
|
24
|
-
* The only caller-settable deployment annotation is `workers/message` (max 1000
|
|
25
|
-
* bytes); `workers/triggered_by` is read-only (Cloudflare rejects it, HTTP 400
|
|
26
|
-
* code 10210). So the idempotency tag AND the trigger context both ride in
|
|
27
|
-
* `workers/message` — `[hsx-op:<operationId>] [<triggeredBy>] <message>`.
|
|
28
|
-
* `reconcileDeployment` recovers a previously-applied deployment by that tag
|
|
29
|
-
* after an ambiguous (timeout/5xx) create response.
|
|
30
|
-
*
|
|
31
|
-
* The adapter takes account id + script name verbatim and never invents
|
|
32
|
-
* names or ids: every version/deployment id it returns came from Cloudflare.
|
|
33
|
-
*/
|
|
34
|
-
export class CloudflareWorkerVersionsError extends Error {
|
|
35
|
-
detail;
|
|
36
|
-
status;
|
|
37
|
-
constructor(message, detail, status) {
|
|
38
|
-
super(message);
|
|
39
|
-
this.detail = detail;
|
|
40
|
-
this.status = status;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/** 401/403 (or Cloudflare "Authentication error" code 10000) from the API. */
|
|
44
|
-
export class CloudflareWorkerAuthFailedError extends CloudflareWorkerVersionsError {
|
|
45
|
-
code = 'HSX_E_CLOUDFLARE_AUTH_FAILED';
|
|
46
|
-
constructor(detail, status) {
|
|
47
|
-
super('Cloudflare rejected the API credential for the Worker Versions API.', detail, status);
|
|
48
|
-
this.name = 'CloudflareWorkerAuthFailedError';
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
/** The Worker script does not exist on this account. */
|
|
52
|
-
export class CloudflareScriptNotFoundError extends CloudflareWorkerVersionsError {
|
|
53
|
-
code = 'HSX_E_CLOUDFLARE_SCRIPT_NOT_FOUND';
|
|
54
|
-
scriptName;
|
|
55
|
-
constructor(scriptName, detail, status) {
|
|
56
|
-
super(`Cloudflare Worker script "${scriptName}" was not found.`, detail, status);
|
|
57
|
-
this.name = 'CloudflareScriptNotFoundError';
|
|
58
|
-
this.scriptName = scriptName;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
/** The target version id does not exist (or is not deployable) for this script. */
|
|
62
|
-
export class CloudflareVersionNotFoundError extends CloudflareWorkerVersionsError {
|
|
63
|
-
code = 'HSX_E_CLOUDFLARE_VERSION_NOT_FOUND';
|
|
64
|
-
versionId;
|
|
65
|
-
constructor(versionId, detail, status) {
|
|
66
|
-
super(`Cloudflare Worker version "${versionId}" was not found or is not deployable.`, detail, status);
|
|
67
|
-
this.name = 'CloudflareVersionNotFoundError';
|
|
68
|
-
this.versionId = versionId;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* A deployment create got an ambiguous response (network failure, timeout, or
|
|
73
|
-
* 5xx AFTER the POST was sent): Cloudflare may or may not have applied it.
|
|
74
|
-
* Callers must NOT blindly retry a raw POST — call `reconcileDeployment`
|
|
75
|
-
* (or `createDeployment` again, which reconciles first) with the same
|
|
76
|
-
* `operationId` to discover whether the deployment took effect.
|
|
77
|
-
*/
|
|
78
|
-
export class CloudflareDeploymentAmbiguousError extends CloudflareWorkerVersionsError {
|
|
79
|
-
code = 'HSX_E_CLOUDFLARE_DEPLOYMENT_AMBIGUOUS';
|
|
80
|
-
operationId;
|
|
81
|
-
versionId;
|
|
82
|
-
constructor(input) {
|
|
83
|
-
super('Cloudflare returned an ambiguous response while creating a Worker deployment; it may or may not have been applied. Reconcile with the same operation id before retrying.', input.detail, input.status);
|
|
84
|
-
this.name = 'CloudflareDeploymentAmbiguousError';
|
|
85
|
-
this.operationId = input.operationId;
|
|
86
|
-
this.versionId = input.versionId;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/** Any other API failure (unexpected 4xx, malformed body, transport error on reads). */
|
|
90
|
-
export class CloudflareVersionsApiError extends CloudflareWorkerVersionsError {
|
|
91
|
-
code = 'HSX_E_CLOUDFLARE_VERSIONS_API';
|
|
92
|
-
constructor(detail, status) {
|
|
93
|
-
super('Cloudflare Worker Versions API request failed.', detail, status);
|
|
94
|
-
this.name = 'CloudflareVersionsApiError';
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
// ---------------------------------------------------------------------------
|
|
98
|
-
// Idempotency tag helpers
|
|
99
|
-
// ---------------------------------------------------------------------------
|
|
100
|
-
const OPERATION_ID_PATTERN = /^[A-Za-z0-9._-]{1,64}$/;
|
|
101
|
-
const OPERATION_TAG_PATTERN = /\[hsx-op:([A-Za-z0-9._-]{1,64})\]/;
|
|
102
|
-
/** `workers/message` is truncated by Cloudflare at 1000 bytes; stay under it. */
|
|
103
|
-
const MAX_MESSAGE_BYTES = 1000;
|
|
104
|
-
export function formatOperationTag(operationId) {
|
|
105
|
-
if (!OPERATION_ID_PATTERN.test(operationId)) {
|
|
106
|
-
throw new Error(`operationId must match ${String(OPERATION_ID_PATTERN)} (got ${JSON.stringify(operationId)})`);
|
|
107
|
-
}
|
|
108
|
-
return `[hsx-op:${operationId}]`;
|
|
109
|
-
}
|
|
110
|
-
export function parseOperationTag(message) {
|
|
111
|
-
if (!message)
|
|
112
|
-
return undefined;
|
|
113
|
-
const match = OPERATION_TAG_PATTERN.exec(message);
|
|
114
|
-
return match?.[1];
|
|
115
|
-
}
|
|
116
|
-
function buildDeploymentMessage(operationId, message, triggeredBy) {
|
|
117
|
-
const tag = formatOperationTag(operationId);
|
|
118
|
-
// Cloudflare rejects a caller-set `workers/triggered_by` annotation (HTTP 400
|
|
119
|
-
// code 10210 — it is read-only, set by Cloudflare), so carry the trigger
|
|
120
|
-
// context inside `workers/message` instead. The tag stays at the very front:
|
|
121
|
-
// reconcile keys on it, so it must never be truncated.
|
|
122
|
-
const prefix = triggeredBy ? `${tag} [${triggeredBy}]` : tag;
|
|
123
|
-
if (!message)
|
|
124
|
-
return prefix;
|
|
125
|
-
const full = `${prefix} ${message}`;
|
|
126
|
-
if (Buffer.byteLength(full, 'utf8') <= MAX_MESSAGE_BYTES)
|
|
127
|
-
return full;
|
|
128
|
-
let trimmed = message;
|
|
129
|
-
while (trimmed.length > 0 &&
|
|
130
|
-
Buffer.byteLength(`${prefix} ${trimmed}`, 'utf8') > MAX_MESSAGE_BYTES) {
|
|
131
|
-
trimmed = trimmed.slice(0, -1);
|
|
132
|
-
}
|
|
133
|
-
return trimmed.length > 0 ? `${prefix} ${trimmed}` : prefix;
|
|
134
|
-
}
|
|
135
|
-
/** Cloudflare "workers.api.error.script_not_found". */
|
|
136
|
-
const CF_CODE_SCRIPT_NOT_FOUND = 10007;
|
|
137
|
-
/** Cloudflare "Authentication error". */
|
|
138
|
-
const CF_CODE_AUTH_ERROR = 10000;
|
|
139
|
-
export function createWorkerVersionsClient(input) {
|
|
140
|
-
const fetchImpl = input.fetchImpl ?? fetch;
|
|
141
|
-
const baseUrl = input.baseUrl ?? 'https://api.cloudflare.com';
|
|
142
|
-
const scriptRoot = `/client/v4/accounts/${encodeURIComponent(input.accountId)}/workers/scripts/${encodeURIComponent(input.scriptName)}`;
|
|
143
|
-
/**
|
|
144
|
-
* Execute a request and parse the standard Cloudflare envelope. Transport
|
|
145
|
-
* failures (fetch throw / timeout) are NOT caught here — create-deployment
|
|
146
|
-
* needs to classify them as ambiguous, reads classify them as API errors.
|
|
147
|
-
*/
|
|
148
|
-
const request = async (path, init = {}) => {
|
|
149
|
-
const response = await fetchImpl(new URL(path, baseUrl), {
|
|
150
|
-
...init,
|
|
151
|
-
headers: {
|
|
152
|
-
authorization: `Bearer ${input.apiToken}`,
|
|
153
|
-
accept: 'application/json',
|
|
154
|
-
...(init.body ? { 'content-type': 'application/json' } : {}),
|
|
155
|
-
...(init.headers ?? {}),
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
const rawText = await response.text().catch(() => '');
|
|
159
|
-
let body = {};
|
|
160
|
-
try {
|
|
161
|
-
body = rawText ? JSON.parse(rawText) : {};
|
|
162
|
-
}
|
|
163
|
-
catch {
|
|
164
|
-
body = {};
|
|
165
|
-
}
|
|
166
|
-
return { status: response.status, body, rawText };
|
|
167
|
-
};
|
|
168
|
-
const errorDetail = (response, fallback) => {
|
|
169
|
-
const messages = (response.body.errors ?? [])
|
|
170
|
-
.map((error) => (error.message ? `${error.code ?? ''} ${error.message}`.trim() : undefined))
|
|
171
|
-
.filter((message) => Boolean(message));
|
|
172
|
-
if (messages.length > 0)
|
|
173
|
-
return `HTTP ${response.status}: ${messages.join('; ')}`;
|
|
174
|
-
if (response.rawText)
|
|
175
|
-
return `HTTP ${response.status}: ${response.rawText.slice(0, 300)}`;
|
|
176
|
-
return `HTTP ${response.status}: ${fallback}`;
|
|
177
|
-
};
|
|
178
|
-
const isAuthFailure = (response) => response.status === 401 ||
|
|
179
|
-
response.status === 403 ||
|
|
180
|
-
(response.body.errors ?? []).some((error) => error.code === CF_CODE_AUTH_ERROR);
|
|
181
|
-
const isScriptNotFound = (response) => (response.body.errors ?? []).some((error) => error.code === CF_CODE_SCRIPT_NOT_FOUND ||
|
|
182
|
-
/script.*not.?found|workers\.api\.error\.script_not_found/i.test(error.message ?? ''));
|
|
183
|
-
const succeeded = (response) => response.status >= 200 && response.status < 300 && response.body.success !== false;
|
|
184
|
-
/** Shared classification for read paths (list/get). */
|
|
185
|
-
const throwReadError = (response, context) => {
|
|
186
|
-
if (isAuthFailure(response)) {
|
|
187
|
-
throw new CloudflareWorkerAuthFailedError(errorDetail(response, 'authentication failed'), response.status);
|
|
188
|
-
}
|
|
189
|
-
if (isScriptNotFound(response)) {
|
|
190
|
-
throw new CloudflareScriptNotFoundError(input.scriptName, errorDetail(response, 'script not found'), response.status);
|
|
191
|
-
}
|
|
192
|
-
if (context.versionId && response.status === 404) {
|
|
193
|
-
throw new CloudflareVersionNotFoundError(context.versionId, errorDetail(response, 'version not found'), response.status);
|
|
194
|
-
}
|
|
195
|
-
throw new CloudflareVersionsApiError(errorDetail(response, 'request failed'), response.status);
|
|
196
|
-
};
|
|
197
|
-
const asRecord = (value) => typeof value === 'object' && value !== null ? value : {};
|
|
198
|
-
const asString = (value) => typeof value === 'string' ? value : undefined;
|
|
199
|
-
const asAnnotations = (value) => {
|
|
200
|
-
const record = asRecord(value);
|
|
201
|
-
const entries = Object.entries(record).filter((entry) => typeof entry[1] === 'string');
|
|
202
|
-
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
203
|
-
};
|
|
204
|
-
const normalizeVersion = (raw) => {
|
|
205
|
-
const record = asRecord(raw);
|
|
206
|
-
const metadata = asRecord(record.metadata);
|
|
207
|
-
const annotations = asAnnotations(record.annotations);
|
|
208
|
-
const id = asString(record.id);
|
|
209
|
-
if (!id) {
|
|
210
|
-
throw new CloudflareVersionsApiError('Cloudflare returned a version without an id.');
|
|
211
|
-
}
|
|
212
|
-
return {
|
|
213
|
-
id,
|
|
214
|
-
...(typeof record.number === 'number' ? { number: record.number } : {}),
|
|
215
|
-
...(asString(metadata.created_on) ? { createdOn: asString(metadata.created_on) } : {}),
|
|
216
|
-
...(asString(metadata.source) ? { source: asString(metadata.source) } : {}),
|
|
217
|
-
...(asString(metadata.author_email) ? { authorEmail: asString(metadata.author_email) } : {}),
|
|
218
|
-
...(annotations?.['workers/message'] ? { message: annotations['workers/message'] } : {}),
|
|
219
|
-
...(annotations?.['workers/tag'] ? { tag: annotations['workers/tag'] } : {}),
|
|
220
|
-
...(annotations ? { annotations } : {}),
|
|
221
|
-
...('resources' in record ? { resources: record.resources } : {}),
|
|
222
|
-
};
|
|
223
|
-
};
|
|
224
|
-
const normalizeDeployment = (raw) => {
|
|
225
|
-
const record = asRecord(raw);
|
|
226
|
-
const id = asString(record.id);
|
|
227
|
-
if (!id) {
|
|
228
|
-
throw new CloudflareVersionsApiError('Cloudflare returned a deployment without an id.');
|
|
229
|
-
}
|
|
230
|
-
const annotations = asAnnotations(record.annotations);
|
|
231
|
-
const versions = Array.isArray(record.versions)
|
|
232
|
-
? record.versions.flatMap((entry) => {
|
|
233
|
-
const version = asRecord(entry);
|
|
234
|
-
const versionId = asString(version.version_id);
|
|
235
|
-
return versionId ? [{ versionId, percentage: Number(version.percentage ?? 0) }] : [];
|
|
236
|
-
})
|
|
237
|
-
: [];
|
|
238
|
-
const operationId = parseOperationTag(annotations?.['workers/message']);
|
|
239
|
-
return {
|
|
240
|
-
id,
|
|
241
|
-
strategy: asString(record.strategy) ?? 'percentage',
|
|
242
|
-
versions,
|
|
243
|
-
...(asString(record.created_on) ? { createdOn: asString(record.created_on) } : {}),
|
|
244
|
-
...(asString(record.source) ? { source: asString(record.source) } : {}),
|
|
245
|
-
...(asString(record.author_email) ? { authorEmail: asString(record.author_email) } : {}),
|
|
246
|
-
...(annotations ? { annotations } : {}),
|
|
247
|
-
...(operationId ? { operationId } : {}),
|
|
248
|
-
};
|
|
249
|
-
};
|
|
250
|
-
const listDeployments = async () => {
|
|
251
|
-
const response = await request(`${scriptRoot}/deployments`);
|
|
252
|
-
if (!succeeded(response))
|
|
253
|
-
throwReadError(response, {});
|
|
254
|
-
const result = asRecord(response.body.result);
|
|
255
|
-
const deployments = Array.isArray(result.deployments) ? result.deployments : [];
|
|
256
|
-
return deployments.map(normalizeDeployment);
|
|
257
|
-
};
|
|
258
|
-
const reconcileDeployment = async (operationId) => {
|
|
259
|
-
const tag = formatOperationTag(operationId);
|
|
260
|
-
const deployments = await listDeployments();
|
|
261
|
-
return deployments.find((deployment) => (deployment.annotations?.['workers/message'] ?? '').includes(tag));
|
|
262
|
-
};
|
|
263
|
-
return {
|
|
264
|
-
async listVersions(options) {
|
|
265
|
-
const url = new URL(`${scriptRoot}/versions`, baseUrl);
|
|
266
|
-
if (options?.deployable !== undefined) {
|
|
267
|
-
url.searchParams.set('deployable', String(options.deployable));
|
|
268
|
-
}
|
|
269
|
-
if (options?.page !== undefined)
|
|
270
|
-
url.searchParams.set('page', String(options.page));
|
|
271
|
-
if (options?.perPage !== undefined)
|
|
272
|
-
url.searchParams.set('per_page', String(options.perPage));
|
|
273
|
-
const response = await request(`${url.pathname}${url.search}`);
|
|
274
|
-
if (!succeeded(response))
|
|
275
|
-
throwReadError(response, {});
|
|
276
|
-
const result = asRecord(response.body.result);
|
|
277
|
-
const items = Array.isArray(result.items) ? result.items : [];
|
|
278
|
-
return items.map(normalizeVersion);
|
|
279
|
-
},
|
|
280
|
-
async getVersion(versionId) {
|
|
281
|
-
const response = await request(`${scriptRoot}/versions/${encodeURIComponent(versionId)}`);
|
|
282
|
-
if (!succeeded(response))
|
|
283
|
-
throwReadError(response, { versionId });
|
|
284
|
-
return normalizeVersion(response.body.result);
|
|
285
|
-
},
|
|
286
|
-
async createDeployment(deploymentInput) {
|
|
287
|
-
const { versionId, operationId } = deploymentInput;
|
|
288
|
-
const message = buildDeploymentMessage(operationId, deploymentInput.message, deploymentInput.triggeredBy);
|
|
289
|
-
// Reconcile-before-create: if a prior attempt with this operationId
|
|
290
|
-
// already applied (e.g. we got an ambiguous 500/timeout and the caller
|
|
291
|
-
// retried), return that deployment instead of double-applying.
|
|
292
|
-
const existing = await reconcileDeployment(operationId);
|
|
293
|
-
if (existing)
|
|
294
|
-
return { deployment: existing, alreadyApplied: true };
|
|
295
|
-
const path = `${scriptRoot}/deployments${deploymentInput.force ? '?force=true' : ''}`;
|
|
296
|
-
let response;
|
|
297
|
-
try {
|
|
298
|
-
response = await request(path, {
|
|
299
|
-
method: 'POST',
|
|
300
|
-
body: JSON.stringify({
|
|
301
|
-
strategy: 'percentage',
|
|
302
|
-
versions: [{ percentage: 100, version_id: versionId }],
|
|
303
|
-
annotations: {
|
|
304
|
-
'workers/message': message,
|
|
305
|
-
},
|
|
306
|
-
}),
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
catch (error) {
|
|
310
|
-
// Transport failure AFTER the POST left the process: Cloudflare may
|
|
311
|
-
// have applied it. Distinguishable so R04 reconciles, never blind-retries.
|
|
312
|
-
throw new CloudflareDeploymentAmbiguousError({
|
|
313
|
-
operationId,
|
|
314
|
-
versionId,
|
|
315
|
-
detail: error instanceof Error ? error.message : String(error),
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
if (succeeded(response)) {
|
|
319
|
-
return { deployment: normalizeDeployment(response.body.result), alreadyApplied: false };
|
|
320
|
-
}
|
|
321
|
-
if (response.status >= 500) {
|
|
322
|
-
// 5xx after a POST is ambiguous: the deployment may have been applied
|
|
323
|
-
// before the error was produced.
|
|
324
|
-
throw new CloudflareDeploymentAmbiguousError({
|
|
325
|
-
operationId,
|
|
326
|
-
versionId,
|
|
327
|
-
detail: errorDetail(response, 'deployment create returned a server error'),
|
|
328
|
-
status: response.status,
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
if (isAuthFailure(response)) {
|
|
332
|
-
throw new CloudflareWorkerAuthFailedError(errorDetail(response, 'authentication failed'), response.status);
|
|
333
|
-
}
|
|
334
|
-
if (isScriptNotFound(response)) {
|
|
335
|
-
throw new CloudflareScriptNotFoundError(input.scriptName, errorDetail(response, 'script not found'), response.status);
|
|
336
|
-
}
|
|
337
|
-
// Definitive 4xx: a missing/incompatible target version is the expected
|
|
338
|
-
// failure ("could not find version" / "not deployable").
|
|
339
|
-
if ((response.body.errors ?? []).some((error) => /version.*(not.?found|does not exist|not deployable)|could not find version/i.test(error.message ?? ''))) {
|
|
340
|
-
throw new CloudflareVersionNotFoundError(versionId, errorDetail(response, 'target version not found'), response.status);
|
|
341
|
-
}
|
|
342
|
-
throw new CloudflareVersionsApiError(errorDetail(response, 'deployment create failed'), response.status);
|
|
343
|
-
},
|
|
344
|
-
async getDeployment(deploymentId) {
|
|
345
|
-
const response = await request(`${scriptRoot}/deployments/${encodeURIComponent(deploymentId)}`);
|
|
346
|
-
if (!succeeded(response))
|
|
347
|
-
throwReadError(response, {});
|
|
348
|
-
return normalizeDeployment(response.body.result);
|
|
349
|
-
},
|
|
350
|
-
listDeployments,
|
|
351
|
-
async getActiveDeployment() {
|
|
352
|
-
// Cloudflare lists deployments with the active deployment first:
|
|
353
|
-
// https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/deployments/methods/list/
|
|
354
|
-
const deployments = await listDeployments();
|
|
355
|
-
return deployments[0];
|
|
356
|
-
},
|
|
357
|
-
reconcileDeployment,
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
//# sourceMappingURL=cloudflare-worker-versions.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare-worker-versions.js","sourceRoot":"","sources":["../src/cloudflare-worker-versions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Traffic-first rollback orchestration (ADR-021 R04).
|
|
3
|
-
*
|
|
4
|
-
* A rollback restores live Cloudflare traffic to a verified prior Worker
|
|
5
|
-
* *version* BEFORE any control-plane record moves. Given a membership-gated
|
|
6
|
-
* {@link DeployRollbackPlan} (which already resolved the target, confirmed it
|
|
7
|
-
* carries a real Cloudflare version, enforced the force gate, and minted the
|
|
8
|
-
* deterministic operation id), this drives the data-plane change through the
|
|
9
|
-
* R01 Worker Versions/Deployments adapter and returns the verbatim
|
|
10
|
-
* {@link RollbackOperation} outcome the CLI then commits to the control plane:
|
|
11
|
-
*
|
|
12
|
-
* 1. read the current active deployment (the restore point);
|
|
13
|
-
* 2. create a 100% deployment of the target version (idempotent by
|
|
14
|
-
* operation id — a retry reconciles instead of double-applying);
|
|
15
|
-
* 3. health-probe the now-live deployment;
|
|
16
|
-
* 4a. probe OK → status `applied` (or `ambiguous-reconciled` when the
|
|
17
|
-
* create response was ambiguous and we reconciled to the applied
|
|
18
|
-
* deployment). The commit advances the CP active pointer.
|
|
19
|
-
* 4b. probe FAILS → restore traffic to the pre-rollback version and
|
|
20
|
-
* report status `probe-failed-restored`. The CP pointer is NOT advanced.
|
|
21
|
-
* 4c. no traffic ever changed (missing/incompatible target, create rejected,
|
|
22
|
-
* or an ambiguous create that reconciled to nothing) → status `failed`.
|
|
23
|
-
* The CP pointer is NOT advanced.
|
|
24
|
-
*
|
|
25
|
-
* This module never fabricates a version or deployment id — every id it records
|
|
26
|
-
* came verbatim from Cloudflare (or the injected fake) through the adapter.
|
|
27
|
-
*/
|
|
28
|
-
import type { DeployRollbackPlan, RollbackOperation } from '@hs-x/types';
|
|
29
|
-
import { type CloudflareWorkerVersionsClient, type WorkerDeployment } from './cloudflare-worker-versions.js';
|
|
30
|
-
export interface TrafficRollbackProbeInput {
|
|
31
|
-
readonly client: CloudflareWorkerVersionsClient;
|
|
32
|
-
/** The deployment the rollback just created (or reconciled to). */
|
|
33
|
-
readonly deployment: WorkerDeployment;
|
|
34
|
-
/** The target Cloudflare version id traffic should now serve. */
|
|
35
|
-
readonly versionId: string;
|
|
36
|
-
readonly scriptName: string;
|
|
37
|
-
readonly cloudflareAccountId: string;
|
|
38
|
-
}
|
|
39
|
-
/** Health-probe the now-live deployment. `ok:false` triggers a restore. */
|
|
40
|
-
export type TrafficRollbackProbe = (input: TrafficRollbackProbeInput) => Promise<{
|
|
41
|
-
readonly ok: boolean;
|
|
42
|
-
readonly detail?: string;
|
|
43
|
-
}>;
|
|
44
|
-
export interface TrafficRollbackDeps {
|
|
45
|
-
/** Injection seam for tests / alternate transports (default: the R01 HTTP adapter). */
|
|
46
|
-
readonly createClient?: (input: {
|
|
47
|
-
readonly accountId: string;
|
|
48
|
-
readonly scriptName: string;
|
|
49
|
-
readonly apiToken: string;
|
|
50
|
-
}) => CloudflareWorkerVersionsClient;
|
|
51
|
-
/** Health probe (default: confirm the target version now serves 100% of traffic). */
|
|
52
|
-
readonly probe?: TrafficRollbackProbe;
|
|
53
|
-
readonly fetchImpl?: typeof fetch;
|
|
54
|
-
/** Cloudflare API base URL for the default adapter (default: https://api.cloudflare.com). */
|
|
55
|
-
readonly baseUrl?: string;
|
|
56
|
-
/** ISO-8601 clock; defaults to `new Date().toISOString()`. */
|
|
57
|
-
readonly now?: () => string;
|
|
58
|
-
}
|
|
59
|
-
export interface TrafficRollbackInput {
|
|
60
|
-
readonly plan: DeployRollbackPlan;
|
|
61
|
-
/** Cloudflare API token for the tenant account that owns the Worker. */
|
|
62
|
-
readonly apiToken: string;
|
|
63
|
-
/** Bypass the binding-compatibility gate and Cloudflare deploy safeguards. */
|
|
64
|
-
readonly force: boolean;
|
|
65
|
-
}
|
|
66
|
-
export interface TrafficRollbackOutcome {
|
|
67
|
-
readonly operation: RollbackOperation;
|
|
68
|
-
/** True iff live traffic now serves the target version (`applied` | `ambiguous-reconciled`). */
|
|
69
|
-
readonly ok: boolean;
|
|
70
|
-
readonly liveVersionId?: string;
|
|
71
|
-
readonly liveDeploymentId?: string;
|
|
72
|
-
/** Version traffic was restored to after a failed probe (when a restore point existed). */
|
|
73
|
-
readonly restoredVersionId?: string;
|
|
74
|
-
/** True when the target deployment was found already-applied via reconcile (idempotent retry). */
|
|
75
|
-
readonly alreadyApplied: boolean;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Default health probe: confirm through Cloudflare that the created deployment
|
|
79
|
-
* is the active one and the target version now serves 100% of traffic. This is
|
|
80
|
-
* a real edge-state check (not a content probe); R05's live E2E layers an
|
|
81
|
-
* authenticated HTTP request to the Worker on top via a custom `probe`.
|
|
82
|
-
*/
|
|
83
|
-
export declare const defaultTrafficRollbackProbe: TrafficRollbackProbe;
|
|
84
|
-
export declare function runTrafficRollback(deps: TrafficRollbackDeps, input: TrafficRollbackInput): Promise<TrafficRollbackOutcome>;
|
|
85
|
-
//# sourceMappingURL=rollback-traffic.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rollback-traffic.d.ts","sourceRoot":"","sources":["../src/rollback-traffic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAEL,KAAK,8BAA8B,EAGnC,KAAK,gBAAgB,EAEtB,MAAM,iCAAiC,CAAC;AAEzC,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,8BAA8B,CAAC;IAChD,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC;IACtC,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAED,2EAA2E;AAC3E,MAAM,MAAM,oBAAoB,GAAG,CACjC,KAAK,EAAE,yBAAyB,KAC7B,OAAO,CAAC;IAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,uFAAuF;IACvF,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE;QAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,KAAK,8BAA8B,CAAC;IACrC,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,6FAA6F;IAC7F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,gGAAgG;IAChG,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,2FAA2F;IAC3F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,kGAAkG;IAClG,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,EAAE,oBAezC,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,mBAAmB,EACzB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,sBAAsB,CAAC,CA6JjC"}
|