run402 1.55.0 → 1.57.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 +13 -0
- package/lib/deploy-v2.mjs +258 -8
- package/lib/deploy.mjs +53 -8
- package/lib/secrets.mjs +15 -7
- package/package.json +1 -1
- package/sdk/dist/index.d.ts +1 -1
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/namespaces/apps.d.ts +11 -4
- package/sdk/dist/namespaces/apps.d.ts.map +1 -1
- package/sdk/dist/namespaces/apps.js +73 -9
- package/sdk/dist/namespaces/apps.js.map +1 -1
- package/sdk/dist/namespaces/ci.d.ts.map +1 -1
- package/sdk/dist/namespaces/ci.js +3 -0
- package/sdk/dist/namespaces/ci.js.map +1 -1
- package/sdk/dist/namespaces/deploy.d.ts +31 -9
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +143 -22
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +200 -13
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/secrets.d.ts +3 -2
- package/sdk/dist/namespaces/secrets.d.ts.map +1 -1
- package/sdk/dist/namespaces/secrets.js +45 -5
- package/sdk/dist/namespaces/secrets.js.map +1 -1
- package/sdk/dist/node/index.d.ts +1 -1
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/scoped.d.ts +6 -6
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +15 -4
- package/sdk/dist/scoped.js.map +1 -1
- package/sdk/dist/type-contract.d.ts +2 -0
- package/sdk/dist/type-contract.d.ts.map +1 -0
- package/sdk/dist/type-contract.js +2 -0
- package/sdk/dist/type-contract.js.map +1 -0
package/README.md
CHANGED
|
@@ -57,10 +57,13 @@ run402 projects schema <id> # introspect tables + R
|
|
|
57
57
|
```bash
|
|
58
58
|
run402 sites deploy-dir ./dist # incremental upload (plan/commit transport)
|
|
59
59
|
run402 deploy --manifest app.json # one-call full stack deploy
|
|
60
|
+
run402 deploy release active # inspect current-live release inventory
|
|
61
|
+
run402 deploy release diff --from empty --to active
|
|
60
62
|
run402 subdomains claim my-app # → my-app.run402.com (auto-reassigns on next deploy)
|
|
61
63
|
```
|
|
62
64
|
|
|
63
65
|
`deploy-dir` hashes each file client-side and only uploads bytes the gateway doesn't already have. Re-deploying an unchanged tree returns immediately with `bytes_uploaded: 0`. Progress events stream to stderr.
|
|
66
|
+
Release inspection commands print `{ status: "ok", release: ... }` or `{ status: "ok", diff: ... }`; use them after deploys to compare release inventory without starting another mutation.
|
|
64
67
|
|
|
65
68
|
### GitHub Actions OIDC deploys
|
|
66
69
|
|
|
@@ -119,6 +122,16 @@ import { db, adminDb, getUser, email, ai } from "@run402/functions";
|
|
|
119
122
|
|
|
120
123
|
`db(req)` is the caller-context client (RLS applies); `adminDb()` bypasses RLS for platform-authored writes.
|
|
121
124
|
|
|
125
|
+
### Secrets
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
run402 secrets set <id> OPENAI_API_KEY --file ./.secrets/openai-key
|
|
129
|
+
run402 secrets list <id>
|
|
130
|
+
run402 deploy apply --manifest run402.deploy.json # manifest uses secrets.require, not values
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Secret values are write-only. `list` returns keys and timestamps only; deploy manifests should declare dependencies with `secrets.require` and never contain values.
|
|
134
|
+
|
|
122
135
|
### Email
|
|
123
136
|
|
|
124
137
|
```bash
|
package/lib/deploy-v2.mjs
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* "project_id": "...",
|
|
12
12
|
* "base": { "release": "current" } | { "release": "empty" } | { "release_id": "..." },
|
|
13
13
|
* "database": { "migrations": [...], "expose": {...}, "zero_downtime": false },
|
|
14
|
-
* "secrets": { "
|
|
14
|
+
* "secrets": { "require": ["OPENAI_API_KEY"], "delete": ["OLD_KEY"] },
|
|
15
15
|
* "functions": { "replace": {...}, "patch": { "set": {...}, "delete": [...] } },
|
|
16
16
|
* "site": { "replace": {...} } | { "patch": { "put": {...}, "delete": [...] } },
|
|
17
17
|
* "subdomains": { "set": ["..."], "add": [...], "remove": [...] },
|
|
@@ -33,8 +33,8 @@ import { API, allowanceAuthHeaders, getActiveProjectId, resolveProjectId } from
|
|
|
33
33
|
const APPLY_HELP = `run402 deploy apply — Unified deploy primitive (v1.34+)
|
|
34
34
|
|
|
35
35
|
Usage:
|
|
36
|
-
run402 deploy apply --manifest <path> [--project <id>] [--quiet]
|
|
37
|
-
run402 deploy apply --spec '<json>' [--project <id>] [--quiet]
|
|
36
|
+
run402 deploy apply --manifest <path> [--project <id>] [--quiet] [--allow-warnings]
|
|
37
|
+
run402 deploy apply --spec '<json>' [--project <id>] [--quiet] [--allow-warnings]
|
|
38
38
|
cat spec.json | run402 deploy apply [--project <id>]
|
|
39
39
|
|
|
40
40
|
Manifest format mirrors the MCP \`deploy\` tool's ReleaseSpec:
|
|
@@ -42,7 +42,7 @@ Manifest format mirrors the MCP \`deploy\` tool's ReleaseSpec:
|
|
|
42
42
|
"project_id": "prj_...",
|
|
43
43
|
"base": { "release": "current" },
|
|
44
44
|
"database": { "migrations": [{ "id": "001_init", "sql": "CREATE TABLE ..." }], "expose": {...} },
|
|
45
|
-
"secrets": { "
|
|
45
|
+
"secrets": { "require": ["OPENAI_API_KEY"], "delete": ["OLD_KEY"] },
|
|
46
46
|
"functions": { "replace": { "api": { "source": { "data": "export default ..." } } } },
|
|
47
47
|
"site": { "replace": { "index.html": { "data": "<html>..." } } },
|
|
48
48
|
"subdomains": { "set": ["my-app"] }
|
|
@@ -53,11 +53,18 @@ Options:
|
|
|
53
53
|
--spec '<json>' Inline JSON spec (single-quote in shell)
|
|
54
54
|
--project <id> Override project_id from the manifest
|
|
55
55
|
--quiet Suppress per-event JSON-line stderr (final result still on stdout)
|
|
56
|
+
--allow-warnings Continue past plan warnings that require confirmation
|
|
56
57
|
|
|
57
58
|
Output:
|
|
58
|
-
stdout: { "status": "ok", "release_id": "rel_...", "operation_id": "op_...", "urls": {...} }
|
|
59
|
+
stdout: { "status": "ok", "release_id": "rel_...", "operation_id": "op_...", "urls": {...}, "warnings": [...] }
|
|
59
60
|
stderr: one JSON event per line (suppressed with --quiet)
|
|
60
61
|
|
|
62
|
+
Secrets:
|
|
63
|
+
Secret values do not belong in deploy manifests. Set them first:
|
|
64
|
+
run402 secrets set prj_... OPENAI_API_KEY --file ./.secrets/openai-key
|
|
65
|
+
Then deploy a value-free declaration:
|
|
66
|
+
{ "project_id": "prj_...", "secrets": { "require": ["OPENAI_API_KEY"] } }
|
|
67
|
+
|
|
61
68
|
Patch examples (only the listed file changes):
|
|
62
69
|
{ "project_id": "prj_...", "site": { "patch": { "put": { "index.html": { "data": "..." } } } } }
|
|
63
70
|
{ "project_id": "prj_...", "site": { "patch": { "delete": ["old.html"] } } }
|
|
@@ -103,11 +110,70 @@ Output:
|
|
|
103
110
|
stdout: { "status": "ok", "events": [...] }
|
|
104
111
|
`;
|
|
105
112
|
|
|
113
|
+
const RELEASE_HELP = `run402 deploy release — Inspect deploy release inventory and diffs
|
|
114
|
+
|
|
115
|
+
Usage:
|
|
116
|
+
run402 deploy release get <release_id> [--project <id>] [--site-limit <n>]
|
|
117
|
+
run402 deploy release active [--project <id>] [--site-limit <n>]
|
|
118
|
+
run402 deploy release diff --from <empty|active|release_id> --to <active|release_id> [--project <id>] [--limit <n>]
|
|
119
|
+
|
|
120
|
+
Subcommands:
|
|
121
|
+
get Fetch the inventory for a specific release id
|
|
122
|
+
active Fetch the current-live release inventory for the project
|
|
123
|
+
diff Diff two release targets
|
|
124
|
+
|
|
125
|
+
Output:
|
|
126
|
+
get/active: { "status": "ok", "release": {...} }
|
|
127
|
+
diff: { "status": "ok", "diff": {...} }
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
const RELEASE_GET_HELP = `run402 deploy release get — Fetch a release inventory by id
|
|
131
|
+
|
|
132
|
+
Usage:
|
|
133
|
+
run402 deploy release get <release_id> [--project <id>] [--site-limit <n>]
|
|
134
|
+
|
|
135
|
+
Options:
|
|
136
|
+
--project <id> Project ID that owns the release (default: active project)
|
|
137
|
+
--site-limit <n> Maximum site path entries to include (gateway default: 5000)
|
|
138
|
+
|
|
139
|
+
Output:
|
|
140
|
+
stdout: { "status": "ok", "release": {...} }
|
|
141
|
+
`;
|
|
142
|
+
|
|
143
|
+
const RELEASE_ACTIVE_HELP = `run402 deploy release active — Fetch the active release inventory
|
|
144
|
+
|
|
145
|
+
Usage:
|
|
146
|
+
run402 deploy release active [--project <id>] [--site-limit <n>]
|
|
147
|
+
|
|
148
|
+
Options:
|
|
149
|
+
--project <id> Project ID to inspect (default: active project)
|
|
150
|
+
--site-limit <n> Maximum site path entries to include (gateway default: 5000)
|
|
151
|
+
|
|
152
|
+
Output:
|
|
153
|
+
stdout: { "status": "ok", "release": {...} }
|
|
154
|
+
`;
|
|
155
|
+
|
|
156
|
+
const RELEASE_DIFF_HELP = `run402 deploy release diff — Diff two release targets
|
|
157
|
+
|
|
158
|
+
Usage:
|
|
159
|
+
run402 deploy release diff --from <empty|active|release_id> --to <active|release_id> [--project <id>] [--limit <n>]
|
|
160
|
+
|
|
161
|
+
Options:
|
|
162
|
+
--from <target> Diff source: empty, active, or rel_...
|
|
163
|
+
--to <target> Diff target: active or rel_...
|
|
164
|
+
--project <id> Project ID to inspect (default: active project)
|
|
165
|
+
--limit <n> Maximum entries per site diff bucket (gateway default: 1000)
|
|
166
|
+
|
|
167
|
+
Output:
|
|
168
|
+
stdout: { "status": "ok", "diff": {...} }
|
|
169
|
+
`;
|
|
170
|
+
|
|
106
171
|
export async function runDeployV2(sub, args) {
|
|
107
172
|
if (sub === "apply") return await applyCmd(args);
|
|
108
173
|
if (sub === "resume") return await resumeCmd(args);
|
|
109
174
|
if (sub === "list") return await listCmd(args);
|
|
110
175
|
if (sub === "events") return await eventsCmd(args);
|
|
176
|
+
if (sub === "release") return await releaseCmd(args);
|
|
111
177
|
fail({
|
|
112
178
|
code: "BAD_USAGE",
|
|
113
179
|
message: `Unknown deploy subcommand: ${sub}`,
|
|
@@ -129,13 +195,14 @@ function makeStderrEventWriter(quiet) {
|
|
|
129
195
|
}
|
|
130
196
|
|
|
131
197
|
async function applyCmd(args) {
|
|
132
|
-
const opts = { manifest: null, spec: null, project: null, quiet: false };
|
|
198
|
+
const opts = { manifest: null, spec: null, project: null, quiet: false, allowWarnings: false };
|
|
133
199
|
for (let i = 0; i < args.length; i++) {
|
|
134
200
|
if (args[i] === "--help" || args[i] === "-h") { console.log(APPLY_HELP); process.exit(0); }
|
|
135
201
|
if (args[i] === "--manifest" && args[i + 1]) { opts.manifest = args[++i]; continue; }
|
|
136
202
|
if (args[i] === "--spec" && args[i + 1]) { opts.spec = args[++i]; continue; }
|
|
137
203
|
if (args[i] === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
138
204
|
if (args[i] === "--quiet") { opts.quiet = true; continue; }
|
|
205
|
+
if (args[i] === "--allow-warnings") { opts.allowWarnings = true; continue; }
|
|
139
206
|
}
|
|
140
207
|
|
|
141
208
|
let raw;
|
|
@@ -166,6 +233,10 @@ async function applyCmd(args) {
|
|
|
166
233
|
details: { source: opts.manifest ? "manifest" : opts.spec ? "spec" : "stdin", parse_error: err.message },
|
|
167
234
|
});
|
|
168
235
|
}
|
|
236
|
+
rejectLegacySecretManifest(spec, {
|
|
237
|
+
source: opts.manifest ? "manifest" : opts.spec ? "spec" : "stdin",
|
|
238
|
+
...(opts.manifest ? { path: resolve(opts.manifest) } : {}),
|
|
239
|
+
});
|
|
169
240
|
|
|
170
241
|
// GH-232: Reject empty specs client-side. Without this guard,
|
|
171
242
|
// `run402 deploy apply --spec '{}'` (and `--manifest <empty>`) would silently
|
|
@@ -241,6 +312,7 @@ async function applyCmd(args) {
|
|
|
241
312
|
const result = await getSdk(sdkOpts).deploy.apply(releaseSpec, {
|
|
242
313
|
onEvent: makeStderrEventWriter(opts.quiet),
|
|
243
314
|
idempotencyKey,
|
|
315
|
+
allowWarnings: opts.allowWarnings,
|
|
244
316
|
});
|
|
245
317
|
console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
|
|
246
318
|
} catch (err) {
|
|
@@ -320,8 +392,43 @@ const CI_DEPLOY_ERROR_GUIDANCE = {
|
|
|
320
392
|
};
|
|
321
393
|
|
|
322
394
|
function reportDeployApplyError(err, useGithubActionsOidc) {
|
|
323
|
-
|
|
324
|
-
return reportSdkError(
|
|
395
|
+
const warningEnhanced = enhanceDeployWarningError(err);
|
|
396
|
+
if (!useGithubActionsOidc) return reportSdkError(warningEnhanced);
|
|
397
|
+
return reportSdkError(enhanceCiDeployError(warningEnhanced));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function enhanceDeployWarningError(err) {
|
|
401
|
+
const existingBody = err?.body && typeof err.body === "object" && !Array.isArray(err.body)
|
|
402
|
+
? err.body
|
|
403
|
+
: {};
|
|
404
|
+
const warnings = Array.isArray(existingBody.warnings) ? existingBody.warnings : null;
|
|
405
|
+
const code = existingBody.code || err?.code || null;
|
|
406
|
+
if (!warnings && code !== "MISSING_REQUIRED_SECRET") return err;
|
|
407
|
+
|
|
408
|
+
const enhanced = Object.assign(new Error(err?.message || existingBody.message || String(code)), err);
|
|
409
|
+
const affected = warnings
|
|
410
|
+
? warnings.flatMap((w) => Array.isArray(w?.affected) ? w.affected : [])
|
|
411
|
+
: [];
|
|
412
|
+
enhanced.body = {
|
|
413
|
+
...existingBody,
|
|
414
|
+
code: code || "DEPLOY_WARNING_REQUIRES_CONFIRMATION",
|
|
415
|
+
message: existingBody.message || err?.message || "Deploy plan returned warnings that require confirmation.",
|
|
416
|
+
hint: existingBody.hint ||
|
|
417
|
+
(code === "MISSING_REQUIRED_SECRET"
|
|
418
|
+
? "Set the missing secret values with `run402 secrets set`, then retry deploy apply. Use --allow-warnings only after explicit review."
|
|
419
|
+
: "Review the plan warnings, then retry with --allow-warnings if you intentionally accept them."),
|
|
420
|
+
next_actions: Array.isArray(existingBody.next_actions) && existingBody.next_actions.length > 0
|
|
421
|
+
? existingBody.next_actions
|
|
422
|
+
: [
|
|
423
|
+
...(affected.length > 0
|
|
424
|
+
? [`Set or inspect affected secrets: ${Array.from(new Set(affected)).join(", ")}`]
|
|
425
|
+
: []),
|
|
426
|
+
"Retry `run402 deploy apply` after resolving warnings.",
|
|
427
|
+
"Use `--allow-warnings` only when the warning was explicitly reviewed.",
|
|
428
|
+
],
|
|
429
|
+
...(warnings ? { warnings } : {}),
|
|
430
|
+
};
|
|
431
|
+
return enhanced;
|
|
325
432
|
}
|
|
326
433
|
|
|
327
434
|
function enhanceCiDeployError(err) {
|
|
@@ -345,6 +452,37 @@ function enhanceCiDeployError(err) {
|
|
|
345
452
|
return enhanced;
|
|
346
453
|
}
|
|
347
454
|
|
|
455
|
+
function rejectLegacySecretManifest(spec, details) {
|
|
456
|
+
if (!spec || typeof spec !== "object" || Array.isArray(spec)) return;
|
|
457
|
+
const secrets = spec.secrets;
|
|
458
|
+
if (secrets === undefined) return;
|
|
459
|
+
if (Array.isArray(secrets) && secrets.length > 0) {
|
|
460
|
+
fail({
|
|
461
|
+
code: "UNSAFE_SECRET_MANIFEST",
|
|
462
|
+
message: "Deploy manifests must not contain secret values. Legacy secrets arrays are no longer supported by deploy apply.",
|
|
463
|
+
hint: "Run `run402 secrets set <project> <KEY> --file <path>` first, then use `\"secrets\": { \"require\": [\"KEY\"] }` in the deploy manifest.",
|
|
464
|
+
details: { ...details, field: "secrets", legacy_shape: "array" },
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
if (typeof secrets !== "object" || secrets === null) return;
|
|
468
|
+
if (Object.prototype.hasOwnProperty.call(secrets, "set")) {
|
|
469
|
+
fail({
|
|
470
|
+
code: "UNSAFE_SECRET_MANIFEST",
|
|
471
|
+
message: "Deploy manifests must not use secrets.set. Secret values are write-only and must be set outside deploy specs.",
|
|
472
|
+
hint: "Run `run402 secrets set <project> <KEY> --file <path>` first, then use `\"secrets\": { \"require\": [\"KEY\"] }`.",
|
|
473
|
+
details: { ...details, field: "secrets.set" },
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
if (Object.prototype.hasOwnProperty.call(secrets, "replace_all")) {
|
|
477
|
+
fail({
|
|
478
|
+
code: "UNSAFE_SECRET_MANIFEST",
|
|
479
|
+
message: "Deploy manifests must not use secrets.replace_all. Exact replacement is not representable in the value-free deploy contract.",
|
|
480
|
+
hint: "Use `secrets.require` for keys that must exist and `secrets.delete` for explicit removals.",
|
|
481
|
+
details: { ...details, field: "secrets.replace_all" },
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
348
486
|
async function resumeCmd(args) {
|
|
349
487
|
const opts = { operationId: null, quiet: false };
|
|
350
488
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -419,6 +557,118 @@ async function eventsCmd(args) {
|
|
|
419
557
|
}
|
|
420
558
|
}
|
|
421
559
|
|
|
560
|
+
async function releaseCmd(args) {
|
|
561
|
+
const action = args[0];
|
|
562
|
+
if (!action || action === "--help" || action === "-h") {
|
|
563
|
+
console.log(RELEASE_HELP);
|
|
564
|
+
process.exit(0);
|
|
565
|
+
}
|
|
566
|
+
if (action === "get") return await releaseGetCmd(args.slice(1));
|
|
567
|
+
if (action === "active") return await releaseActiveCmd(args.slice(1));
|
|
568
|
+
if (action === "diff") return await releaseDiffCmd(args.slice(1));
|
|
569
|
+
fail({
|
|
570
|
+
code: "BAD_USAGE",
|
|
571
|
+
message: `Unknown deploy release subcommand: ${action}`,
|
|
572
|
+
details: { subcommand: action },
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
async function releaseGetCmd(args) {
|
|
577
|
+
const opts = { releaseId: null, project: null, siteLimit: null };
|
|
578
|
+
for (let i = 0; i < args.length; i++) {
|
|
579
|
+
if (args[i] === "--help" || args[i] === "-h") { console.log(RELEASE_GET_HELP); process.exit(0); }
|
|
580
|
+
if (args[i] === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
581
|
+
if (args[i] === "--site-limit" && args[i + 1]) { opts.siteLimit = parsePositiveInt(args[++i], "--site-limit"); continue; }
|
|
582
|
+
if (!args[i].startsWith("-") && !opts.releaseId) opts.releaseId = args[i];
|
|
583
|
+
}
|
|
584
|
+
if (!opts.releaseId) {
|
|
585
|
+
fail({
|
|
586
|
+
code: "BAD_USAGE",
|
|
587
|
+
message: "Missing <release_id>.",
|
|
588
|
+
hint: "run402 deploy release get <release_id>",
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const project = resolveProjectId(opts.project);
|
|
593
|
+
|
|
594
|
+
try {
|
|
595
|
+
const sdkOpts = { project };
|
|
596
|
+
if (opts.siteLimit !== null) sdkOpts.siteLimit = opts.siteLimit;
|
|
597
|
+
const release = await getSdk().deploy.getRelease(opts.releaseId, sdkOpts);
|
|
598
|
+
console.log(JSON.stringify({ status: "ok", release }, null, 2));
|
|
599
|
+
} catch (err) {
|
|
600
|
+
reportSdkError(err);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
async function releaseActiveCmd(args) {
|
|
605
|
+
const opts = { project: null, siteLimit: null };
|
|
606
|
+
for (let i = 0; i < args.length; i++) {
|
|
607
|
+
if (args[i] === "--help" || args[i] === "-h") { console.log(RELEASE_ACTIVE_HELP); process.exit(0); }
|
|
608
|
+
if (args[i] === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
609
|
+
if (args[i] === "--site-limit" && args[i + 1]) { opts.siteLimit = parsePositiveInt(args[++i], "--site-limit"); continue; }
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
const project = resolveProjectId(opts.project);
|
|
613
|
+
|
|
614
|
+
try {
|
|
615
|
+
const sdkOpts = { project };
|
|
616
|
+
if (opts.siteLimit !== null) sdkOpts.siteLimit = opts.siteLimit;
|
|
617
|
+
const release = await getSdk().deploy.getActiveRelease(sdkOpts);
|
|
618
|
+
console.log(JSON.stringify({ status: "ok", release }, null, 2));
|
|
619
|
+
} catch (err) {
|
|
620
|
+
reportSdkError(err);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
async function releaseDiffCmd(args) {
|
|
625
|
+
const opts = { project: null, from: null, to: null, limit: null };
|
|
626
|
+
for (let i = 0; i < args.length; i++) {
|
|
627
|
+
if (args[i] === "--help" || args[i] === "-h") { console.log(RELEASE_DIFF_HELP); process.exit(0); }
|
|
628
|
+
if (args[i] === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
629
|
+
if (args[i] === "--from" && args[i + 1]) { opts.from = args[++i]; continue; }
|
|
630
|
+
if (args[i] === "--to" && args[i + 1]) { opts.to = args[++i]; continue; }
|
|
631
|
+
if (args[i] === "--limit" && args[i + 1]) { opts.limit = parsePositiveInt(args[++i], "--limit"); continue; }
|
|
632
|
+
}
|
|
633
|
+
if (!opts.from || !opts.to) {
|
|
634
|
+
fail({
|
|
635
|
+
code: "BAD_USAGE",
|
|
636
|
+
message: "Missing --from or --to release target.",
|
|
637
|
+
hint: "run402 deploy release diff --from empty --to active",
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
if (opts.to === "empty") {
|
|
641
|
+
fail({
|
|
642
|
+
code: "BAD_USAGE",
|
|
643
|
+
message: "--to cannot be empty. Use active or a release id.",
|
|
644
|
+
details: { flag: "--to", value: opts.to },
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const project = resolveProjectId(opts.project);
|
|
649
|
+
|
|
650
|
+
try {
|
|
651
|
+
const sdkOpts = { project, from: opts.from, to: opts.to };
|
|
652
|
+
if (opts.limit !== null) sdkOpts.limit = opts.limit;
|
|
653
|
+
const diff = await getSdk().deploy.diff(sdkOpts);
|
|
654
|
+
console.log(JSON.stringify({ status: "ok", diff }, null, 2));
|
|
655
|
+
} catch (err) {
|
|
656
|
+
reportSdkError(err);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
function parsePositiveInt(value, flag) {
|
|
661
|
+
const parsed = Number(value);
|
|
662
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
663
|
+
fail({
|
|
664
|
+
code: "BAD_USAGE",
|
|
665
|
+
message: `${flag} must be a positive integer.`,
|
|
666
|
+
details: { flag, value },
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
return parsed;
|
|
670
|
+
}
|
|
671
|
+
|
|
422
672
|
// ─── Manifest → ReleaseSpec ──────────────────────────────────────────────────
|
|
423
673
|
|
|
424
674
|
function mapManifestToReleaseSpec(spec) {
|
package/lib/deploy.mjs
CHANGED
|
@@ -21,6 +21,7 @@ Subcommands (recommended for new manifests):
|
|
|
21
21
|
run402 deploy resume <operation_id> resume a stuck operation
|
|
22
22
|
run402 deploy list [--project <id>] list recent deploy operations
|
|
23
23
|
run402 deploy events <operation_id> fetch event stream for an operation
|
|
24
|
+
run402 deploy release ... inspect release inventory and diffs
|
|
24
25
|
|
|
25
26
|
Manifest format (JSON, v2 ReleaseSpec — recommended):
|
|
26
27
|
{
|
|
@@ -36,7 +37,7 @@ Manifest format (JSON, v2 ReleaseSpec — recommended):
|
|
|
36
37
|
]
|
|
37
38
|
}
|
|
38
39
|
},
|
|
39
|
-
"secrets": { "
|
|
40
|
+
"secrets": { "require": ["OPENAI_API_KEY"], "delete": ["OLD_KEY"] },
|
|
40
41
|
"functions": {
|
|
41
42
|
"replace": {
|
|
42
43
|
"api": {
|
|
@@ -63,9 +64,13 @@ Manifest format (JSON, v2 ReleaseSpec — recommended):
|
|
|
63
64
|
Replace vs patch semantics per resource:
|
|
64
65
|
"site": { "replace": {...} } whole-site (omitted files removed)
|
|
65
66
|
"site": { "patch": { "put": {...}, "delete": [...] } } surgical updates
|
|
66
|
-
Same for "functions"
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
Same for "functions". Secrets are value-free declarations:
|
|
68
|
+
"secrets": { "require": ["OPENAI_API_KEY"], "delete": ["OLD_KEY"] }
|
|
69
|
+
Secret values must be set outside deploy manifests with:
|
|
70
|
+
run402 secrets set prj_... OPENAI_API_KEY --file ./.secrets/openai-key
|
|
71
|
+
Migrations are always additive (each is keyed by id; re-shipping the same
|
|
72
|
+
id+sql is a registry noop, same id with different sql is a hard
|
|
73
|
+
MIGRATION_CHECKSUM_MISMATCH error).
|
|
69
74
|
|
|
70
75
|
File entries accept inline "data", a local "path", or a "sql_path"
|
|
71
76
|
(migrations only) — paths are resolved relative to the manifest file's
|
|
@@ -94,12 +99,14 @@ Manifest format (JSON, v2 ReleaseSpec — recommended):
|
|
|
94
99
|
⚠️ Without an "expose" entry, tables are unreachable via anon_key.
|
|
95
100
|
|
|
96
101
|
Legacy v1 bundle format (still accepted via compatibility shim):
|
|
97
|
-
Existing manifests with top-level "migrations" (string), "
|
|
98
|
-
"
|
|
102
|
+
Existing manifests with top-level "migrations" (string), "functions" (array),
|
|
103
|
+
"files" (array), "subdomain" (string), and the
|
|
99
104
|
"files[].file/data/path" + inline "manifest.json" entry continue to work —
|
|
100
105
|
the SDK translates them into a v2 ReleaseSpec under the hood. Prefer the
|
|
101
106
|
v2 shape above for new manifests; the legacy form is preserved for the
|
|
102
|
-
deprecation window so existing scripts don't break.
|
|
107
|
+
deprecation window so existing scripts don't break. Legacy file manifests
|
|
108
|
+
with secret values no longer deploy: run 'run402 secrets set' first, then
|
|
109
|
+
use 'run402 deploy apply' with 'secrets.require'.
|
|
103
110
|
|
|
104
111
|
"migrations_file": "setup.sql" (legacy convenience) reads SQL from disk
|
|
105
112
|
relative to the manifest file. Useful when JSONB literals make inline
|
|
@@ -224,6 +231,11 @@ async function loadManifest(opts) {
|
|
|
224
231
|
});
|
|
225
232
|
}
|
|
226
233
|
|
|
234
|
+
rejectUnsafeSecretManifest(manifest, {
|
|
235
|
+
source: opts.manifest ? "manifest" : "stdin",
|
|
236
|
+
...(opts.manifest ? { path: resolve(opts.manifest) } : {}),
|
|
237
|
+
});
|
|
238
|
+
|
|
227
239
|
if (opts.manifest) {
|
|
228
240
|
try {
|
|
229
241
|
resolveMigrationsFile(manifest, baseDir);
|
|
@@ -255,19 +267,52 @@ async function loadManifest(opts) {
|
|
|
255
267
|
return manifest;
|
|
256
268
|
}
|
|
257
269
|
|
|
270
|
+
function rejectUnsafeSecretManifest(manifest, details) {
|
|
271
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) return;
|
|
272
|
+
const secrets = manifest.secrets;
|
|
273
|
+
if (secrets === undefined) return;
|
|
274
|
+
if (Array.isArray(secrets) && secrets.length > 0) {
|
|
275
|
+
fail({
|
|
276
|
+
code: "UNSAFE_SECRET_MANIFEST",
|
|
277
|
+
message: "Deploy manifests must not contain secret values. Legacy top-level secrets arrays are no longer supported.",
|
|
278
|
+
hint: "Run `run402 secrets set <project> <KEY> --file <path>` first, then use `run402 deploy apply` with `\"secrets\": { \"require\": [\"KEY\"] }`.",
|
|
279
|
+
details: { ...details, field: "secrets", legacy_shape: "array" },
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (!secrets || typeof secrets !== "object" || Array.isArray(secrets)) return;
|
|
283
|
+
if (Object.prototype.hasOwnProperty.call(secrets, "set")) {
|
|
284
|
+
fail({
|
|
285
|
+
code: "UNSAFE_SECRET_MANIFEST",
|
|
286
|
+
message: "Deploy manifests must not use secrets.set. Secret values are write-only and must be set outside deploy specs.",
|
|
287
|
+
hint: "Run `run402 secrets set <project> <KEY> --file <path>` first, then deploy with `\"secrets\": { \"require\": [\"KEY\"] }`.",
|
|
288
|
+
details: { ...details, field: "secrets.set" },
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
if (Object.prototype.hasOwnProperty.call(secrets, "replace_all")) {
|
|
292
|
+
fail({
|
|
293
|
+
code: "UNSAFE_SECRET_MANIFEST",
|
|
294
|
+
message: "Deploy manifests must not use secrets.replace_all. Exact replacement is not representable in the value-free deploy contract.",
|
|
295
|
+
hint: "Use `secrets.require` for keys that must exist and `secrets.delete` for explicit removals.",
|
|
296
|
+
details: { ...details, field: "secrets.replace_all" },
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
258
301
|
export async function run(args) {
|
|
259
302
|
// Subcommand dispatch (v1.34+):
|
|
260
303
|
// run402 deploy apply ... → unified deploy primitive (deploy.apply)
|
|
261
304
|
// run402 deploy resume <op> → resume an activation_pending operation
|
|
262
305
|
// run402 deploy list → list recent deploy operations
|
|
263
306
|
// run402 deploy events <op> → fetch recorded event stream for an operation
|
|
307
|
+
// run402 deploy release ... → release inventory/diff observability
|
|
264
308
|
// run402 deploy --manifest … → legacy bundle deploy (routes through v2)
|
|
265
309
|
const sub = args[0];
|
|
266
310
|
switch (sub) {
|
|
267
311
|
case "apply":
|
|
268
312
|
case "resume":
|
|
269
313
|
case "list":
|
|
270
|
-
case "events":
|
|
314
|
+
case "events":
|
|
315
|
+
case "release": {
|
|
271
316
|
const { runDeployV2 } = await import("./deploy-v2.mjs");
|
|
272
317
|
await runDeployV2(sub, args.slice(1));
|
|
273
318
|
return;
|
package/lib/secrets.mjs
CHANGED
|
@@ -14,14 +14,15 @@ Subcommands:
|
|
|
14
14
|
delete <id> <key> Delete a secret from a project
|
|
15
15
|
|
|
16
16
|
Examples:
|
|
17
|
-
run402 secrets set prj_abc123 STRIPE_KEY
|
|
17
|
+
run402 secrets set prj_abc123 STRIPE_KEY --file ./.secrets/stripe-key
|
|
18
18
|
run402 secrets set prj_abc123 TLS_CERT --file cert.pem
|
|
19
19
|
run402 secrets list prj_abc123
|
|
20
20
|
run402 secrets delete prj_abc123 STRIPE_KEY
|
|
21
21
|
|
|
22
22
|
Notes:
|
|
23
23
|
- Secrets are injected as process.env in serverless functions
|
|
24
|
-
- Values are write-only — list returns keys
|
|
24
|
+
- Values are write-only — list returns keys and timestamps only
|
|
25
|
+
- Deploy manifests should declare existing keys with secrets.require; never put values in deploy specs
|
|
25
26
|
`;
|
|
26
27
|
|
|
27
28
|
const SUB_HELP = {
|
|
@@ -41,10 +42,11 @@ Options:
|
|
|
41
42
|
|
|
42
43
|
Notes:
|
|
43
44
|
- Secrets are injected as process.env in serverless functions
|
|
44
|
-
- Values are write-only; 'list'
|
|
45
|
+
- Values are write-only; 'list' cannot verify values by hash
|
|
46
|
+
- Prefer --file for real secrets so values do not land in shell history
|
|
45
47
|
|
|
46
48
|
Examples:
|
|
47
|
-
run402 secrets set prj_abc123 STRIPE_KEY
|
|
49
|
+
run402 secrets set prj_abc123 STRIPE_KEY --file ./.secrets/stripe-key
|
|
48
50
|
run402 secrets set prj_abc123 TLS_CERT --file cert.pem
|
|
49
51
|
`,
|
|
50
52
|
list: `run402 secrets list — List all secrets for a project
|
|
@@ -56,8 +58,7 @@ Arguments:
|
|
|
56
58
|
<id> Project ID (from 'run402 projects list')
|
|
57
59
|
|
|
58
60
|
Notes:
|
|
59
|
-
- Returns secret keys
|
|
60
|
-
for verifying the correct value was set; raw values are write-only
|
|
61
|
+
- Returns secret keys and timestamps only; raw values and value-derived hashes are never returned
|
|
61
62
|
|
|
62
63
|
Examples:
|
|
63
64
|
run402 secrets list prj_abc123
|
|
@@ -103,7 +104,14 @@ async function set(projectId, key, args = []) {
|
|
|
103
104
|
async function list(projectId) {
|
|
104
105
|
try {
|
|
105
106
|
const data = await getSdk().secrets.list(projectId);
|
|
106
|
-
|
|
107
|
+
const sanitized = {
|
|
108
|
+
secrets: (data.secrets || []).map((s) => ({
|
|
109
|
+
key: s.key,
|
|
110
|
+
...(s.created_at ? { created_at: s.created_at } : {}),
|
|
111
|
+
...(s.updated_at ? { updated_at: s.updated_at } : {}),
|
|
112
|
+
})),
|
|
113
|
+
};
|
|
114
|
+
console.log(JSON.stringify(sanitized, null, 2));
|
|
107
115
|
} catch (err) {
|
|
108
116
|
reportSdkError(err);
|
|
109
117
|
}
|
package/package.json
CHANGED
package/sdk/dist/index.d.ts
CHANGED
|
@@ -130,5 +130,5 @@ export { Deploy } from "./namespaces/deploy.js";
|
|
|
130
130
|
export { Ci, CI_AUDIENCE, CI_GITHUB_ACTIONS_ISSUER, CI_GITHUB_ACTIONS_PROVIDER, DEFAULT_CI_DELEGATION_CHAIN_ID, V1_CI_ALLOWED_ACTIONS, V1_CI_ALLOWED_EVENTS_DEFAULT, assertCiDeployableSpec, buildCiDelegationResourceUri, buildCiDelegationStatement, normalizeCiDelegationValues, validateCiNonce, validateCiSubjectMatch, } from "./namespaces/ci.js";
|
|
131
131
|
export { ScopedRun402 } from "./scoped.js";
|
|
132
132
|
export type { CiAllowedAction, CiAllowedEvent, CiBindingErrorCode, CiBindingRow, CiCreateBindingInput, CiDelegationValues, CiDeployErrorCode, CiErrorCode, CiListBindingsInput, CiListBindingsResult, CiProvider, CiTokenExchangeErrorCode, CiTokenExchangeInput, CiTokenExchangeRequestBody, CiTokenExchangeResponse, NormalizedCiDelegationValues, ParsedDelegation, } from "./namespaces/ci.types.js";
|
|
133
|
-
export type { ApplyOptions, CommitResponse, CommitStatus, ContentRef, ContentSource, DatabaseSpec, DeployDiff, DeployEvent, DeployOperation, DeployResult, ExposeManifest, FileSet, FsFileSource, FunctionSpec, FunctionsSpec, MigrationSpec, MissingContent, OperationSnapshot, OperationStatus, PaymentRequiredHint, PlanRequest, PlanResponse, ReleaseSpec, RouteSpec, SecretsSpec, SiteSpec, SmokeCheck, StartOptions, SubdomainsSpec, } from "./namespaces/deploy.types.js";
|
|
133
|
+
export type { ApplyOptions, ActiveReleaseInventory, CommitResponse, CommitStatus, ContentRef, ContentSource, DatabaseSpec, DeployObservabilityWarningEntry, DeployDiff, DeployEvent, DeployOperation, DeployResult, ExposeManifest, FileSet, FsFileSource, FunctionSpec, FunctionsDiff, FunctionsSpec, LegacyWarningEntry, MigrationAppliedEntry, MigrationSpec, MissingContent, OperationSnapshot, OperationStatus, PaymentRequiredHint, PlanDiffEnvelope, PlanMigrationDiff, PlanRequest, PlanResponse, ReleaseDiffOptions, ReleaseDiffTarget, ReleaseDiffToTarget, ReleaseFunctionEntry, ReleaseInventory, ReleaseInventoryBase, ReleaseInventoryByIdOptions, ReleaseInventoryOptions, ReleaseInventoryStateKind, ReleaseInventoryStatus, ReleaseSnapshotInventory, ReleaseSpec, ReleaseToReleaseDiff, RouteSpec, SecretsSpec, SecretsDiff, SiteDiff, SitePathEntry, SiteSpec, SmokeCheck, StartOptions, SubdomainsSpec, SubdomainsDiff, WarningEntry, } from "./namespaces/deploy.types.js";
|
|
134
134
|
//# sourceMappingURL=index.d.ts.map
|
package/sdk/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { Client } from "../kernel.js";
|
|
6
6
|
import type { ProjectTier, RlsTemplate, RlsTableSpec } from "./projects.types.js";
|
|
7
7
|
import type { SiteFile } from "./sites.js";
|
|
8
|
+
import type { WarningEntry } from "./deploy.types.js";
|
|
8
9
|
export interface BundleRlsOptions {
|
|
9
10
|
template: RlsTemplate;
|
|
10
11
|
tables: RlsTableSpec[];
|
|
@@ -47,6 +48,7 @@ export interface BundleDeployResult {
|
|
|
47
48
|
schedule?: string | null;
|
|
48
49
|
}>;
|
|
49
50
|
subdomain_url?: string;
|
|
51
|
+
warnings?: WarningEntry[];
|
|
50
52
|
}
|
|
51
53
|
export interface AppSummary {
|
|
52
54
|
id: string;
|
|
@@ -128,10 +130,10 @@ export declare class Apps {
|
|
|
128
130
|
private readonly client;
|
|
129
131
|
constructor(client: Client);
|
|
130
132
|
/**
|
|
131
|
-
* Deploy to an existing project: runs migrations, applies RLS,
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* renewal.
|
|
133
|
+
* Deploy to an existing project: runs migrations, applies RLS, writes
|
|
134
|
+
* legacy in-memory secret values through the secrets API, deploys
|
|
135
|
+
* functions, deploys a static site, and claims a subdomain. Payment flows
|
|
136
|
+
* through x402 when the project lease needs renewal.
|
|
135
137
|
*
|
|
136
138
|
* **As of v1.34, this method is a thin compatibility shim over
|
|
137
139
|
* {@link Deploy.apply}.** It translates the legacy bundle options into a
|
|
@@ -144,6 +146,11 @@ export declare class Apps {
|
|
|
144
146
|
* the only behavior change vs. v1's blind re-execution and is safe for
|
|
145
147
|
* idempotent migrations (the documented agent norm).
|
|
146
148
|
*
|
|
149
|
+
* Legacy `opts.secrets` are not embedded in the release spec. They are
|
|
150
|
+
* pre-validated, written before deploy, then represented as
|
|
151
|
+
* `secrets.require` keys. Those writes are intentionally not atomic with
|
|
152
|
+
* the later deploy commit.
|
|
153
|
+
*
|
|
147
154
|
* `inherit: true` is silently ignored;
|
|
148
155
|
* patch semantics on `r.deploy.apply` replace it.
|
|
149
156
|
*/
|