@heyditto/cli 2.5.1 → 2.6.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 +52 -20
- package/dist/commands.d.ts +34 -3
- package/dist/commands.js +130 -59
- package/dist/commands.js.map +1 -1
- package/dist/secret-stores/aws.d.ts +8 -0
- package/dist/secret-stores/aws.js +59 -0
- package/dist/secret-stores/aws.js.map +1 -0
- package/dist/secret-stores/azure.d.ts +7 -0
- package/dist/secret-stores/azure.js +63 -0
- package/dist/secret-stores/azure.js.map +1 -0
- package/dist/secret-stores/cloudflare.d.ts +7 -0
- package/dist/secret-stores/cloudflare.js +46 -0
- package/dist/secret-stores/cloudflare.js.map +1 -0
- package/dist/secret-stores/doppler.d.ts +7 -0
- package/dist/secret-stores/doppler.js +52 -0
- package/dist/secret-stores/doppler.js.map +1 -0
- package/dist/secret-stores/exec.d.ts +55 -0
- package/dist/secret-stores/exec.js +132 -0
- package/dist/secret-stores/exec.js.map +1 -0
- package/dist/secret-stores/fly.d.ts +7 -0
- package/dist/secret-stores/fly.js +54 -0
- package/dist/secret-stores/fly.js.map +1 -0
- package/dist/secret-stores/gcloud.d.ts +7 -0
- package/dist/secret-stores/gcloud.js +62 -0
- package/dist/secret-stores/gcloud.js.map +1 -0
- package/dist/secret-stores/github.d.ts +9 -0
- package/dist/secret-stores/github.js +74 -0
- package/dist/secret-stores/github.js.map +1 -0
- package/dist/secret-stores/gitlab.d.ts +7 -0
- package/dist/secret-stores/gitlab.js +82 -0
- package/dist/secret-stores/gitlab.js.map +1 -0
- package/dist/secret-stores/index.d.ts +42 -0
- package/dist/secret-stores/index.js +106 -0
- package/dist/secret-stores/index.js.map +1 -0
- package/dist/secret-stores/kubernetes.d.ts +8 -0
- package/dist/secret-stores/kubernetes.js +76 -0
- package/dist/secret-stores/kubernetes.js.map +1 -0
- package/dist/secret-stores/naming.d.ts +20 -0
- package/dist/secret-stores/naming.js +62 -0
- package/dist/secret-stores/naming.js.map +1 -0
- package/dist/secret-stores/onepassword.d.ts +7 -0
- package/dist/secret-stores/onepassword.js +50 -0
- package/dist/secret-stores/onepassword.js.map +1 -0
- package/dist/secret-stores/types.d.ts +108 -0
- package/dist/secret-stores/types.js +25 -0
- package/dist/secret-stores/types.js.map +1 -0
- package/dist/secret-stores/vault.d.ts +7 -0
- package/dist/secret-stores/vault.js +47 -0
- package/dist/secret-stores/vault.js.map +1 -0
- package/dist/secret-stores/vercel.d.ts +9 -0
- package/dist/secret-stores/vercel.js +49 -0
- package/dist/secret-stores/vercel.js.map +1 -0
- package/dist/teleport/harness.d.ts +5 -0
- package/dist/teleport/harness.js +21 -5
- package/dist/teleport/harness.js.map +1 -1
- package/dist/teleport/types.d.ts +7 -0
- package/dist/teleport/types.js +12 -1
- package/dist/teleport/types.js.map +1 -1
- package/dist/teleport/worktree.js +2 -0
- package/dist/teleport/worktree.js.map +1 -1
- package/package.json +1 -1
- package/dist/gh-secret.d.ts +0 -31
- package/dist/gh-secret.js +0 -94
- package/dist/gh-secret.js.map +0 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
/** Keeps platform CLIs quiet and non-interactive; they must never prompt. */
|
|
6
|
+
const QUIET_ENV = {
|
|
7
|
+
GH_NO_UPDATE_NOTIFIER: "1",
|
|
8
|
+
GH_PROMPT_DISABLED: "1",
|
|
9
|
+
GLAB_CHECK_UPDATE: "0",
|
|
10
|
+
NO_COLOR: "1",
|
|
11
|
+
AWS_PAGER: "",
|
|
12
|
+
CLOUDSDK_CORE_DISABLE_PROMPTS: "1",
|
|
13
|
+
AZURE_CORE_ONLY_SHOW_ERRORS: "true",
|
|
14
|
+
DO_NOT_TRACK: "1",
|
|
15
|
+
};
|
|
16
|
+
export function run(bin, args, input) {
|
|
17
|
+
const res = spawnSync(bin, args, {
|
|
18
|
+
encoding: "utf8",
|
|
19
|
+
// Always an explicit (possibly empty) stdin: a CLI that reads stdin on a
|
|
20
|
+
// probe like `gh auth status` must see EOF rather than wait for us.
|
|
21
|
+
input: input ?? "",
|
|
22
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
23
|
+
env: { ...process.env, ...QUIET_ENV },
|
|
24
|
+
});
|
|
25
|
+
const missing = res.error !== undefined && res.error.code === "ENOENT";
|
|
26
|
+
return { status: res.status, stdout: res.stdout ?? "", stderr: res.stderr ?? "", missing };
|
|
27
|
+
}
|
|
28
|
+
/** Last few stderr lines, clamped — platform CLIs can be very chatty on failure. */
|
|
29
|
+
export function trimmedStderr(res) {
|
|
30
|
+
return (res.stderr || res.stdout).trim().split("\n").slice(-3).join(" ").slice(0, 300);
|
|
31
|
+
}
|
|
32
|
+
const presence = new Map();
|
|
33
|
+
/**
|
|
34
|
+
* True when `bin` is on PATH. Memoized: `endpoints keys stores` asks about a
|
|
35
|
+
* dozen CLIs, and resolving alternate names asks again.
|
|
36
|
+
*/
|
|
37
|
+
export function installed(bin, versionArgs = ["--version"]) {
|
|
38
|
+
const cached = presence.get(bin);
|
|
39
|
+
if (cached !== undefined)
|
|
40
|
+
return cached;
|
|
41
|
+
const found = !run(bin, [...versionArgs]).missing;
|
|
42
|
+
presence.set(bin, found);
|
|
43
|
+
return found;
|
|
44
|
+
}
|
|
45
|
+
const resolvedBins = new Map();
|
|
46
|
+
/**
|
|
47
|
+
* Some CLIs ship under more than one name (`fly` and `flyctl`). Picks the
|
|
48
|
+
* first that answers, remembering it so one command spawns the probe once.
|
|
49
|
+
*/
|
|
50
|
+
export function resolveBin(store) {
|
|
51
|
+
const cached = resolvedBins.get(store.bin);
|
|
52
|
+
if (cached)
|
|
53
|
+
return cached;
|
|
54
|
+
const candidates = [store.bin, ...(store.altBins ?? [])];
|
|
55
|
+
const found = candidates.find((bin) => installed(bin, store.versionArgs)) ?? store.bin;
|
|
56
|
+
resolvedBins.set(store.bin, found);
|
|
57
|
+
return found;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Standard preflight: the binary answers, and the account check exits 0.
|
|
61
|
+
* Runs before anything is minted so a missing CLI costs nothing.
|
|
62
|
+
*/
|
|
63
|
+
export function preflight(input) {
|
|
64
|
+
const bin = resolveBin(input);
|
|
65
|
+
const version = run(bin, [...(input.versionArgs ?? ["--version"])]);
|
|
66
|
+
if (version.missing) {
|
|
67
|
+
throw new Error(`storing a key in ${input.label} needs ${input.bin} on PATH; ${input.installHint}`);
|
|
68
|
+
}
|
|
69
|
+
const auth = run(bin, input.authArgs);
|
|
70
|
+
if (auth.missing) {
|
|
71
|
+
throw new Error(`storing a key in ${input.label} needs ${input.bin} on PATH; ${input.installHint}`);
|
|
72
|
+
}
|
|
73
|
+
if (auth.status !== 0) {
|
|
74
|
+
const detail = trimmedStderr(auth);
|
|
75
|
+
throw new Error(`${bin} is not signed in (\`${bin} ${input.authArgs.join(" ")}\` failed${detail ? `: ${detail}` : ""}). ${input.authHint}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Placeholder in `path` delivery argv, replaced with the file the CLI should read. */
|
|
79
|
+
export const PATH_PLACEHOLDER = "{}";
|
|
80
|
+
/** POSIX CLIs can read the piped stdin through this path; Windows cannot. */
|
|
81
|
+
const STDIN_PATH = "/dev/stdin";
|
|
82
|
+
function substitute(args, path) {
|
|
83
|
+
return args.map((arg) => arg.split(PATH_PLACEHOLDER).join(path));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Hands `value` to the store's CLI, trying each attempt in order. Throws with
|
|
87
|
+
* every attempt's own last stderr lines when all of them fail, so the caller
|
|
88
|
+
* can revoke the key it just minted and the operator can see why.
|
|
89
|
+
*
|
|
90
|
+
* `path` delivery uses `/dev/stdin` wherever it exists, keeping the plaintext
|
|
91
|
+
* off disk. Only on Windows does it fall back to a 0600 file in a private
|
|
92
|
+
* temp directory, which is overwritten and removed before returning.
|
|
93
|
+
*/
|
|
94
|
+
export function deliver(store, name, attempts, value) {
|
|
95
|
+
const failures = [];
|
|
96
|
+
for (const attempt of attempts) {
|
|
97
|
+
const payload = attempt.payload ? attempt.payload(value) : value;
|
|
98
|
+
const res = attempt.kind === "stdin" ? runStdin(store, attempt, payload) : runPath(store, attempt, payload);
|
|
99
|
+
if (res.missing) {
|
|
100
|
+
throw new Error(`${store.bin} disappeared from PATH while storing the secret; ${store.installHint}`);
|
|
101
|
+
}
|
|
102
|
+
if (res.status === 0)
|
|
103
|
+
return;
|
|
104
|
+
const detail = trimmedStderr(res);
|
|
105
|
+
failures.push(`${attempt.note}: ${detail || `exit ${res.status}`}`);
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`${store.bin} could not store ${name} — ${failures.join("; ")}`);
|
|
108
|
+
}
|
|
109
|
+
function runStdin(store, attempt, payload) {
|
|
110
|
+
return run(resolveBin(store), attempt.args, payload);
|
|
111
|
+
}
|
|
112
|
+
function runPath(store, attempt, payload) {
|
|
113
|
+
if (process.platform !== "win32") {
|
|
114
|
+
return run(resolveBin(store), substitute(attempt.args, STDIN_PATH), payload);
|
|
115
|
+
}
|
|
116
|
+
const dir = mkdtempSync(join(tmpdir(), "heyditto-secret-"));
|
|
117
|
+
const file = join(dir, "value");
|
|
118
|
+
try {
|
|
119
|
+
writeFileSync(file, payload, { mode: 0o600 });
|
|
120
|
+
return run(resolveBin(store), substitute(attempt.args, file));
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
try {
|
|
124
|
+
writeFileSync(file, "0".repeat(payload.length), { mode: 0o600 });
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Best effort; the directory removal below is what matters.
|
|
128
|
+
}
|
|
129
|
+
rmSync(dir, { recursive: true, force: true });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/secret-stores/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAiBjC,6EAA6E;AAC7E,MAAM,SAAS,GAA2B;IACxC,qBAAqB,EAAE,GAAG;IAC1B,kBAAkB,EAAE,GAAG;IACvB,iBAAiB,EAAE,GAAG;IACtB,QAAQ,EAAE,GAAG;IACb,SAAS,EAAE,EAAE;IACb,6BAA6B,EAAE,GAAG;IAClC,2BAA2B,EAAE,MAAM;IACnC,YAAY,EAAE,GAAG;CAClB,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,IAAc,EAAE,KAAc;IAC7D,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE;QAC/B,QAAQ,EAAE,MAAM;QAChB,yEAAyE;QACzE,oEAAoE;QACpE,KAAK,EAAE,KAAK,IAAI,EAAE;QAClB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE;KACtC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,KAAK,SAAS,IAAK,GAAG,CAAC,KAA+B,CAAC,IAAI,KAAK,QAAQ,CAAC;IAClG,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC;AAC7F,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,CAAC,GAAc;IAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,cAAiC,CAAC,WAAW,CAAC;IACnF,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;IAClD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE/C;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,KAAoF;IAC7G,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC;IACvF,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAQzB;IACC,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,CAAC,KAAK,UAAU,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,oBAAoB,KAAK,CAAC,KAAK,UAAU,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACtG,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,GAAG,GAAG,wBAAwB,GAAG,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,KAAK,CAAC,QAAQ,EAAE,CAC3H,CAAC;IACJ,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC,6EAA6E;AAC7E,MAAM,UAAU,GAAG,YAAY,CAAC;AAEhC,SAAS,UAAU,CAAC,IAAc,EAAE,IAAY;IAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CAAC,KAAkB,EAAE,IAAY,EAAE,QAAoB,EAAE,KAAa;IAC3F,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACjE,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5G,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,oDAAoD,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACvG,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC7B,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,oBAAoB,IAAI,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,QAAQ,CAAC,KAAkB,EAAE,OAAqC,EAAE,OAAe;IAC1F,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,OAAO,CAAC,KAAkB,EAAE,OAAoC,EAAE,OAAe;IACxF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9C,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YACH,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACP,4DAA4D;QAC9D,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Fly.io. `fly secrets import` reads `KEY=VALUE` lines from stdin, which is
|
|
4
|
+
* the only way to set a secret without putting the value in argv. It replaces
|
|
5
|
+
* an existing secret and stages a release for the app.
|
|
6
|
+
*/
|
|
7
|
+
export declare const fly: SecretStore;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { preflight } from "./exec.js";
|
|
2
|
+
import { envStyleName, slug } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install flyctl from https://fly.io/docs/flyctl/install (brew install flyctl), then run `fly auth login`";
|
|
4
|
+
function target(options) {
|
|
5
|
+
const app = options.app ? slug("--app", options.app, /^[a-z0-9-]+$/) : undefined;
|
|
6
|
+
return {
|
|
7
|
+
describe: app ? `Fly app ${app}` : "the Fly app in this directory's fly.toml",
|
|
8
|
+
fields: app ? { app } : {},
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Fly.io. `fly secrets import` reads `KEY=VALUE` lines from stdin, which is
|
|
13
|
+
* the only way to set a secret without putting the value in argv. It replaces
|
|
14
|
+
* an existing secret and stages a release for the app.
|
|
15
|
+
*/
|
|
16
|
+
export const fly = {
|
|
17
|
+
id: "fly",
|
|
18
|
+
label: "Fly.io",
|
|
19
|
+
bin: "fly",
|
|
20
|
+
altBins: ["flyctl"],
|
|
21
|
+
shorthand: "--fly-secret",
|
|
22
|
+
nameLabel: "NAME",
|
|
23
|
+
installHint: INSTALL_HINT,
|
|
24
|
+
options: ["app"],
|
|
25
|
+
validateName: (name) => envStyleName("Fly secret", name),
|
|
26
|
+
preflight: () => preflight({
|
|
27
|
+
bin: "fly",
|
|
28
|
+
altBins: ["flyctl"],
|
|
29
|
+
label: "Fly.io",
|
|
30
|
+
installHint: INSTALL_HINT,
|
|
31
|
+
authArgs: ["auth", "whoami"],
|
|
32
|
+
authHint: "Run `fly auth login` first, or set FLY_API_TOKEN.",
|
|
33
|
+
}),
|
|
34
|
+
resolveTarget: target,
|
|
35
|
+
deliveries: (name, t) => {
|
|
36
|
+
const args = ["secrets", "import"];
|
|
37
|
+
if (t.fields.app)
|
|
38
|
+
args.push("--app", t.fields.app);
|
|
39
|
+
return [
|
|
40
|
+
{
|
|
41
|
+
note: "fly secrets import",
|
|
42
|
+
kind: "stdin",
|
|
43
|
+
args,
|
|
44
|
+
payload: (value) => `${name}=${value}\n`,
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
},
|
|
48
|
+
usage: (name, _t, gateway) => [
|
|
49
|
+
`${name} is in the app's environment after the release finishes:`,
|
|
50
|
+
` OPENAI_API_KEY=$${name} with OPENAI_BASE_URL=${gateway.openaiBaseUrl}`,
|
|
51
|
+
` # or ANTHROPIC_AUTH_TOKEN with ANTHROPIC_BASE_URL=${gateway.anthropicBaseUrl}`,
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=fly.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fly.js","sourceRoot":"","sources":["../../src/secret-stores/fly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,YAAY,GAChB,yGAAyG,CAAC;AAE5G,SAAS,MAAM,CAAC,OAAqB;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjF,OAAO;QACL,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,0CAA0C;QAC7E,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE;KAC3B,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,GAAG,GAAgB;IAC9B,EAAE,EAAE,KAAK;IACT,KAAK,EAAE,QAAQ;IACf,GAAG,EAAE,KAAK;IACV,OAAO,EAAE,CAAC,QAAQ,CAAC;IACnB,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,YAAY;IACzB,OAAO,EAAE,CAAC,KAAK,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC;IACxD,SAAS,EAAE,GAAG,EAAE,CACd,SAAS,CAAC;QACR,GAAG,EAAE,KAAK;QACV,OAAO,EAAE,CAAC,QAAQ,CAAC;QACnB,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,YAAY;QACzB,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QAC5B,QAAQ,EAAE,mDAAmD;KAC9D,CAAC;IACJ,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG;YAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnD,OAAO;YACL;gBACE,IAAI,EAAE,oBAAoB;gBAC1B,IAAI,EAAE,OAAO;gBACb,IAAI;gBACJ,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI;aACzC;SACF,CAAC;IACJ,CAAC;IACD,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC;QAC5B,GAAG,IAAI,0DAA0D;QACjE,qBAAqB,IAAI,yBAAyB,OAAO,CAAC,aAAa,EAAE;QACzE,uDAAuD,OAAO,CAAC,gBAAgB,EAAE;KAClF;CACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Google Secret Manager. Both `secrets create` and `versions add` read the
|
|
4
|
+
* payload from stdin with `--data-file=-`; creation fails when the secret
|
|
5
|
+
* already exists, so the second attempt adds a version to it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const gcloud: SecretStore;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { preflight, run, trimmedStderr } from "./exec.js";
|
|
2
|
+
import { resourceName, slug } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install the Google Cloud CLI from https://cloud.google.com/sdk/docs/install (brew install --cask google-cloud-sdk), then run `gcloud auth login`";
|
|
4
|
+
/** The project gcloud is currently configured for, so --project stays optional. */
|
|
5
|
+
function resolveProjectFromConfig() {
|
|
6
|
+
const res = run("gcloud", ["config", "get-value", "project"]);
|
|
7
|
+
const project = res.stdout.trim();
|
|
8
|
+
if (res.status !== 0 || !project || project === "(unset)") {
|
|
9
|
+
const detail = trimmedStderr(res);
|
|
10
|
+
throw new Error(`gcloud has no active project${detail ? ` (${detail})` : ""}. Pass --project my-project, or run \`gcloud config set project my-project\`.`);
|
|
11
|
+
}
|
|
12
|
+
return project;
|
|
13
|
+
}
|
|
14
|
+
function target(options) {
|
|
15
|
+
const project = options.project ? slug("--project", options.project) : resolveProjectFromConfig();
|
|
16
|
+
return { describe: `Google Secret Manager in project ${project}`, fields: { project } };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Google Secret Manager. Both `secrets create` and `versions add` read the
|
|
20
|
+
* payload from stdin with `--data-file=-`; creation fails when the secret
|
|
21
|
+
* already exists, so the second attempt adds a version to it.
|
|
22
|
+
*/
|
|
23
|
+
export const gcloud = {
|
|
24
|
+
id: "gcloud",
|
|
25
|
+
label: "Google Secret Manager",
|
|
26
|
+
bin: "gcloud",
|
|
27
|
+
shorthand: "--gcp-secret",
|
|
28
|
+
nameLabel: "NAME",
|
|
29
|
+
installHint: INSTALL_HINT,
|
|
30
|
+
options: ["project"],
|
|
31
|
+
validateName: (name) => resourceName("Google Secret Manager secret", name, "_"),
|
|
32
|
+
preflight: () => preflight({
|
|
33
|
+
bin: "gcloud",
|
|
34
|
+
label: "Google Secret Manager",
|
|
35
|
+
installHint: INSTALL_HINT,
|
|
36
|
+
authArgs: ["auth", "print-access-token"],
|
|
37
|
+
authHint: "Run `gcloud auth login` first.",
|
|
38
|
+
}),
|
|
39
|
+
resolveTarget: target,
|
|
40
|
+
deliveries: (name, t) => {
|
|
41
|
+
const project = ["--project", t.fields.project];
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
note: "gcloud secrets create",
|
|
45
|
+
kind: "stdin",
|
|
46
|
+
args: ["secrets", "create", name, "--data-file=-", "--replication-policy=automatic", ...project],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
note: "gcloud secrets versions add",
|
|
50
|
+
kind: "stdin",
|
|
51
|
+
args: ["secrets", "versions", "add", name, "--data-file=-", ...project],
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
},
|
|
55
|
+
usage: (name, t, gateway) => [
|
|
56
|
+
"Read it back at runtime:",
|
|
57
|
+
` gcloud secrets versions access latest --secret=${name} --project=${t.fields.project}`,
|
|
58
|
+
` # export OPENAI_API_KEY=$(…) with OPENAI_BASE_URL=${gateway.openaiBaseUrl}`,
|
|
59
|
+
` # Cloud Run: gcloud run deploy … --set-secrets OPENAI_API_KEY=${name}:latest`,
|
|
60
|
+
],
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=gcloud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcloud.js","sourceRoot":"","sources":["../../src/secret-stores/gcloud.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGjD,MAAM,YAAY,GAChB,kJAAkJ,CAAC;AAErJ,mFAAmF;AACnF,SAAS,wBAAwB;IAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAClC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,+BAA+B,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,+EAA+E,CAC3I,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,MAAM,CAAC,OAAqB;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC;IAClG,OAAO,EAAE,QAAQ,EAAE,oCAAoC,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC;AAC1F,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAgB;IACjC,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,uBAAuB;IAC9B,GAAG,EAAE,QAAQ;IACb,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,YAAY;IACzB,OAAO,EAAE,CAAC,SAAS,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,8BAA8B,EAAE,IAAI,EAAE,GAAG,CAAC;IAC/E,SAAS,EAAE,GAAG,EAAE,CACd,SAAS,CAAC;QACR,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,YAAY;QACzB,QAAQ,EAAE,CAAC,MAAM,EAAE,oBAAoB,CAAC;QACxC,QAAQ,EAAE,gCAAgC;KAC3C,CAAC;IACJ,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACtB,MAAM,OAAO,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChD,OAAO;YACL;gBACE,IAAI,EAAE,uBAAuB;gBAC7B,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,gCAAgC,EAAE,GAAG,OAAO,CAAC;aACjG;YACD;gBACE,IAAI,EAAE,6BAA6B;gBACnC,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;aACxE;SACF,CAAC;IACJ,CAAC;IACD,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3B,0BAA0B;QAC1B,oDAAoD,IAAI,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE;QACxF,uDAAuD,OAAO,CAAC,aAAa,EAAE;QAC9E,mEAAmE,IAAI,SAAS;KACjF;CACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
export declare const GH_INSTALL_HINT = "install the GitHub CLI from https://cli.github.com (brew install gh / winget install GitHub.cli), then run `gh auth login`";
|
|
3
|
+
/** Resolves owner/repo for the current directory the same way `gh` does (git remotes + gh config). */
|
|
4
|
+
export declare function resolveRepoFromCwd(): string;
|
|
5
|
+
/**
|
|
6
|
+
* GitHub Actions. `gh secret set` reads the value from stdin when `--body` is
|
|
7
|
+
* omitted, so the key never appears in argv, `ps`, shell history or our output.
|
|
8
|
+
*/
|
|
9
|
+
export declare const github: SecretStore;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { preflight, run, trimmedStderr } from "./exec.js";
|
|
2
|
+
import { validateRepo, validateSecretName } from "./naming.js";
|
|
3
|
+
export const GH_INSTALL_HINT = "install the GitHub CLI from https://cli.github.com (brew install gh / winget install GitHub.cli), then run `gh auth login`";
|
|
4
|
+
/** Resolves owner/repo for the current directory the same way `gh` does (git remotes + gh config). */
|
|
5
|
+
export function resolveRepoFromCwd() {
|
|
6
|
+
const res = run("gh", ["repo", "view", "--json", "nameWithOwner", "-q", ".nameWithOwner"]);
|
|
7
|
+
const repo = res.stdout.trim();
|
|
8
|
+
if (res.status !== 0 || !repo) {
|
|
9
|
+
const detail = trimmedStderr(res);
|
|
10
|
+
throw new Error(`could not determine the GitHub repository from the current directory${detail ? ` (${detail})` : ""}. Pass --repo owner/repo, or run from inside a clone with a GitHub remote.`);
|
|
11
|
+
}
|
|
12
|
+
return repo;
|
|
13
|
+
}
|
|
14
|
+
/** Where the secret lands: a repository, one of its environments, or an organization. */
|
|
15
|
+
function target(options) {
|
|
16
|
+
const org = options.org?.trim();
|
|
17
|
+
const env = options.env?.trim();
|
|
18
|
+
if (org) {
|
|
19
|
+
if (options.repo || env) {
|
|
20
|
+
throw new Error("--org cannot be combined with --repo or --env (organization secrets are not scoped to one repository)");
|
|
21
|
+
}
|
|
22
|
+
if (!/^[A-Za-z0-9_.-]+$/.test(org))
|
|
23
|
+
throw new Error(`--org must be an organization login, got "${options.org}"`);
|
|
24
|
+
return { describe: `organization ${org}`, fields: { kind: "org", org } };
|
|
25
|
+
}
|
|
26
|
+
const repo = options.repo ? validateRepo(options.repo) : resolveRepoFromCwd();
|
|
27
|
+
if (env)
|
|
28
|
+
return { describe: `${repo}, environment ${env}`, fields: { kind: "env", repo, env } };
|
|
29
|
+
return { describe: `${repo} (repository secret)`, fields: { kind: "repo", repo } };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* GitHub Actions. `gh secret set` reads the value from stdin when `--body` is
|
|
33
|
+
* omitted, so the key never appears in argv, `ps`, shell history or our output.
|
|
34
|
+
*/
|
|
35
|
+
export const github = {
|
|
36
|
+
id: "github",
|
|
37
|
+
label: "GitHub Actions",
|
|
38
|
+
bin: "gh",
|
|
39
|
+
shorthand: "--gh-secret",
|
|
40
|
+
nameLabel: "NAME",
|
|
41
|
+
installHint: GH_INSTALL_HINT,
|
|
42
|
+
options: ["repo", "env", "org"],
|
|
43
|
+
validateName: validateSecretName,
|
|
44
|
+
preflight: () => preflight({
|
|
45
|
+
bin: "gh",
|
|
46
|
+
label: "GitHub Actions",
|
|
47
|
+
installHint: GH_INSTALL_HINT,
|
|
48
|
+
authArgs: ["auth", "status"],
|
|
49
|
+
authHint: "Run `gh auth login` first.",
|
|
50
|
+
}),
|
|
51
|
+
resolveTarget: target,
|
|
52
|
+
deliveries: (name, t) => {
|
|
53
|
+
const args = ["secret", "set", name];
|
|
54
|
+
if (t.fields.kind === "org")
|
|
55
|
+
args.push("--org", t.fields.org);
|
|
56
|
+
else if (t.fields.kind === "env")
|
|
57
|
+
args.push("--repo", t.fields.repo, "--env", t.fields.env);
|
|
58
|
+
else
|
|
59
|
+
args.push("--repo", t.fields.repo);
|
|
60
|
+
return [{ note: "gh secret set", kind: "stdin", args }];
|
|
61
|
+
},
|
|
62
|
+
// Both predate the multi-store registry and are part of the published
|
|
63
|
+
// contract: key labels in the app and the `snippet` field in --output json.
|
|
64
|
+
keyName: (name, t) => (t.fields.kind === "org" ? `gh-secret:${name}` : `gh:${t.fields.repo}:${name}`),
|
|
65
|
+
snippet: (name) => `\${{ secrets.${name} }}`,
|
|
66
|
+
usage: (name, _t, gateway) => [
|
|
67
|
+
"Use it in a workflow step:",
|
|
68
|
+
" env:",
|
|
69
|
+
` ANTHROPIC_AUTH_TOKEN: \${{ secrets.${name} }}`,
|
|
70
|
+
` ANTHROPIC_BASE_URL: ${gateway.anthropicBaseUrl}`,
|
|
71
|
+
` # OpenAI-compatible clients: OPENAI_API_KEY: \${{ secrets.${name} }} with OPENAI_BASE_URL: ${gateway.openaiBaseUrl}`,
|
|
72
|
+
],
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/secret-stores/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* GitLab CI/CD variables. `glab variable set KEY` reads the value from stdin
|
|
4
|
+
* when no value argument is given (`cat file | glab variable set KEY`), and
|
|
5
|
+
* `--masked` keeps it out of job logs.
|
|
6
|
+
*/
|
|
7
|
+
export declare const gitlab: SecretStore;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { preflight, run, trimmedStderr } from "./exec.js";
|
|
2
|
+
import { envStyleName, slug } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install the GitLab CLI from https://gitlab.com/gitlab-org/cli (brew install glab), then run `glab auth login`";
|
|
4
|
+
/** Resolves the project for the current directory the way glab itself does. */
|
|
5
|
+
function resolveProjectFromCwd() {
|
|
6
|
+
const res = run("glab", ["repo", "view", "-F", "json"]);
|
|
7
|
+
if (res.status === 0) {
|
|
8
|
+
try {
|
|
9
|
+
const parsed = JSON.parse(res.stdout);
|
|
10
|
+
if (parsed.path_with_namespace)
|
|
11
|
+
return parsed.path_with_namespace;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// Fall through to the shared error below.
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const detail = trimmedStderr(res);
|
|
18
|
+
throw new Error(`could not determine the GitLab project from the current directory${detail ? ` (${detail})` : ""}. Pass --project group/project, or run from inside a clone with a GitLab remote.`);
|
|
19
|
+
}
|
|
20
|
+
function target(options) {
|
|
21
|
+
const group = options.org?.trim();
|
|
22
|
+
const env = options.env?.trim();
|
|
23
|
+
if (group) {
|
|
24
|
+
if (options.project)
|
|
25
|
+
throw new Error("--org (GitLab group) cannot be combined with --project");
|
|
26
|
+
const g = slug("--org", group, /^[A-Za-z0-9_.\-/]+$/);
|
|
27
|
+
return { describe: `group ${g}`, fields: { kind: "group", group: g, ...(env ? { env } : {}) } };
|
|
28
|
+
}
|
|
29
|
+
const project = options.project ? slug("--project", options.project, /^[A-Za-z0-9_.\-/]+$/) : resolveProjectFromCwd();
|
|
30
|
+
return {
|
|
31
|
+
describe: `${project}${env ? `, environment scope ${env}` : ""} (CI/CD variable)`,
|
|
32
|
+
fields: { kind: "project", project, ...(env ? { env } : {}) },
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* GitLab CI/CD variables. `glab variable set KEY` reads the value from stdin
|
|
37
|
+
* when no value argument is given (`cat file | glab variable set KEY`), and
|
|
38
|
+
* `--masked` keeps it out of job logs.
|
|
39
|
+
*/
|
|
40
|
+
export const gitlab = {
|
|
41
|
+
id: "gitlab",
|
|
42
|
+
label: "GitLab CI/CD",
|
|
43
|
+
bin: "glab",
|
|
44
|
+
shorthand: "--gitlab-var",
|
|
45
|
+
nameLabel: "NAME",
|
|
46
|
+
installHint: INSTALL_HINT,
|
|
47
|
+
options: ["project", "org", "env"],
|
|
48
|
+
validateName: (name) => envStyleName("GitLab CI/CD variable", name),
|
|
49
|
+
preflight: () => preflight({
|
|
50
|
+
bin: "glab",
|
|
51
|
+
label: "GitLab CI/CD",
|
|
52
|
+
installHint: INSTALL_HINT,
|
|
53
|
+
authArgs: ["auth", "status"],
|
|
54
|
+
authHint: "Run `glab auth login` first.",
|
|
55
|
+
}),
|
|
56
|
+
resolveTarget: target,
|
|
57
|
+
deliveries: (name, t) => {
|
|
58
|
+
const scope = (verb) => {
|
|
59
|
+
const args = ["variable", verb, name, "--masked"];
|
|
60
|
+
if (t.fields.kind === "group")
|
|
61
|
+
args.push("--group", t.fields.group);
|
|
62
|
+
else
|
|
63
|
+
args.push("--repo", t.fields.project);
|
|
64
|
+
if (t.fields.env)
|
|
65
|
+
args.push("--scope", t.fields.env);
|
|
66
|
+
return args;
|
|
67
|
+
};
|
|
68
|
+
// `set` refuses an existing variable, so fall back to `update`.
|
|
69
|
+
return [
|
|
70
|
+
{ note: "glab variable set", kind: "stdin", args: scope("set") },
|
|
71
|
+
{ note: "glab variable update", kind: "stdin", args: scope("update") },
|
|
72
|
+
];
|
|
73
|
+
},
|
|
74
|
+
usage: (name, _t, gateway) => [
|
|
75
|
+
"Use it in .gitlab-ci.yml:",
|
|
76
|
+
" variables:",
|
|
77
|
+
` ANTHROPIC_BASE_URL: ${gateway.anthropicBaseUrl}`,
|
|
78
|
+
` # ${name} is injected into every job; for OpenAI-compatible clients set`,
|
|
79
|
+
` # OPENAI_API_KEY: $${name} with OPENAI_BASE_URL: ${gateway.openaiBaseUrl}`,
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=gitlab.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab.js","sourceRoot":"","sources":["../../src/secret-stores/gitlab.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type SecretStore, type StoreId, type StoreOptions } from "./types.js";
|
|
2
|
+
export { deliver, installed, resolveBin } from "./exec.js";
|
|
3
|
+
export { GH_INSTALL_HINT, resolveRepoFromCwd } from "./github.js";
|
|
4
|
+
export { validateRepo, validateSecretName } from "./naming.js";
|
|
5
|
+
export { STORE_IDS } from "./types.js";
|
|
6
|
+
export type { Delivery, Gateway, SecretStore, StoreId, StoreOptions, StoreTarget } from "./types.js";
|
|
7
|
+
export { VERCEL_TARGETS } from "./vercel.js";
|
|
8
|
+
/** Every store, in the order they are listed to the operator. */
|
|
9
|
+
export declare const STORES: readonly SecretStore[];
|
|
10
|
+
export declare function storeById(id: string): SecretStore;
|
|
11
|
+
/** `--store <id>` is the canonical selector; every store also has a shorthand. */
|
|
12
|
+
export interface StoreSelection {
|
|
13
|
+
store: SecretStore;
|
|
14
|
+
/** Secret / variable / item / path name. */
|
|
15
|
+
name: string;
|
|
16
|
+
/** The flag the operator actually used, for error messages. */
|
|
17
|
+
flag: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolves which store gets the key from `--store`/`--secret` or exactly one
|
|
21
|
+
* shorthand, and rejects flags that belong to a different store — silently
|
|
22
|
+
* ignoring `--repo` on an AWS run would store the secret somewhere the
|
|
23
|
+
* operator did not intend.
|
|
24
|
+
*/
|
|
25
|
+
export declare function selectStore(options: StoreOptions & {
|
|
26
|
+
store?: string;
|
|
27
|
+
shorthands: Partial<Record<StoreId, string>>;
|
|
28
|
+
}): StoreSelection;
|
|
29
|
+
export interface StoreProbe {
|
|
30
|
+
id: StoreId;
|
|
31
|
+
label: string;
|
|
32
|
+
bin: string;
|
|
33
|
+
/** The binary actually found on PATH (fly vs flyctl). */
|
|
34
|
+
resolvedBin: string;
|
|
35
|
+
installed: boolean;
|
|
36
|
+
shorthand: string;
|
|
37
|
+
nameLabel: string;
|
|
38
|
+
flags: string[];
|
|
39
|
+
installHint: string;
|
|
40
|
+
}
|
|
41
|
+
/** Which platform CLIs this machine has — the answer to "what can I delegate to?". */
|
|
42
|
+
export declare function probeStores(): StoreProbe[];
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { aws } from "./aws.js";
|
|
2
|
+
import { azure } from "./azure.js";
|
|
3
|
+
import { cloudflare } from "./cloudflare.js";
|
|
4
|
+
import { doppler } from "./doppler.js";
|
|
5
|
+
import { installed, resolveBin } from "./exec.js";
|
|
6
|
+
import { fly } from "./fly.js";
|
|
7
|
+
import { gcloud } from "./gcloud.js";
|
|
8
|
+
import { github } from "./github.js";
|
|
9
|
+
import { gitlab } from "./gitlab.js";
|
|
10
|
+
import { kubernetes } from "./kubernetes.js";
|
|
11
|
+
import { onepassword } from "./onepassword.js";
|
|
12
|
+
import { vault } from "./vault.js";
|
|
13
|
+
import { vercel } from "./vercel.js";
|
|
14
|
+
import { STORE_IDS } from "./types.js";
|
|
15
|
+
export { deliver, installed, resolveBin } from "./exec.js";
|
|
16
|
+
export { GH_INSTALL_HINT, resolveRepoFromCwd } from "./github.js";
|
|
17
|
+
export { validateRepo, validateSecretName } from "./naming.js";
|
|
18
|
+
export { STORE_IDS } from "./types.js";
|
|
19
|
+
export { VERCEL_TARGETS } from "./vercel.js";
|
|
20
|
+
/** Every store, in the order they are listed to the operator. */
|
|
21
|
+
export const STORES = [
|
|
22
|
+
github,
|
|
23
|
+
gitlab,
|
|
24
|
+
aws,
|
|
25
|
+
gcloud,
|
|
26
|
+
azure,
|
|
27
|
+
onepassword,
|
|
28
|
+
vault,
|
|
29
|
+
doppler,
|
|
30
|
+
cloudflare,
|
|
31
|
+
vercel,
|
|
32
|
+
kubernetes,
|
|
33
|
+
fly,
|
|
34
|
+
];
|
|
35
|
+
/** Human label for every flag, so "unsupported flag" errors name the flag the operator typed. */
|
|
36
|
+
const OPTION_FLAGS = {
|
|
37
|
+
repo: "--repo",
|
|
38
|
+
env: "--env",
|
|
39
|
+
org: "--org",
|
|
40
|
+
region: "--region",
|
|
41
|
+
project: "--project",
|
|
42
|
+
keyVault: "--key-vault",
|
|
43
|
+
opVault: "--op-vault",
|
|
44
|
+
mount: "--mount",
|
|
45
|
+
field: "--field",
|
|
46
|
+
dopplerConfig: "--doppler-config",
|
|
47
|
+
worker: "--worker",
|
|
48
|
+
vercelTarget: "--vercel-target",
|
|
49
|
+
namespace: "--namespace",
|
|
50
|
+
k8sKey: "--k8s-key",
|
|
51
|
+
app: "--app",
|
|
52
|
+
};
|
|
53
|
+
const OPTION_KEYS = Object.keys(OPTION_FLAGS);
|
|
54
|
+
export function storeById(id) {
|
|
55
|
+
const store = STORES.find((s) => s.id === id);
|
|
56
|
+
if (!store)
|
|
57
|
+
throw new Error(`unknown --store "${id}". Available: ${STORE_IDS.join(", ")}`);
|
|
58
|
+
return store;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Resolves which store gets the key from `--store`/`--secret` or exactly one
|
|
62
|
+
* shorthand, and rejects flags that belong to a different store — silently
|
|
63
|
+
* ignoring `--repo` on an AWS run would store the secret somewhere the
|
|
64
|
+
* operator did not intend.
|
|
65
|
+
*/
|
|
66
|
+
export function selectStore(options) {
|
|
67
|
+
const used = STORES.filter((s) => options.shorthands[s.id] !== undefined);
|
|
68
|
+
if (used.length > 1) {
|
|
69
|
+
throw new Error(`pick one destination: ${used.map((s) => s.shorthand).join(" and ")} cannot both be set`);
|
|
70
|
+
}
|
|
71
|
+
const shorthand = used[0];
|
|
72
|
+
if (shorthand && options.store && options.store !== shorthand.id) {
|
|
73
|
+
throw new Error(`--store ${options.store} contradicts ${shorthand.shorthand} (which implies --store ${shorthand.id})`);
|
|
74
|
+
}
|
|
75
|
+
const store = shorthand ?? (options.store ? storeById(options.store) : undefined);
|
|
76
|
+
if (!store) {
|
|
77
|
+
throw new Error(`pick a destination: --store <${STORE_IDS.join("|")}> with --secret <NAME>, or a shorthand such as ${github.shorthand} NAME. See \`heyditto endpoints keys stores\`.`);
|
|
78
|
+
}
|
|
79
|
+
const raw = shorthand ? options.shorthands[store.id] : options.secret;
|
|
80
|
+
const flag = shorthand ? store.shorthand : "--secret";
|
|
81
|
+
if (!raw)
|
|
82
|
+
throw new Error(`--store ${store.id} needs --secret <${store.nameLabel}>`);
|
|
83
|
+
const stray = OPTION_KEYS.filter((key) => options[key] !== undefined && !store.options.includes(key));
|
|
84
|
+
if (stray.length > 0) {
|
|
85
|
+
throw new Error(`${stray.map((key) => OPTION_FLAGS[key]).join(", ")} ${stray.length > 1 ? "do" : "does"} not apply to ${store.label}; it accepts ${store.options.map((key) => OPTION_FLAGS[key]).join(", ") || "no scoping flags"}`);
|
|
86
|
+
}
|
|
87
|
+
return { store, name: store.validateName(raw), flag };
|
|
88
|
+
}
|
|
89
|
+
/** Which platform CLIs this machine has — the answer to "what can I delegate to?". */
|
|
90
|
+
export function probeStores() {
|
|
91
|
+
return STORES.map((store) => {
|
|
92
|
+
const bin = resolveBin(store);
|
|
93
|
+
return {
|
|
94
|
+
id: store.id,
|
|
95
|
+
label: store.label,
|
|
96
|
+
bin: store.bin,
|
|
97
|
+
resolvedBin: bin,
|
|
98
|
+
installed: installed(bin, store.versionArgs),
|
|
99
|
+
shorthand: store.shorthand,
|
|
100
|
+
nameLabel: store.nameLabel,
|
|
101
|
+
flags: store.options.map((key) => OPTION_FLAGS[key]),
|
|
102
|
+
installHint: store.installHint,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/secret-stores/index.ts"],"names":[],"mappings":"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"}
|