@rexezuge/tooling 0.0.0-stage → 1.0.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/LICENSE +21 -0
- package/README.md +297 -2
- package/dist/eslint.d.ts +120 -0
- package/dist/eslint.d.ts.map +1 -0
- package/dist/eslint.js +551 -0
- package/dist/eslint.js.map +1 -0
- package/dist/functions/pages-proxy.d.ts +113 -0
- package/dist/functions/pages-proxy.d.ts.map +1 -0
- package/dist/functions/pages-proxy.js +131 -0
- package/dist/functions/pages-proxy.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/scripts/backup/d1-target.d.ts +35 -0
- package/dist/scripts/backup/d1-target.d.ts.map +1 -0
- package/dist/scripts/backup/d1-target.js +31 -0
- package/dist/scripts/backup/d1-target.js.map +1 -0
- package/dist/scripts/backup/destination-config.d.ts +61 -0
- package/dist/scripts/backup/destination-config.d.ts.map +1 -0
- package/dist/scripts/backup/destination-config.js +57 -0
- package/dist/scripts/backup/destination-config.js.map +1 -0
- package/dist/scripts/backup/encrypt-backup.d.ts +35 -0
- package/dist/scripts/backup/encrypt-backup.d.ts.map +1 -0
- package/dist/scripts/backup/encrypt-backup.js +98 -0
- package/dist/scripts/backup/encrypt-backup.js.map +1 -0
- package/dist/scripts/backup/naming.d.ts +44 -0
- package/dist/scripts/backup/naming.d.ts.map +1 -0
- package/dist/scripts/backup/naming.js +58 -0
- package/dist/scripts/backup/naming.js.map +1 -0
- package/dist/scripts/check-god-files.d.ts +164 -0
- package/dist/scripts/check-god-files.d.ts.map +1 -0
- package/dist/scripts/check-god-files.js +271 -0
- package/dist/scripts/check-god-files.js.map +1 -0
- package/dist/scripts/ensure-spa-shell-stub.d.ts +3 -0
- package/dist/scripts/ensure-spa-shell-stub.d.ts.map +1 -0
- package/dist/scripts/ensure-spa-shell-stub.js +30 -0
- package/dist/scripts/ensure-spa-shell-stub.js.map +1 -0
- package/dist/scripts/init-secrets.d.ts +63 -0
- package/dist/scripts/init-secrets.d.ts.map +1 -0
- package/dist/scripts/init-secrets.js +240 -0
- package/dist/scripts/init-secrets.js.map +1 -0
- package/dist/scripts/lib/cli-args.d.ts +78 -0
- package/dist/scripts/lib/cli-args.d.ts.map +1 -0
- package/dist/scripts/lib/cli-args.js +116 -0
- package/dist/scripts/lib/cli-args.js.map +1 -0
- package/dist/scripts/lib/github-actions.d.ts +26 -0
- package/dist/scripts/lib/github-actions.d.ts.map +1 -0
- package/dist/scripts/lib/github-actions.js +38 -0
- package/dist/scripts/lib/github-actions.js.map +1 -0
- package/dist/scripts/lib/wrangler-table.d.ts +46 -0
- package/dist/scripts/lib/wrangler-table.d.ts.map +1 -0
- package/dist/scripts/lib/wrangler-table.js +99 -0
- package/dist/scripts/lib/wrangler-table.js.map +1 -0
- package/dist/scripts/migrations-lock.d.ts +3 -0
- package/dist/scripts/migrations-lock.d.ts.map +1 -0
- package/dist/scripts/migrations-lock.js +46 -0
- package/dist/scripts/migrations-lock.js.map +1 -0
- package/dist/scripts/prepare-wrangler-config.d.ts +3 -0
- package/dist/scripts/prepare-wrangler-config.d.ts.map +1 -0
- package/dist/scripts/prepare-wrangler-config.js +50 -0
- package/dist/scripts/prepare-wrangler-config.js.map +1 -0
- package/dist/scripts/spa-shell.d.ts +41 -0
- package/dist/scripts/spa-shell.d.ts.map +1 -0
- package/dist/scripts/spa-shell.js +155 -0
- package/dist/scripts/spa-shell.js.map +1 -0
- package/dist/scripts/validate-locales.d.ts +26 -0
- package/dist/scripts/validate-locales.d.ts.map +1 -0
- package/dist/scripts/validate-locales.js +350 -0
- package/dist/scripts/validate-locales.js.map +1 -0
- package/dist/scripts/verify-migrations.d.ts +62 -0
- package/dist/scripts/verify-migrations.d.ts.map +1 -0
- package/dist/scripts/verify-migrations.js +302 -0
- package/dist/scripts/verify-migrations.js.map +1 -0
- package/dist/scripts/verify-spa-shell.d.ts +3 -0
- package/dist/scripts/verify-spa-shell.d.ts.map +1 -0
- package/dist/scripts/verify-spa-shell.js +53 -0
- package/dist/scripts/verify-spa-shell.js.map +1 -0
- package/dist/scripts/wrangler-config/cli.d.ts +22 -0
- package/dist/scripts/wrangler-config/cli.d.ts.map +1 -0
- package/dist/scripts/wrangler-config/cli.js +51 -0
- package/dist/scripts/wrangler-config/cli.js.map +1 -0
- package/dist/scripts/wrangler-config/patches.d.ts +51 -0
- package/dist/scripts/wrangler-config/patches.d.ts.map +1 -0
- package/dist/scripts/wrangler-config/patches.js +140 -0
- package/dist/scripts/wrangler-config/patches.js.map +1 -0
- package/dist/scripts/wrangler-config/resources.d.ts +70 -0
- package/dist/scripts/wrangler-config/resources.d.ts.map +1 -0
- package/dist/scripts/wrangler-config/resources.js +290 -0
- package/dist/scripts/wrangler-config/resources.js.map +1 -0
- package/dist/scripts/wrangler-config/types.d.ts +103 -0
- package/dist/scripts/wrangler-config/types.d.ts.map +1 -0
- package/dist/scripts/wrangler-config/types.js +49 -0
- package/dist/scripts/wrangler-config/types.js.map +1 -0
- package/dist/test/integration-migrations.d.ts +167 -0
- package/dist/test/integration-migrations.d.ts.map +1 -0
- package/dist/test/integration-migrations.js +171 -0
- package/dist/test/integration-migrations.js.map +1 -0
- package/dist/test/mocks/cloudflare-workers.d.ts +106 -0
- package/dist/test/mocks/cloudflare-workers.d.ts.map +1 -0
- package/dist/test/mocks/cloudflare-workers.js +90 -0
- package/dist/test/mocks/cloudflare-workers.js.map +1 -0
- package/dist/vite.d.ts +117 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +125 -0
- package/dist/vite.js.map +1 -0
- package/dist/vitest-web.d.ts +73 -0
- package/dist/vitest-web.d.ts.map +1 -0
- package/dist/vitest-web.js +72 -0
- package/dist/vitest-web.js.map +1 -0
- package/dist/vitest.d.ts +92 -0
- package/dist/vitest.d.ts.map +1 -0
- package/dist/vitest.js +128 -0
- package/dist/vitest.js.map +1 -0
- package/package.json +58 -3
- package/src/eslint.test.ts +175 -0
- package/src/eslint.ts +640 -0
- package/src/functions/pages-proxy.test.ts +72 -0
- package/src/functions/pages-proxy.ts +187 -0
- package/src/github/actions/retry-step/action.yml +39 -0
- package/src/github/actions/setup-env/action.yml +20 -0
- package/src/github/dependabot.yml +30 -0
- package/src/github/workflows/backup-main.yml +46 -0
- package/src/github/workflows/continuous-deployment.yml +188 -0
- package/src/github/workflows/continuous-integration.yml +259 -0
- package/src/github/workflows/scheduled-version-update.yml +38 -0
- package/src/github/workflows/upstream-sync.yml +56 -0
- package/src/index.ts +42 -0
- package/src/scripts/backup/backup-rules.test.ts +105 -0
- package/src/scripts/backup/d1-target.ts +54 -0
- package/src/scripts/backup/destination-config.ts +92 -0
- package/src/scripts/backup/encrypt-backup.ts +107 -0
- package/src/scripts/backup/naming.ts +62 -0
- package/src/scripts/check-god-files.test.ts +131 -0
- package/src/scripts/check-god-files.ts +327 -0
- package/src/scripts/ensure-spa-shell-stub.ts +34 -0
- package/src/scripts/init-secrets.ts +265 -0
- package/src/scripts/lib/cli-args.ts +154 -0
- package/src/scripts/lib/github-actions.ts +41 -0
- package/src/scripts/lib/wrangler-table.ts +105 -0
- package/src/scripts/migrations-lock.ts +52 -0
- package/src/scripts/prepare-wrangler-config.ts +51 -0
- package/src/scripts/spa-shell.test.ts +91 -0
- package/src/scripts/spa-shell.ts +179 -0
- package/src/scripts/validate-locales.test.ts +89 -0
- package/src/scripts/validate-locales.ts +380 -0
- package/src/scripts/verify-migrations.test.ts +71 -0
- package/src/scripts/verify-migrations.ts +364 -0
- package/src/scripts/verify-spa-shell.ts +56 -0
- package/src/scripts/wrangler-config/cli.ts +51 -0
- package/src/scripts/wrangler-config/patches.ts +157 -0
- package/src/scripts/wrangler-config/resources.ts +330 -0
- package/src/scripts/wrangler-config/types.ts +113 -0
- package/src/test/integration-migrations.test.ts +169 -0
- package/src/test/integration-migrations.ts +267 -0
- package/src/test/mocks/cloudflare-workers.ts +115 -0
- package/src/vite.test.ts +83 -0
- package/src/vite.ts +202 -0
- package/src/vitest-web.ts +109 -0
- package/src/vitest.ts +185 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-god-files.js","sourceRoot":"","sources":["../../src/scripts/check-god-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-spa-shell-stub.d.ts","sourceRoot":"","sources":["../../src/scripts/ensure-spa-shell-stub.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Write a placeholder `apps/api/src/generated/spa-shell.ts` when it is absent.
|
|
4
|
+
*
|
|
5
|
+
* Provenance: Durable-DAV's `scripts/ensure-spa-shell-stub.mjs` and Edge-Sonic's
|
|
6
|
+
* `scripts/build/ensure-spa-shell-stub.ts`. The rule lives in `spa-shell.ts`; this
|
|
7
|
+
* is the entrypoint that runs it from `postinstall`.
|
|
8
|
+
*
|
|
9
|
+
* `pnpm install` runs this before `typegen` so the API worker typechecks in a
|
|
10
|
+
* fresh clone, where the real file has not been produced by the Vite build yet.
|
|
11
|
+
* It exits having done nothing when the file already exists, so a real build
|
|
12
|
+
* output is never overwritten — overwriting would erase the last build with a
|
|
13
|
+
* stub on the next install. The file is gitignored.
|
|
14
|
+
*
|
|
15
|
+
* Usage, from the repo root (typically wired as `postinstall`):
|
|
16
|
+
*
|
|
17
|
+
* ```bash
|
|
18
|
+
* pnpm exec tsx scripts/ensure-spa-shell-stub.ts [repo-root]
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import { fileURLToPath } from 'node:url';
|
|
23
|
+
import { ensureSpaShellStub } from './spa-shell';
|
|
24
|
+
const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
25
|
+
const root = process.argv[2] === undefined ? REPOSITORY_ROOT : path.resolve(process.argv[2]);
|
|
26
|
+
const result = ensureSpaShellStub({ root });
|
|
27
|
+
console.log(result.created
|
|
28
|
+
? `ensure-spa-shell-stub: created stub at ${result.path}`
|
|
29
|
+
: `ensure-spa-shell-stub: ${result.path} already present, left untouched`);
|
|
30
|
+
//# sourceMappingURL=ensure-spa-shell-stub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-spa-shell-stub.js","sourceRoot":"","sources":["../../src/scripts/ensure-spa-shell-stub.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACzF,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7F,MAAM,MAAM,GAAG,kBAAkB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AAE5C,OAAO,CAAC,GAAG,CACT,MAAM,CAAC,OAAO;IACZ,CAAC,CAAC,0CAA0C,MAAM,CAAC,IAAI,EAAE;IACzD,CAAC,CAAC,0BAA0B,MAAM,CAAC,IAAI,kCAAkC,CAC5E,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Create the Secrets Store entries declared in `wrangler.jsonc`, generating a fresh
|
|
4
|
+
* value for each one that does not exist yet.
|
|
5
|
+
*
|
|
6
|
+
* Provenance: Edge-Sonic's `scripts/deploy/init-secrets.ts` and Durable-DAV's
|
|
7
|
+
* `scripts/init-secrets.ts`, converged. Both record the same two defects that hid
|
|
8
|
+
* a broken deploy for a whole release, and both fixes are carried over.
|
|
9
|
+
*
|
|
10
|
+
* ### Why this script exists at all
|
|
11
|
+
*
|
|
12
|
+
* A `secrets_store_secrets` binding fails the deploy unless the named secret
|
|
13
|
+
* already exists inside the named store. Nothing creates it: Cloudflare will not
|
|
14
|
+
* generate a value, and the template cannot carry one. So this script is the only
|
|
15
|
+
* thing standing between a fresh account and a deploy that cannot succeed.
|
|
16
|
+
*
|
|
17
|
+
* ### The two defects that hid a broken deploy
|
|
18
|
+
*
|
|
19
|
+
* **The generator list was stale.** Durable-DAV's copy carried an allowlist of
|
|
20
|
+
* exact names from the repository it was inherited from, all deleted when the repo
|
|
21
|
+
* was renamed, so the very first iteration threw `Unknown secret` and never created
|
|
22
|
+
* anything. So the rule here is the secret's **name shape**, not a list of names:
|
|
23
|
+
* `*-encryption-key` gets a generated AES-GCM key and `*-signing-secret` gets 32
|
|
24
|
+
* random bytes. Adding a secret to the template is then a one-line change needing
|
|
25
|
+
* no matching edit here, which is the property the exact-name list did not have.
|
|
26
|
+
*
|
|
27
|
+
* **The throw was swallowed.** The original ended in `main().catch(console.error)`.
|
|
28
|
+
* `console.error` returns `undefined` and never sets an exit status, so the process
|
|
29
|
+
* exited **0** and CI marked the step green — the failure only surfaced one step
|
|
30
|
+
* later, as an unexplainable `wrangler deploy` failure. Hence: the whole plan is
|
|
31
|
+
* validated **before** any Cloudflare call, and a rejection reaches the runner as
|
|
32
|
+
* a non-zero exit with a workflow annotation.
|
|
33
|
+
*
|
|
34
|
+
* ### Create-if-absent is a correctness property, not laziness
|
|
35
|
+
*
|
|
36
|
+
* An existing secret is left untouched. A replication encryption key seals every
|
|
37
|
+
* remote target's credential; regenerating it on a redeploy would strand them all
|
|
38
|
+
* as undecryptable. Rotation has to be a deliberate act with a re-encrypt path,
|
|
39
|
+
* not a side effect of deploying.
|
|
40
|
+
*
|
|
41
|
+
* Requires a materialized `wrangler.jsonc` — run
|
|
42
|
+
* `scripts/prepare-wrangler-config.ts` first. Fails rather than skipping when the
|
|
43
|
+
* config is missing, because a step reporting "Secret initialization complete"
|
|
44
|
+
* having created nothing is worse than a named error.
|
|
45
|
+
*/
|
|
46
|
+
import { type WranglerConfig } from './wrangler-config/types';
|
|
47
|
+
/** Whether this script can produce a value for `secretName`. */
|
|
48
|
+
export declare function canProvisionSecret(secretName: string): boolean;
|
|
49
|
+
/** One secret to create, as the plan names it. */
|
|
50
|
+
interface PlannedSecret {
|
|
51
|
+
storeId: string;
|
|
52
|
+
secretName: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Turn the config's bindings into a validated work list.
|
|
56
|
+
*
|
|
57
|
+
* Every entry is checked *before* the first Cloudflare call, so an
|
|
58
|
+
* unprovisionable secret fails the step in milliseconds instead of after some other
|
|
59
|
+
* secret has already been created.
|
|
60
|
+
*/
|
|
61
|
+
export declare function planSecrets(config: WranglerConfig): PlannedSecret[];
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=init-secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-secrets.d.ts","sourceRoot":"","sources":["../../src/scripts/init-secrets.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAOH,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAqD3E,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAO9D;AAwCD,kDAAkD;AAClD,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa,EAAE,CAkBnE"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Create the Secrets Store entries declared in `wrangler.jsonc`, generating a fresh
|
|
4
|
+
* value for each one that does not exist yet.
|
|
5
|
+
*
|
|
6
|
+
* Provenance: Edge-Sonic's `scripts/deploy/init-secrets.ts` and Durable-DAV's
|
|
7
|
+
* `scripts/init-secrets.ts`, converged. Both record the same two defects that hid
|
|
8
|
+
* a broken deploy for a whole release, and both fixes are carried over.
|
|
9
|
+
*
|
|
10
|
+
* ### Why this script exists at all
|
|
11
|
+
*
|
|
12
|
+
* A `secrets_store_secrets` binding fails the deploy unless the named secret
|
|
13
|
+
* already exists inside the named store. Nothing creates it: Cloudflare will not
|
|
14
|
+
* generate a value, and the template cannot carry one. So this script is the only
|
|
15
|
+
* thing standing between a fresh account and a deploy that cannot succeed.
|
|
16
|
+
*
|
|
17
|
+
* ### The two defects that hid a broken deploy
|
|
18
|
+
*
|
|
19
|
+
* **The generator list was stale.** Durable-DAV's copy carried an allowlist of
|
|
20
|
+
* exact names from the repository it was inherited from, all deleted when the repo
|
|
21
|
+
* was renamed, so the very first iteration threw `Unknown secret` and never created
|
|
22
|
+
* anything. So the rule here is the secret's **name shape**, not a list of names:
|
|
23
|
+
* `*-encryption-key` gets a generated AES-GCM key and `*-signing-secret` gets 32
|
|
24
|
+
* random bytes. Adding a secret to the template is then a one-line change needing
|
|
25
|
+
* no matching edit here, which is the property the exact-name list did not have.
|
|
26
|
+
*
|
|
27
|
+
* **The throw was swallowed.** The original ended in `main().catch(console.error)`.
|
|
28
|
+
* `console.error` returns `undefined` and never sets an exit status, so the process
|
|
29
|
+
* exited **0** and CI marked the step green — the failure only surfaced one step
|
|
30
|
+
* later, as an unexplainable `wrangler deploy` failure. Hence: the whole plan is
|
|
31
|
+
* validated **before** any Cloudflare call, and a rejection reaches the runner as
|
|
32
|
+
* a non-zero exit with a workflow annotation.
|
|
33
|
+
*
|
|
34
|
+
* ### Create-if-absent is a correctness property, not laziness
|
|
35
|
+
*
|
|
36
|
+
* An existing secret is left untouched. A replication encryption key seals every
|
|
37
|
+
* remote target's credential; regenerating it on a redeploy would strand them all
|
|
38
|
+
* as undecryptable. Rotation has to be a deliberate act with a re-encrypt path,
|
|
39
|
+
* not a side effect of deploying.
|
|
40
|
+
*
|
|
41
|
+
* Requires a materialized `wrangler.jsonc` — run
|
|
42
|
+
* `scripts/prepare-wrangler-config.ts` first. Fails rather than skipping when the
|
|
43
|
+
* config is missing, because a step reporting "Secret initialization complete"
|
|
44
|
+
* having created nothing is worse than a named error.
|
|
45
|
+
*/
|
|
46
|
+
import { execFileSync } from 'node:child_process';
|
|
47
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
48
|
+
import { parse } from 'jsonc-parser';
|
|
49
|
+
import { fail } from './lib/github-actions';
|
|
50
|
+
import { isEmptySecretsStoreListing, parseWranglerNames } from './lib/wrangler-table';
|
|
51
|
+
import { CONFIG_PATH } from './wrangler-config/types';
|
|
52
|
+
/**
|
|
53
|
+
* The secret names the AES-GCM key generator produces, matched by **shape**.
|
|
54
|
+
*
|
|
55
|
+
* Keyed on the suffix because the alternative is the exact-name map that went
|
|
56
|
+
* stale. See the header: a template naming `*-encryption-key` is then a one-line
|
|
57
|
+
* change with no matching edit here, and a new secret breaks the deploy loudly
|
|
58
|
+
* instead of silently.
|
|
59
|
+
*/
|
|
60
|
+
const ENCRYPTION_KEY_SUFFIX = '-encryption-key';
|
|
61
|
+
/** The secret names the random signing secret generator produces. */
|
|
62
|
+
const SIGNING_SECRET_SUFFIX = '-signing-secret';
|
|
63
|
+
/** A 256-bit AES-GCM key, base64-encoded — the shape the worker's crypto layer accepts. */
|
|
64
|
+
async function generateAESGCMKey() {
|
|
65
|
+
const key = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
|
|
66
|
+
const exported = await crypto.subtle.exportKey('raw', key);
|
|
67
|
+
// Chunked rather than spread: `String.fromCharCode(...bytes)` passes 32 arguments,
|
|
68
|
+
// which is fine today and is a stack overflow the day the key is longer.
|
|
69
|
+
let binary = '';
|
|
70
|
+
for (const byte of new Uint8Array(exported)) {
|
|
71
|
+
binary += String.fromCodePoint(byte);
|
|
72
|
+
}
|
|
73
|
+
return btoa(binary);
|
|
74
|
+
}
|
|
75
|
+
/** A 256-bit random signing secret for internal self-calls, hex-encoded. */
|
|
76
|
+
function generateSigningSecret() {
|
|
77
|
+
let hex = '';
|
|
78
|
+
for (const byte of crypto.getRandomValues(new Uint8Array(32))) {
|
|
79
|
+
hex += byte.toString(16).padStart(2, '0');
|
|
80
|
+
}
|
|
81
|
+
return Promise.resolve(hex);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The generator for a secret name, chosen by the name's shape.
|
|
85
|
+
*
|
|
86
|
+
* A name matching neither is still refused rather than given a guess: the generator
|
|
87
|
+
* is not the only thing that has to be right, and an unusable value that looks
|
|
88
|
+
* provisioned is worse than a failure.
|
|
89
|
+
*/
|
|
90
|
+
function generatorFor(secretName) {
|
|
91
|
+
if (secretName.endsWith(ENCRYPTION_KEY_SUFFIX))
|
|
92
|
+
return generateAESGCMKey;
|
|
93
|
+
if (secretName.endsWith(SIGNING_SECRET_SUFFIX))
|
|
94
|
+
return generateSigningSecret;
|
|
95
|
+
throw new Error(`Unknown secret: ${secretName}. Name it '*-encryption-key' for a generated 32-byte AES-GCM key, ` +
|
|
96
|
+
`or '*-signing-secret' for 32 random bytes, and teach this script the shape if neither fits.`);
|
|
97
|
+
}
|
|
98
|
+
/** Whether this script can produce a value for `secretName`. */
|
|
99
|
+
export function canProvisionSecret(secretName) {
|
|
100
|
+
try {
|
|
101
|
+
generatorFor(secretName);
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Runs a wrangler subcommand, optionally feeding `input` on stdin.
|
|
110
|
+
*
|
|
111
|
+
* Arguments are passed as an argv array rather than interpolated into a shell
|
|
112
|
+
* string, so a value containing shell metacharacters cannot alter the command.
|
|
113
|
+
*/
|
|
114
|
+
function wrangler(args, input) {
|
|
115
|
+
try {
|
|
116
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path
|
|
117
|
+
return execFileSync('pnpm', ['exec', 'wrangler', ...args], {
|
|
118
|
+
encoding: 'utf8',
|
|
119
|
+
stdio: [input === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe'],
|
|
120
|
+
...(input !== undefined && { input }),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
const maybeProcessError = error;
|
|
125
|
+
const stdout = maybeProcessError.stdout ? maybeProcessError.stdout.toString() : '';
|
|
126
|
+
const stderr = maybeProcessError.stderr ? maybeProcessError.stderr.toString() : '';
|
|
127
|
+
throw new Error(`Command failed: pnpm exec wrangler ${args.join(' ')}\n${stdout}${stderr || maybeProcessError.message || ''}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function parseWranglerConfig() {
|
|
131
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
132
|
+
throw new Error(`${CONFIG_PATH} not found. Run scripts/prepare-wrangler-config.ts first — it is what creates the file this script reads.`);
|
|
133
|
+
}
|
|
134
|
+
// `parse` is error-tolerant and returns a partial object, so an empty result means
|
|
135
|
+
// malformed JSON rather than "no secrets declared". Treating that as an empty list
|
|
136
|
+
// would report success having created nothing.
|
|
137
|
+
const config = parse(readFileSync(CONFIG_PATH, 'utf8'));
|
|
138
|
+
if (config.secrets_store_secrets === undefined && Object.keys(config).length === 0) {
|
|
139
|
+
throw new Error(`${CONFIG_PATH} is empty or not valid JSONC. Run scripts/prepare-wrangler-config.ts to regenerate it.`);
|
|
140
|
+
}
|
|
141
|
+
return config;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Turn the config's bindings into a validated work list.
|
|
145
|
+
*
|
|
146
|
+
* Every entry is checked *before* the first Cloudflare call, so an
|
|
147
|
+
* unprovisionable secret fails the step in milliseconds instead of after some other
|
|
148
|
+
* secret has already been created.
|
|
149
|
+
*/
|
|
150
|
+
export function planSecrets(config) {
|
|
151
|
+
const plan = [];
|
|
152
|
+
for (const [index, secret] of (config.secrets_store_secrets ?? []).entries()) {
|
|
153
|
+
const label = secret.binding ?? `index ${index}`;
|
|
154
|
+
const storeId = secret.store_id;
|
|
155
|
+
const secretName = secret.secret_name;
|
|
156
|
+
if (storeId === undefined || storeId === '' || secretName === undefined || secretName === '') {
|
|
157
|
+
throw new Error(`secrets_store_secrets[${index}] ("${label}") needs both store_id and secret_name; ` +
|
|
158
|
+
'store_id is normally filled in by scripts/prepare-wrangler-config.ts.');
|
|
159
|
+
}
|
|
160
|
+
if (!canProvisionSecret(secretName)) {
|
|
161
|
+
throw new Error(`No generator for secret "${secretName}" (binding "${label}").`);
|
|
162
|
+
}
|
|
163
|
+
plan.push({ storeId, secretName });
|
|
164
|
+
}
|
|
165
|
+
return plan;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* List the secret names present in a store.
|
|
169
|
+
*
|
|
170
|
+
* Returns `undefined` when the listing itself failed, which is deliberately
|
|
171
|
+
* distinct from an empty set: a transient CLI failure must not be read as "the
|
|
172
|
+
* secret is missing" and cause a duplicate insert over a live value. An empty store
|
|
173
|
+
* *is* a confirmed absence, so it maps to an empty set rather than `undefined`.
|
|
174
|
+
*
|
|
175
|
+
* The name is taken exactly. `output.includes(secretName)` is not a membership test:
|
|
176
|
+
* `my-replication-encryption-key-2` satisfies a search for
|
|
177
|
+
* `my-replication-encryption-key`, so a store holding only the suffixed entry would
|
|
178
|
+
* report the unsuffixed one as already present and it would never be created.
|
|
179
|
+
*/
|
|
180
|
+
function listSecretNames(storeId) {
|
|
181
|
+
let output;
|
|
182
|
+
try {
|
|
183
|
+
output = wrangler(['secrets-store', 'secret', 'list', storeId, '--remote']);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
if (isEmptySecretsStoreListing(error)) {
|
|
187
|
+
console.log(`Secrets Store ${storeId} is empty`);
|
|
188
|
+
return new Set();
|
|
189
|
+
}
|
|
190
|
+
console.warn(`Unable to list secrets in store ${storeId}:`, error instanceof Error ? error.message : 'unknown error');
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
return parseWranglerNames(output);
|
|
194
|
+
}
|
|
195
|
+
function createSecret(storeId, secretName, secretValue) {
|
|
196
|
+
console.log(`Creating secret: ${secretName}`);
|
|
197
|
+
// The value goes in on stdin, never as an argv entry: an argv is visible to every
|
|
198
|
+
// process on the runner through `ps`, and the previous
|
|
199
|
+
// `echo "${value}" | wrangler … ${name}` also broke on `"`, `$`, backticks and
|
|
200
|
+
// newlines.
|
|
201
|
+
wrangler(['secrets-store', 'secret', 'create', storeId, '--name', secretName, '--scopes', 'workers', '--remote'], secretValue);
|
|
202
|
+
}
|
|
203
|
+
async function main() {
|
|
204
|
+
console.log('Initializing Cloudflare secrets...');
|
|
205
|
+
const config = parseWranglerConfig();
|
|
206
|
+
const plan = planSecrets(config);
|
|
207
|
+
if (plan.length === 0) {
|
|
208
|
+
throw new Error('wrangler.jsonc declares no secrets_store_secrets entries, so there is nothing to initialize.');
|
|
209
|
+
}
|
|
210
|
+
const listedByStore = new Map();
|
|
211
|
+
for (const { storeId, secretName } of plan) {
|
|
212
|
+
if (!listedByStore.has(storeId)) {
|
|
213
|
+
listedByStore.set(storeId, listSecretNames(storeId));
|
|
214
|
+
}
|
|
215
|
+
const existing = listedByStore.get(storeId);
|
|
216
|
+
if (existing === undefined) {
|
|
217
|
+
// Refuse to guess: creating a secret we could not read back risks overwriting
|
|
218
|
+
// a live value with a freshly generated one.
|
|
219
|
+
throw new Error(`Could not list secrets in store ${storeId}; refusing to create ${secretName} without confirming it is absent.`);
|
|
220
|
+
}
|
|
221
|
+
if (existing.has(secretName)) {
|
|
222
|
+
console.log(`Secret ${secretName} already exists; leaving it untouched.`);
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
createSecret(storeId, secretName, await generatorFor(secretName)());
|
|
226
|
+
existing.add(secretName);
|
|
227
|
+
}
|
|
228
|
+
console.log('Secret initialization complete');
|
|
229
|
+
}
|
|
230
|
+
// Top-level await rather than `.catch(console.error)`, so a rejected `main` surfaces
|
|
231
|
+
// as a stack trace with its cause intact and the process exits non-zero. Either way
|
|
232
|
+
// the exit status has to be right: this runs in the deploy pipeline, and swallowing
|
|
233
|
+
// the rejection reported a failed key bootstrap as a green step.
|
|
234
|
+
try {
|
|
235
|
+
await main();
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
fail(error instanceof Error ? `Secret initialization failed: ${error.message}` : String(error));
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=init-secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-secrets.js","sourceRoot":"","sources":["../../src/scripts/init-secrets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal flag parsing for the operator scripts.
|
|
3
|
+
*
|
|
4
|
+
* Provenance: ported from Edge-Sonic's `scripts/lib/cli-args.ts`, which is the
|
|
5
|
+
* only typed arg parser in the family — every other repo reads `process.argv`
|
|
6
|
+
* with `includes('--flag')` inline.
|
|
7
|
+
*
|
|
8
|
+
* The shape is generic: a declared set of value flags and boolean flags, so an
|
|
9
|
+
* unknown or valueless flag is rejected **by name** rather than silently ignored.
|
|
10
|
+
* A mistyped `--write` must not degrade into "ran with no flags" — which is what
|
|
11
|
+
* an inline `argv.includes()` does, and what turns a migration-lock invocation
|
|
12
|
+
* that misspelled the flag into a read-only run that reports success.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* const flags = parseFlags(process.argv.slice(2), {
|
|
18
|
+
* boolean: ['write', 'dry-run'],
|
|
19
|
+
* value: ['locales-dir', 'root'],
|
|
20
|
+
* });
|
|
21
|
+
* if (isSet(flags, 'write')) { ... }
|
|
22
|
+
* const dir = valueOf(flags, 'locales-dir');
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Parsed flags: value flags map to their string, boolean flags to `true`.
|
|
27
|
+
*/
|
|
28
|
+
export type ParsedFlags = Map<string, string | true>;
|
|
29
|
+
/**
|
|
30
|
+
* Declares which flags take a value and which are bare switches.
|
|
31
|
+
*/
|
|
32
|
+
export interface FlagSpec {
|
|
33
|
+
/**
|
|
34
|
+
* `--name` takes a value, e.g. `--to new@example.com`.
|
|
35
|
+
*/
|
|
36
|
+
value?: readonly string[];
|
|
37
|
+
/**
|
|
38
|
+
* `--dry-run` takes no value.
|
|
39
|
+
*/
|
|
40
|
+
boolean?: readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* Short form → long form, e.g. `{ h: 'help' }`.
|
|
43
|
+
*/
|
|
44
|
+
alias?: Readonly<Record<string, string>>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Parses `--flag value` and `--boolean` pairs out of `argv`.
|
|
48
|
+
*
|
|
49
|
+
* @throws when a value flag is missing its value, when a flag is repeated, or
|
|
50
|
+
* when an undeclared flag is seen. Each case names the offending flag.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseFlags(argv: readonly string[], spec: FlagSpec): ParsedFlags;
|
|
53
|
+
/**
|
|
54
|
+
* Reads a value flag, or `undefined` when it was not supplied.
|
|
55
|
+
*/
|
|
56
|
+
export declare function valueOf(flags: ParsedFlags, name: string): string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Reads a boolean flag, defaulting to `false`.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isSet(flags: ParsedFlags, name: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Split `argv` into its positional arguments and the rest, so a caller can accept
|
|
63
|
+
* `tsx script.ts <dir>` alongside `--root <dir>`.
|
|
64
|
+
*
|
|
65
|
+
* A token that follows a value flag *is* that flag's value, not a positional: the
|
|
66
|
+
* naive `argv.filter((arg) => !arg.startsWith('-'))` takes `.` out of
|
|
67
|
+
* `--root . --fail-on-hard` and then `parseFlags` reports `--root requires a value`.
|
|
68
|
+
* The value flags are passed in rather than inferred, because only the caller knows
|
|
69
|
+
* which of its declared flags take one.
|
|
70
|
+
*
|
|
71
|
+
* @throws when more than `expected` positionals are given, naming them: a second
|
|
72
|
+
* directory is far more likely to be a mistyped flag than an intended argument.
|
|
73
|
+
*/
|
|
74
|
+
export declare function splitPositional(argv: readonly string[], valueFlags: readonly string[], expected?: number): {
|
|
75
|
+
positional: string[];
|
|
76
|
+
rest: string[];
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=cli-args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-args.d.ts","sourceRoot":"","sources":["../../../src/scripts/lib/cli-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B;;OAEG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,GAAG,WAAW,CAwC/E;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,QAAQ,SAAI,GACX;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAwB1C"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal flag parsing for the operator scripts.
|
|
3
|
+
*
|
|
4
|
+
* Provenance: ported from Edge-Sonic's `scripts/lib/cli-args.ts`, which is the
|
|
5
|
+
* only typed arg parser in the family — every other repo reads `process.argv`
|
|
6
|
+
* with `includes('--flag')` inline.
|
|
7
|
+
*
|
|
8
|
+
* The shape is generic: a declared set of value flags and boolean flags, so an
|
|
9
|
+
* unknown or valueless flag is rejected **by name** rather than silently ignored.
|
|
10
|
+
* A mistyped `--write` must not degrade into "ran with no flags" — which is what
|
|
11
|
+
* an inline `argv.includes()` does, and what turns a migration-lock invocation
|
|
12
|
+
* that misspelled the flag into a read-only run that reports success.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* const flags = parseFlags(process.argv.slice(2), {
|
|
18
|
+
* boolean: ['write', 'dry-run'],
|
|
19
|
+
* value: ['locales-dir', 'root'],
|
|
20
|
+
* });
|
|
21
|
+
* if (isSet(flags, 'write')) { ... }
|
|
22
|
+
* const dir = valueOf(flags, 'locales-dir');
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Parses `--flag value` and `--boolean` pairs out of `argv`.
|
|
27
|
+
*
|
|
28
|
+
* @throws when a value flag is missing its value, when a flag is repeated, or
|
|
29
|
+
* when an undeclared flag is seen. Each case names the offending flag.
|
|
30
|
+
*/
|
|
31
|
+
export function parseFlags(argv, spec) {
|
|
32
|
+
const valueFlags = new Set(spec.value);
|
|
33
|
+
const booleanFlags = new Set(spec.boolean);
|
|
34
|
+
const aliases = spec.alias ?? {};
|
|
35
|
+
const flags = new Map();
|
|
36
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
37
|
+
const arg = argv[index];
|
|
38
|
+
if (!arg.startsWith('-')) {
|
|
39
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
40
|
+
}
|
|
41
|
+
const raw = arg.replace(/^--?/, '');
|
|
42
|
+
const name = aliases[raw] ?? raw;
|
|
43
|
+
if (booleanFlags.has(name)) {
|
|
44
|
+
if (flags.has(name)) {
|
|
45
|
+
throw new Error(`--${name} was given more than once`);
|
|
46
|
+
}
|
|
47
|
+
flags.set(name, true);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (!valueFlags.has(name)) {
|
|
51
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
52
|
+
}
|
|
53
|
+
if (flags.has(name)) {
|
|
54
|
+
throw new Error(`--${name} was given more than once`);
|
|
55
|
+
}
|
|
56
|
+
const value = argv[index + 1];
|
|
57
|
+
// A value that starts with `-` is treated as a missing value so that
|
|
58
|
+
// `--to --dry-run` reports the real problem instead of capturing the flag.
|
|
59
|
+
if (value === undefined || value.startsWith('-')) {
|
|
60
|
+
throw new Error(`--${name} requires a value`);
|
|
61
|
+
}
|
|
62
|
+
flags.set(name, value);
|
|
63
|
+
index += 1;
|
|
64
|
+
}
|
|
65
|
+
return flags;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Reads a value flag, or `undefined` when it was not supplied.
|
|
69
|
+
*/
|
|
70
|
+
export function valueOf(flags, name) {
|
|
71
|
+
const value = flags.get(name);
|
|
72
|
+
return typeof value === 'string' ? value : undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reads a boolean flag, defaulting to `false`.
|
|
76
|
+
*/
|
|
77
|
+
export function isSet(flags, name) {
|
|
78
|
+
return flags.get(name) === true;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Split `argv` into its positional arguments and the rest, so a caller can accept
|
|
82
|
+
* `tsx script.ts <dir>` alongside `--root <dir>`.
|
|
83
|
+
*
|
|
84
|
+
* A token that follows a value flag *is* that flag's value, not a positional: the
|
|
85
|
+
* naive `argv.filter((arg) => !arg.startsWith('-'))` takes `.` out of
|
|
86
|
+
* `--root . --fail-on-hard` and then `parseFlags` reports `--root requires a value`.
|
|
87
|
+
* The value flags are passed in rather than inferred, because only the caller knows
|
|
88
|
+
* which of its declared flags take one.
|
|
89
|
+
*
|
|
90
|
+
* @throws when more than `expected` positionals are given, naming them: a second
|
|
91
|
+
* directory is far more likely to be a mistyped flag than an intended argument.
|
|
92
|
+
*/
|
|
93
|
+
export function splitPositional(argv, valueFlags, expected = 1) {
|
|
94
|
+
const takes = new Set(valueFlags);
|
|
95
|
+
const positional = [];
|
|
96
|
+
const rest = [];
|
|
97
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
98
|
+
const arg = argv[index];
|
|
99
|
+
if (arg.startsWith('-')) {
|
|
100
|
+
rest.push(arg);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const previous = argv[index - 1];
|
|
104
|
+
const isFlagValue = previous !== undefined && previous.startsWith('-') && takes.has(previous.replace(/^--?/, ''));
|
|
105
|
+
if (isFlagValue) {
|
|
106
|
+
rest.push(arg);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
positional.push(arg);
|
|
110
|
+
}
|
|
111
|
+
if (positional.length > expected) {
|
|
112
|
+
throw new Error(`Expected at most ${expected} positional argument(s), got: ${positional.join(', ')}`);
|
|
113
|
+
}
|
|
114
|
+
return { positional, rest };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=cli-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-args.js","sourceRoot":"","sources":["../../../src/scripts/lib/cli-args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal GitHub Actions step helpers shared by the CI scripts.
|
|
3
|
+
*
|
|
4
|
+
* Provenance: ported from Edge-Sonic's `scripts/lib/github-actions.ts`, the only
|
|
5
|
+
* repo that factored these out. The scripts deliberately avoid `@actions/*`
|
|
6
|
+
* dependencies so they stay runnable with plain `tsx` from a local shell, which
|
|
7
|
+
* is how they are tested.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Append `name=value` to the step's output file. No-op outside Actions.
|
|
11
|
+
*/
|
|
12
|
+
export declare function setOutput(name: string, value: string): void;
|
|
13
|
+
/**
|
|
14
|
+
* Emit a workflow-command annotation so the failure is visible in the run log.
|
|
15
|
+
*/
|
|
16
|
+
export declare function logError(message: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Report a fatal error and exit non-zero.
|
|
19
|
+
*
|
|
20
|
+
* The annotation is written *before* exiting so the reason survives in the run
|
|
21
|
+
* log. This is the whole point of the helper: the failure mode it exists to
|
|
22
|
+
* prevent is a script that ends in `.catch(console.error)`, which reports success
|
|
23
|
+
* while every side effect it was supposed to perform did not happen.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fail(message: string): never;
|
|
26
|
+
//# sourceMappingURL=github-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-actions.d.ts","sourceRoot":"","sources":["../../../src/scripts/lib/github-actions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAM3D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAG3C"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal GitHub Actions step helpers shared by the CI scripts.
|
|
3
|
+
*
|
|
4
|
+
* Provenance: ported from Edge-Sonic's `scripts/lib/github-actions.ts`, the only
|
|
5
|
+
* repo that factored these out. The scripts deliberately avoid `@actions/*`
|
|
6
|
+
* dependencies so they stay runnable with plain `tsx` from a local shell, which
|
|
7
|
+
* is how they are tested.
|
|
8
|
+
*/
|
|
9
|
+
import { appendFileSync } from 'node:fs';
|
|
10
|
+
/**
|
|
11
|
+
* Append `name=value` to the step's output file. No-op outside Actions.
|
|
12
|
+
*/
|
|
13
|
+
export function setOutput(name, value) {
|
|
14
|
+
const outputFile = process.env.GITHUB_OUTPUT;
|
|
15
|
+
if (!outputFile) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
appendFileSync(outputFile, `${name}=${value}\n`);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Emit a workflow-command annotation so the failure is visible in the run log.
|
|
22
|
+
*/
|
|
23
|
+
export function logError(message) {
|
|
24
|
+
process.stderr.write(`::error::${message}\n`);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Report a fatal error and exit non-zero.
|
|
28
|
+
*
|
|
29
|
+
* The annotation is written *before* exiting so the reason survives in the run
|
|
30
|
+
* log. This is the whole point of the helper: the failure mode it exists to
|
|
31
|
+
* prevent is a script that ends in `.catch(console.error)`, which reports success
|
|
32
|
+
* while every side effect it was supposed to perform did not happen.
|
|
33
|
+
*/
|
|
34
|
+
export function fail(message) {
|
|
35
|
+
logError(message);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=github-actions.js.map
|