@smoothbricks/cli 0.11.19 → 0.11.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +68 -5
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +28 -4
  4. package/dist/lib/json.d.ts +22 -1
  5. package/dist/lib/json.d.ts.map +1 -1
  6. package/dist/lib/json.js +15 -3
  7. package/dist/monorepo/cargo-policy.d.ts +17 -0
  8. package/dist/monorepo/cargo-policy.d.ts.map +1 -1
  9. package/dist/monorepo/cargo-policy.js +73 -1
  10. package/dist/monorepo/index.d.ts.map +1 -1
  11. package/dist/monorepo/index.js +4 -2
  12. package/dist/monorepo/packs/index.d.ts.map +1 -1
  13. package/dist/monorepo/packs/index.js +6 -1
  14. package/dist/nx/index.d.ts +6 -0
  15. package/dist/nx/index.d.ts.map +1 -1
  16. package/dist/nx/index.js +14 -0
  17. package/dist/secrets/commands.d.ts +9 -5
  18. package/dist/secrets/commands.d.ts.map +1 -1
  19. package/dist/secrets/commands.js +122 -49
  20. package/dist/secrets/index.d.ts +42 -56
  21. package/dist/secrets/index.d.ts.map +1 -1
  22. package/dist/secrets/index.js +52 -79
  23. package/dist/secrets/resolver.d.ts +59 -0
  24. package/dist/secrets/resolver.d.ts.map +1 -0
  25. package/dist/secrets/resolver.js +100 -0
  26. package/dist/secrets/run.d.ts +23 -0
  27. package/dist/secrets/run.d.ts.map +1 -0
  28. package/dist/secrets/run.js +130 -0
  29. package/dist/secrets/status.d.ts +177 -0
  30. package/dist/secrets/status.d.ts.map +1 -0
  31. package/dist/secrets/status.js +724 -0
  32. package/dist/wrangler/deploy-stage.d.ts +1 -1
  33. package/dist/wrangler/deploy-stage.d.ts.map +1 -1
  34. package/dist/wrangler/deploy-stage.js +22 -20
  35. package/dist/wrangler/deployed-version.d.ts.map +1 -1
  36. package/dist/wrangler/deployed-version.js +7 -12
  37. package/dist/wrangler/flat-config.d.ts +1 -4
  38. package/dist/wrangler/flat-config.d.ts.map +1 -1
  39. package/dist/wrangler/flat-config.js +98 -44
  40. package/dist/wrangler/prepare-env.d.ts +4 -3
  41. package/dist/wrangler/prepare-env.d.ts.map +1 -1
  42. package/dist/wrangler/prepare-env.js +7 -5
  43. package/dist/wrangler/source-config.d.ts +24 -0
  44. package/dist/wrangler/source-config.d.ts.map +1 -0
  45. package/dist/wrangler/source-config.js +110 -0
  46. package/dist/wrangler/stage.d.ts +55 -23
  47. package/dist/wrangler/stage.d.ts.map +1 -1
  48. package/dist/wrangler/stage.js +81 -162
  49. package/managed/raw/tooling/direnv/devenv.smoo.nix +19 -3
  50. package/managed/raw/tooling/direnv/secret-references.ts +280 -76
  51. package/managed/raw/tooling/direnv/setup-environment.ts +58 -2
  52. package/managed/raw/tsconfig.lib.json +28 -0
  53. package/package.json +7 -2
  54. package/src/cli.ts +34 -5
  55. package/src/lib/json.ts +23 -1
  56. package/src/monorepo/cargo-policy.test.ts +91 -1
  57. package/src/monorepo/cargo-policy.ts +87 -1
  58. package/src/monorepo/index.ts +8 -2
  59. package/src/monorepo/packs/index.ts +10 -1
  60. package/src/monorepo/secret-references.test.ts +412 -6
  61. package/src/monorepo/setup-environment.test.ts +181 -0
  62. package/src/nx/index.test.ts +8 -0
  63. package/src/nx/index.ts +20 -0
  64. package/src/secrets/commands.test.ts +186 -4
  65. package/src/secrets/commands.ts +142 -51
  66. package/src/secrets/index.test.ts +4 -10
  67. package/src/secrets/index.ts +54 -115
  68. package/src/secrets/resolver.ts +130 -0
  69. package/src/secrets/run.test.ts +359 -0
  70. package/src/secrets/run.ts +148 -0
  71. package/src/secrets/status.test.ts +164 -0
  72. package/src/secrets/status.ts +297 -0
  73. package/src/wrangler/deploy-stage.test.ts +95 -2
  74. package/src/wrangler/deploy-stage.ts +26 -23
  75. package/src/wrangler/deployed-version.ts +7 -11
  76. package/src/wrangler/flat-config.test.ts +9 -4
  77. package/src/wrangler/flat-config.ts +1 -20
  78. package/src/wrangler/format-parity.test.ts +433 -0
  79. package/src/wrangler/prepare-env.ts +7 -5
  80. package/src/wrangler/source-config.test.ts +102 -0
  81. package/src/wrangler/source-config.ts +110 -0
  82. package/src/wrangler/stage.test.ts +61 -32
  83. package/src/wrangler/stage.ts +124 -173
