@smoothbricks/cli 0.11.18 → 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.
- package/README.md +91 -11
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +28 -4
- package/dist/github-ci/index.d.ts.map +1 -1
- package/dist/github-ci/index.js +6 -20
- package/dist/lib/deploy-tags.d.ts +17 -3
- package/dist/lib/deploy-tags.d.ts.map +1 -1
- package/dist/lib/deploy-tags.js +23 -4
- package/dist/lib/json.d.ts +22 -1
- package/dist/lib/json.d.ts.map +1 -1
- package/dist/lib/json.js +15 -3
- package/dist/monorepo/cargo-policy.d.ts +17 -0
- package/dist/monorepo/cargo-policy.d.ts.map +1 -1
- package/dist/monorepo/cargo-policy.js +73 -1
- package/dist/monorepo/index.d.ts.map +1 -1
- package/dist/monorepo/index.js +4 -2
- package/dist/monorepo/managed-files.d.ts +5 -2
- package/dist/monorepo/managed-files.d.ts.map +1 -1
- package/dist/monorepo/managed-files.js +35 -21
- package/dist/monorepo/packs/index.d.ts.map +1 -1
- package/dist/monorepo/packs/index.js +6 -1
- package/dist/nx/index.d.ts +6 -0
- package/dist/nx/index.d.ts.map +1 -1
- package/dist/nx/index.js +14 -0
- package/dist/secrets/commands.d.ts +9 -5
- package/dist/secrets/commands.d.ts.map +1 -1
- package/dist/secrets/commands.js +122 -49
- package/dist/secrets/index.d.ts +42 -56
- package/dist/secrets/index.d.ts.map +1 -1
- package/dist/secrets/index.js +52 -79
- package/dist/secrets/resolver.d.ts +59 -0
- package/dist/secrets/resolver.d.ts.map +1 -0
- package/dist/secrets/resolver.js +100 -0
- package/dist/secrets/run.d.ts +23 -0
- package/dist/secrets/run.d.ts.map +1 -0
- package/dist/secrets/run.js +130 -0
- package/dist/secrets/status.d.ts +177 -0
- package/dist/secrets/status.d.ts.map +1 -0
- package/dist/secrets/status.js +724 -0
- package/dist/wrangler/deploy-stage.d.ts +1 -1
- package/dist/wrangler/deploy-stage.d.ts.map +1 -1
- package/dist/wrangler/deploy-stage.js +22 -20
- package/dist/wrangler/deployed-version.d.ts.map +1 -1
- package/dist/wrangler/deployed-version.js +7 -12
- package/dist/wrangler/flat-config.d.ts +1 -4
- package/dist/wrangler/flat-config.d.ts.map +1 -1
- package/dist/wrangler/flat-config.js +98 -44
- package/dist/wrangler/prepare-env.d.ts +4 -3
- package/dist/wrangler/prepare-env.d.ts.map +1 -1
- package/dist/wrangler/prepare-env.js +7 -5
- package/dist/wrangler/source-config.d.ts +24 -0
- package/dist/wrangler/source-config.d.ts.map +1 -0
- package/dist/wrangler/source-config.js +110 -0
- package/dist/wrangler/stage.d.ts +55 -23
- package/dist/wrangler/stage.d.ts.map +1 -1
- package/dist/wrangler/stage.js +81 -162
- package/managed/raw/tooling/direnv/devenv.smoo.nix +19 -3
- package/managed/raw/tooling/direnv/secret-references.ts +280 -76
- package/managed/raw/tooling/direnv/setup-environment.ts +58 -2
- package/managed/raw/tsconfig.lib.json +28 -0
- package/package.json +7 -2
- package/src/cli.ts +34 -5
- package/src/github-ci/index.test.ts +6 -7
- package/src/github-ci/index.ts +11 -19
- package/src/lib/deploy-tags.ts +22 -4
- package/src/lib/json.ts +23 -1
- package/src/monorepo/cargo-policy.test.ts +91 -1
- package/src/monorepo/cargo-policy.ts +87 -1
- package/src/monorepo/index.ts +8 -2
- package/src/monorepo/managed-files.test.ts +69 -37
- package/src/monorepo/managed-files.ts +38 -21
- package/src/monorepo/packs/index.ts +10 -1
- package/src/monorepo/secret-references.test.ts +412 -6
- package/src/monorepo/setup-environment.test.ts +181 -0
- package/src/nx/index.test.ts +8 -0
- package/src/nx/index.ts +20 -0
- package/src/secrets/commands.test.ts +186 -4
- package/src/secrets/commands.ts +142 -51
- package/src/secrets/index.test.ts +4 -10
- package/src/secrets/index.ts +54 -115
- package/src/secrets/resolver.ts +130 -0
- package/src/secrets/run.test.ts +359 -0
- package/src/secrets/run.ts +148 -0
- package/src/secrets/status.test.ts +164 -0
- package/src/secrets/status.ts +297 -0
- package/src/wrangler/deploy-stage.test.ts +95 -2
- package/src/wrangler/deploy-stage.ts +26 -23
- package/src/wrangler/deployed-version.ts +7 -11
- package/src/wrangler/flat-config.test.ts +9 -4
- package/src/wrangler/flat-config.ts +1 -20
- package/src/wrangler/format-parity.test.ts +433 -0
- package/src/wrangler/prepare-env.ts +7 -5
- package/src/wrangler/source-config.test.ts +102 -0
- package/src/wrangler/source-config.ts +110 -0
- package/src/wrangler/stage.test.ts +61 -32
- package/src/wrangler/stage.ts +124 -173
|
@@ -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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"}
|