@@ -0,0 +1,100 @@
1
+ /**
2
+ * The bootstrap secret resolver, as the CLI sees it.
3
+ *
4
+ * `managed/raw/tooling/direnv/secret-references.ts` holds the one
5
+ * implementation of THE RULE — which group resolves where, and what CI and a
6
+ * cowshed workspace refuse instead. A managed repository runs the copy smoo
7
+ * writes into its own `tooling/direnv/secret-references.ts` at shell entry;
8
+ * `smoo secrets run` runs THIS package's copy of the same file. One
9
+ * implementation, so the command and the shell cannot disagree about a group.
10
+ *
11
+ * It is loaded, not statically imported, and that is forced rather than
12
+ * chosen: the file is a raw bootstrap script that must load before any
13
+ * workspace package and before the Typia transform exists, so it lives
14
+ * outside `src` — outside this package's compiled `rootDir`, which a static
15
+ * import may not cross. A dynamic `import()` reaches it in both layouts
16
+ * (`src/secrets/` and `dist/secrets/` are each two directories below the
17
+ * package root), and typia validates what comes back: the same boundary
18
+ * ../monorepo/packed-package.ts puts around a foreign module. `require` is
19
+ * not the alternative — under a Bun loader plugin, which this package's own
20
+ * tests preload, every module is async and `require` of one throws.
21
+ */
22
+ import { fileURLToPath, pathToFileURL } from 'node:url';
23
+ import typia from 'typia';
24
+ const isSecretReferencesModule = (() => {
25
+ const _io0 = input => true && true;
26
+ return input => "object" === typeof input && null !== input && false === Array.isArray(input) && _io0(input);
27
+ })();
28
+ const isGroupedSecrets = (() => {
29
+ const _io0 = input => "string" === typeof input.name && "string" === typeof input.group && "string" === typeof input.derivedGroup;
30
+ return input => Array.isArray(input) && input.every(elem => "object" === typeof elem && null !== elem && _io0(elem));
31
+ })();
32
+ const isSecretResolution = (() => {
33
+ const _io0 = input => "object" === typeof input.values && null !== input.values && false === Array.isArray(input.values) && _io1(input.values) && (Array.isArray(input.deferred) && input.deferred.every(elem => "object" === typeof elem && null !== elem && _io2(elem)));
34
+ const _io1 = input => Object.keys(input).every(key => {
35
+ const value = input[key];
36
+ if (undefined === value)
37
+ return true;
38
+ return "string" === typeof value;
39
+ });
40
+ const _io2 = input => "string" === typeof input.name && "string" === typeof input.group && "string" === typeof input.guidance;
41
+ return input => "object" === typeof input && null !== input && _io0(input);
42
+ })();
43
+ const RESOLVER_PATH = fileURLToPath(new URL('../../managed/raw/tooling/direnv/secret-references.ts', import.meta.url));
44
+ /**
45
+ * A loaded export, narrowed to the signature this file calls it with. typia
46
+ * validates data, not functions — it reports a module missing both of these
47
+ * as valid — so presence is checked here, and what each one RETURNS is
48
+ * validated below, where it is data again.
49
+ */
50
+ function isSecretGroupsReader(value) {
51
+ return typeof value === 'function';
52
+ }
53
+ function isSecretGroupResolver(value) {
54
+ return typeof value === 'function';
55
+ }
56
+ let loaded;
57
+ async function secretReferences() {
58
+ if (loaded !== undefined) {
59
+ return loaded;
60
+ }
61
+ // Dynamic by necessity: the target is a managed raw script outside this
62
+ // package's compiled rootDir, so no static import can name it.
63
+ const imported = await import(pathToFileURL(RESOLVER_PATH).href);
64
+ if (!isSecretReferencesModule(imported)) {
65
+ throw new Error(`${RESOLVER_PATH} did not load as a module`);
66
+ }
67
+ const { readSecretGroups: read, resolveSecretEnvironment: resolve } = imported;
68
+ if (!isSecretGroupsReader(read) || !isSecretGroupResolver(resolve)) {
69
+ throw new Error(`${RESOLVER_PATH} does not expose the expected secret resolver API`);
70
+ }
71
+ loaded = { readSecretGroups: read, resolveSecretEnvironment: resolve };
72
+ return loaded;
73
+ }
74
+ /**
75
+ * Every `smoo.secrets` entry of the repository at `root`, each with the group
76
+ * that resolves it. Rejects with the offending declaration named — never a
77
+ * value — when the manifest or `.npmrc` cannot be read.
78
+ */
79
+ export async function readSecretGroups(root) {
80
+ const references = await secretReferences();
81
+ const groups = references.readSecretGroups(root);
82
+ if (!isGroupedSecrets(groups)) {
83
+ throw new Error(`${RESOLVER_PATH} returned an unexpected group listing`);
84
+ }
85
+ return groups;
86
+ }
87
+ /**
88
+ * Resolve exactly one group's secrets for one child process. Everything
89
+ * outside the group comes back deferred rather than resolved, so a run for
90
+ * one group never triggers another group's provider command. Rejects with the
91
+ * resolver's aggregated refusal, which names variables and groups only.
92
+ */
93
+ export async function resolveSecretGroup(root, group) {
94
+ const references = await secretReferences();
95
+ const resolution = await references.resolveSecretEnvironment({ root, group });
96
+ if (!isSecretResolution(resolution)) {
97
+ throw new Error(`${RESOLVER_PATH} returned an unexpected resolution`);
98
+ }
99
+ return resolution;
100
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `smoo secrets run <group> <command...>` — the half of THE RULE that shell
3
+ * entry is not.
4
+ *
5
+ * The rule lives in tooling/direnv/secret-references.ts: shell entry resolves
6
+ * the `shell` group and nothing else, because a provider authorises per
7
+ * requesting process lineage and every direnv reload is a new one. Every
8
+ * other group belongs to the command that needs it, and this is that command.
9
+ * One deliberate `smoo secrets run registry bun install` instead of a
10
+ * credential prompt on every shell.
11
+ *
12
+ * Exactly one group is resolved. A repository that declares a registry
13
+ * credential and a cache token runs one provider command here, not two: a
14
+ * wrapper that resolved everything declared would fire provider commands for
15
+ * credentials the command never touches, which is the prompt this exists to
16
+ * remove.
17
+ *
18
+ * The value reaches the child the only way that leaves no trace: its
19
+ * environment. Never a file, never argv — argv is world-readable through
20
+ * `ps` — and never this process's stdout.
21
+ */
22
+ export declare function secretsRun(root: string, group: string | undefined, command: readonly string[]): Promise<number>;
23
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/secrets/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAiBH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0CrH"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * `smoo secrets run <group> <command...>` — the half of THE RULE that shell
3
+ * entry is not.
4
+ *
5
+ * The rule lives in tooling/direnv/secret-references.ts: shell entry resolves
6
+ * the `shell` group and nothing else, because a provider authorises per
7
+ * requesting process lineage and every direnv reload is a new one. Every
8
+ * other group belongs to the command that needs it, and this is that command.
9
+ * One deliberate `smoo secrets run registry bun install` instead of a
10
+ * credential prompt on every shell.
11
+ *
12
+ * Exactly one group is resolved. A repository that declares a registry
13
+ * credential and a cache token runs one provider command here, not two: a
14
+ * wrapper that resolved everything declared would fire provider commands for
15
+ * credentials the command never touches, which is the prompt this exists to
16
+ * remove.
17
+ *
18
+ * The value reaches the child the only way that leaves no trace: its
19
+ * environment. Never a file, never argv — argv is world-readable through
20
+ * `ps` — and never this process's stdout.
21
+ */
22
+ import { spawn } from 'node:child_process';
23
+ import { constants } from 'node:os';
24
+ import { readSecretGroups, resolveSecretGroup } from './resolver.js';
25
+ /**
26
+ * Nothing ran, and the listing is the answer: no group named, a group this
27
+ * repository does not declare, or a group with no command to run. Distinct
28
+ * from 1, which is a resolution that refused, and from any other code, which
29
+ * is the child's own.
30
+ */
31
+ const REFUSED = 2;
32
+ /** A command that could not be started at all, as a shell reports it. */
33
+ const NOT_EXECUTABLE = 127;
34
+ export async function secretsRun(root, group, command) {
35
+ let declared;
36
+ try {
37
+ declared = await readSecretGroups(root);
38
+ }
39
+ catch (error) {
40
+ console.error(error instanceof Error ? error.message : String(error));
41
+ return 1;
42
+ }
43
+ if (group === undefined) {
44
+ console.error('smoo secrets run <group> <command...> runs one command with one group of secrets in its environment.');
45
+ printGroups(declared);
46
+ return REFUSED;
47
+ }
48
+ const members = declared.filter((secret) => secret.group === group);
49
+ if (members.length === 0) {
50
+ console.error(`smoo secrets run: no declared secret is in group \`${group}\`.`);
51
+ printGroups(declared);
52
+ return REFUSED;
53
+ }
54
+ const [program, ...args] = command;
55
+ if (program === undefined) {
56
+ console.error(`smoo secrets run ${group} <command...>: name the command to run with ` +
57
+ `${members.map((secret) => secret.name).join(', ')} in its environment.`);
58
+ return REFUSED;
59
+ }
60
+ let values;
61
+ try {
62
+ ({ values } = await resolveSecretGroup(root, group));
63
+ }
64
+ catch (error) {
65
+ console.error(error instanceof Error ? error.message : String(error));
66
+ return 1;
67
+ }
68
+ return await runWithSecrets(program, args, values);
69
+ }
70
+ /**
71
+ * The child's exit status, reproduced: a code as itself, death by signal as
72
+ * 128+signum, and a program that could not be started as 127. It shares this
73
+ * process group, so terminal signals reach it directly; it is spawned rather
74
+ * than exec'd only because neither Bun nor Node exposes `execve`.
75
+ */
76
+ async function runWithSecrets(program, args, values) {
77
+ return await new Promise((resolve) => {
78
+ const child = spawn(program, [...args], { stdio: 'inherit', env: { ...process.env, ...values } });
79
+ child.on('error', (error) => {
80
+ console.error(`smoo secrets run: cannot run \`${program}\`: ${error.message}`);
81
+ resolve(NOT_EXECUTABLE);
82
+ });
83
+ child.on('close', (code, signal) => {
84
+ if (signal !== null) {
85
+ resolve(128 + constants.signals[signal]);
86
+ return;
87
+ }
88
+ resolve(code ?? 1);
89
+ });
90
+ });
91
+ }
92
+ /**
93
+ * The groups this repository declares and the secrets in each. Most people
94
+ * meet this command exactly once, at a 401, after reading a message that
95
+ * named it — so the refusal answers "which group?" from this checkout's own
96
+ * declarations rather than printing a usage line that sends them to the
97
+ * manifest to work it out.
98
+ */
99
+ function printGroups(declared) {
100
+ if (declared.length === 0) {
101
+ console.error('This repository declares no smoo.secrets, so there is no group to run.');
102
+ return;
103
+ }
104
+ const members = new Map();
105
+ for (const secret of declared) {
106
+ const named = members.get(secret.group);
107
+ if (named === undefined) {
108
+ members.set(secret.group, [secret.name]);
109
+ continue;
110
+ }
111
+ named.push(secret.name);
112
+ }
113
+ const groups = [...members.keys()].sort((left, right) => left.localeCompare(right));
114
+ const width = Math.max(...groups.map((group) => group.length));
115
+ console.error('');
116
+ console.error('Groups this repository declares:');
117
+ for (const group of groups) {
118
+ console.error(` ${group.padEnd(width)} ${(members.get(group) ?? []).join(', ')}`);
119
+ }
120
+ // An override is stated, never left for the next reader to discover by
121
+ // wondering why a `.npmrc` credential resolves at shell entry.
122
+ for (const secret of declared) {
123
+ if (secret.group === secret.derivedGroup)
124
+ continue;
125
+ console.error(` note: ${secret.name} declares group \`${secret.group}\`, overriding the \`${secret.derivedGroup}\` ` +
126
+ "this repository's declarations derive.");
127
+ }
128
+ console.error('');
129
+ console.error(` smoo secrets run ${groups[0] ?? '<group>'} <command...>`);
130
+ }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * The value model behind `smoo secrets`: one row per secret name, reconciled
3
+ * from every source that has an opinion about it, plus the machine-readable
4
+ * document `smoo secrets status --json` emits.
5
+ *
6
+ * Everything here is pure and depends on nothing but typia, which is what lets
7
+ * `@smoothbricks/cli/secrets` be imported for the types alone — a consumer
8
+ * driving a UI or a repository's own operations CLI gets the document type and
9
+ * a validator without pulling in `gh`, the filesystem readers, or commander.
10
+ * The readers that produce these facts live in ./index.ts; the operator
11
+ * commands that print them live in ./commands.ts.
12
+ */
13
+ import typia from 'typia';
14
+ import type { SecretStageMap, SecretStageScope } from '../wrangler/stage-secrets.js';
15
+ export type { SecretStageScope };
16
+ /** Where an env name is described, which repository secret carries it, and whether that exists. */
17
+ export interface SecretRow {
18
+ name: string;
19
+ /** The repository secret this env name reads from, by convention or declaration. */
20
+ repositorySecret: string;
21
+ /** Wrangler projects whose `.dev.vars.example` declares it. */
22
+ declaredByWorkers: string[];
23
+ /** True when a managed workflow renders `secrets.<name>` into a job. */
24
+ suppliedByWorkflow: boolean;
25
+ /** True when `smoo.secrets` can fetch it for a developer shell; equivalently, `localGroup` is set. */
26
+ fetchableLocally: boolean;
27
+ /**
28
+ * How `smoo.secrets` resolves it locally: the group that resolves it, and
29
+ * the group this repository's own declarations derive. They differ exactly
30
+ * when the entry overrides the derivation, which is the one thing a reader
31
+ * must never have to infer. Absent when nothing fetches the name locally.
32
+ */
33
+ localGroup?: {
34
+ resolves: string;
35
+ derived: string;
36
+ };
37
+ /** True when the repository holds a secret of this name. */
38
+ onRepository: boolean;
39
+ /**
40
+ * GitHub Environments holding their own value for this name. A job bound to
41
+ * an environment reads that value in preference to the repository's, which
42
+ * is how one name carries test credentials on a preview stage and live ones
43
+ * in production.
44
+ */
45
+ heldByEnvironment: string[];
46
+ }
47
+ /**
48
+ * One `smoo.secrets` entry as the reconciliation needs it: the name, the
49
+ * group that resolves it, and the group this repository's declarations
50
+ * derive. ../secrets/resolver.ts produces these from the same file shell
51
+ * entry routes with.
52
+ */
53
+ export interface LocalSecret {
54
+ name: string;
55
+ group: string;
56
+ derivedGroup: string;
57
+ }
58
+ export interface SecretSources {
59
+ /** Worker label -> env names it declares. */
60
+ workerSecrets: Record<string, readonly string[]>;
61
+ /** Env names a managed workflow passes into a job. */
62
+ workflowSecrets: readonly string[];
63
+ /** Env name -> repository secret, by convention with declared exceptions. */
64
+ secretNames: Readonly<Record<string, string>>;
65
+ /** Every `smoo.secrets` entry with the group that resolves it. */
66
+ localSecrets: readonly LocalSecret[];
67
+ /** Repository secret names GitHub currently holds. */
68
+ repositorySecrets: readonly string[];
69
+ /** Environment name -> secret names that environment holds. */
70
+ environmentSecrets?: Readonly<Record<string, readonly string[]>>;
71
+ }
72
+ /**
73
+ * One row per name known to any source, sorted, so a reader sees the whole
74
+ * picture rather than one source's view of it.
75
+ */
76
+ export declare function reconcileSecrets(sources: SecretSources): SecretRow[];
77
+ /**
78
+ * The rows a CI deploy cannot satisfy: a Worker declares the name, a workflow
79
+ * promises to pass it, and the repository has no value to pass. Reported
80
+ * separately from "declared but not wired into any workflow", because the
81
+ * remedies differ — set a secret, versus declare it in `smoo.github`.
82
+ */
83
+ export declare function unsatisfiedSecrets(rows: readonly SecretRow[], boundEnvironments?: readonly string[]): SecretRow[];
84
+ /** Bound environments that lack their own value and cannot fall back to the repository. */
85
+ export declare function environmentsMissing(row: SecretRow, boundEnvironments: readonly string[]): string[];
86
+ /** Worker-declared names no managed workflow passes: a CI deploy will run without them. */
87
+ export declare function unwiredSecrets(rows: readonly SecretRow[]): SecretRow[];
88
+ /** The repository the status was read from, and how that repository was chosen. */
89
+ export interface SecretsStatusRepository {
90
+ /** `owner/name`, the form `gh --repo` takes. */
91
+ repo: string;
92
+ /** Why this repository — the checkout fact that decided it, verbatim from the resolver. */
93
+ source: string;
94
+ /** How many secrets it holds at repository scope. */
95
+ secretCount: number;
96
+ }
97
+ /**
98
+ * One GitHub Environment the status looked at. Discriminated on `readable`
99
+ * because an environment `gh` refused to list is not an empty one: reporting
100
+ * it as empty would call values missing that may well be set, and the reason
101
+ * is the only thing that lets an operator tell the two apart.
102
+ */
103
+ export type SecretsStatusEnvironment = {
104
+ name: string;
105
+ /** True when a managed workflow binds a job to it, so a job reads it before the repository. */
106
+ bound: boolean;
107
+ readable: true;
108
+ secretCount: number;
109
+ } | {
110
+ name: string;
111
+ bound: boolean;
112
+ readable: false;
113
+ /** What `gh` said, so nothing below claims what this environment holds. */
114
+ reason: string;
115
+ };
116
+ /** A reconciled row, plus which deployment stages require the name to have a value. */
117
+ export interface SecretsStatusRow extends SecretRow {
118
+ /**
119
+ * Stages that refuse to deploy without a value, from `smoo.wrangler.secretStages`
120
+ * unioned over every wrangler project declaring the name: absent from the map
121
+ * means every stage, mapped to `[]` means none. A name no wrangler project
122
+ * declares is `[]` too — `declaredByWorkers` tells those two apart.
123
+ */
124
+ requiredByStages: SecretStageScope[];
125
+ }
126
+ /** A name a workflow passes that no scope the job reads can supply: this is what fails a deploy. */
127
+ export interface UnsatisfiedSecret {
128
+ name: string;
129
+ repositorySecret: string;
130
+ /**
131
+ * Bound environments holding no value for it. Empty means no environment is
132
+ * bound and the repository itself is the scope to set it in.
133
+ */
134
+ missingIn: string[];
135
+ }
136
+ /**
137
+ * Everything `smoo secrets status` learned, in one document.
138
+ *
139
+ * `unsatisfied` is the exit code's reason and not a convenience: the rule that
140
+ * decides whether a value exists in a scope a bound job reads is smoo's, and a
141
+ * consumer re-deriving it from `secrets` would be maintaining a second copy of
142
+ * it.
143
+ */
144
+ export interface SecretsStatusDocument {
145
+ /** Document shape, so a consumer refuses a document it does not understand instead of misreading it. */
146
+ version: 1;
147
+ repository: SecretsStatusRepository;
148
+ /** Every environment looked at: those the workflows bind, then any asked for with `--env`. */
149
+ environments: SecretsStatusEnvironment[];
150
+ /** One row per name any source knows, sorted by name. */
151
+ secrets: SecretsStatusRow[];
152
+ /** Empty exactly when the command exits 0. */
153
+ unsatisfied: UnsatisfiedSecret[];
154
+ }
155
+ /** The facts a document is projected from, all gathered before anything is printed. */
156
+ export interface SecretsStatusFacts {
157
+ repository: SecretsStatusRepository;
158
+ environments: readonly SecretsStatusEnvironment[];
159
+ rows: readonly SecretRow[];
160
+ /** Worker label -> its `smoo.wrangler.secretStages` declaration; a worker with no block is absent. */
161
+ stageScopes: Readonly<Record<string, SecretStageMap>>;
162
+ }
163
+ /** The document, from facts. Pure: every read happened before this was called. */
164
+ export declare function projectSecretsStatus(facts: SecretsStatusFacts): SecretsStatusDocument;
165
+ /**
166
+ * The consumer's boundary: text off a `smoo secrets status --json` run into a
167
+ * validated document, or typia's own account of every field that disagreed.
168
+ */
169
+ export declare const parseSecretsStatusDocument: (input: string) => typia.IValidation<SecretsStatusDocument>;
170
+ /**
171
+ * The emitter's boundary: the projection is checked against its declared type
172
+ * before it becomes text. A shape bug then fails here, naming the field, rather
173
+ * than reaching a consumer as a document its validator rejects with no idea who
174
+ * produced it.
175
+ */
176
+ export declare const stringifySecretsStatusDocument: (input: unknown, errorFactory?: undefined | ((props: typia.TypeGuardError.IProps) => Error)) => string;
177
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/secrets/status.ts"],"names":[],"mappings":"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"}