@heyditto/cli 2.5.2 → 2.7.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 +47 -19
- package/dist/api.d.ts +13 -0
- package/dist/api.js +20 -0
- package/dist/api.js.map +1 -1
- package/dist/commands.d.ts +41 -3
- package/dist/commands.js +237 -61
- 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/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,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shape for every secret store the CLI can hand a freshly minted key to.
|
|
3
|
+
*
|
|
4
|
+
* The contract every store must honour: the plaintext key travels to the
|
|
5
|
+
* platform CLI over stdin (directly, or through a path the CLI reads such as
|
|
6
|
+
* `/dev/stdin`), never through argv. Anything in argv is visible to every
|
|
7
|
+
* process on the machine via `ps`, and lands in shell history when a human
|
|
8
|
+
* copies the command.
|
|
9
|
+
*/
|
|
10
|
+
/** Stable ids, also the values accepted by `--store`. */
|
|
11
|
+
export declare const STORE_IDS: readonly ["github", "gitlab", "aws", "gcloud", "azure", "1password", "vault", "doppler", "cloudflare", "vercel", "kubernetes", "fly"];
|
|
12
|
+
export type StoreId = (typeof STORE_IDS)[number];
|
|
13
|
+
/** Flags that scope where a secret lands. Each store reads the ones it supports. */
|
|
14
|
+
export interface StoreOptions {
|
|
15
|
+
/** Secret / variable / item name, from --secret or a store shorthand. */
|
|
16
|
+
secret?: string;
|
|
17
|
+
repo?: string;
|
|
18
|
+
env?: string;
|
|
19
|
+
org?: string;
|
|
20
|
+
region?: string;
|
|
21
|
+
project?: string;
|
|
22
|
+
keyVault?: string;
|
|
23
|
+
opVault?: string;
|
|
24
|
+
mount?: string;
|
|
25
|
+
field?: string;
|
|
26
|
+
dopplerConfig?: string;
|
|
27
|
+
worker?: string;
|
|
28
|
+
vercelTarget?: string;
|
|
29
|
+
namespace?: string;
|
|
30
|
+
k8sKey?: string;
|
|
31
|
+
app?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Every option name a store may claim, for the "unsupported flag" check. */
|
|
34
|
+
export type StoreOptionKey = Exclude<keyof StoreOptions, "secret">;
|
|
35
|
+
/**
|
|
36
|
+
* Where the secret lands, resolved from the flags (and sometimes the current
|
|
37
|
+
* directory). `fields` are echoed into `--output json`; `describe` is the human
|
|
38
|
+
* sentence in the confirmation prompt and the success line.
|
|
39
|
+
*/
|
|
40
|
+
export interface StoreTarget {
|
|
41
|
+
describe: string;
|
|
42
|
+
fields: Record<string, string>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* How the plaintext reaches the platform CLI.
|
|
46
|
+
*
|
|
47
|
+
* - `stdin`: the value (or a rendered `payload`) is written to the child's stdin.
|
|
48
|
+
* - `path`: argv names a file the CLI reads. On POSIX that is `/dev/stdin` with
|
|
49
|
+
* the value piped in; on Windows the runner writes a 0600 temp file and
|
|
50
|
+
* substitutes its path for the `{}` placeholder.
|
|
51
|
+
*
|
|
52
|
+
* `note` explains what the attempt does, for the error message when every
|
|
53
|
+
* attempt fails.
|
|
54
|
+
*/
|
|
55
|
+
export type Delivery = {
|
|
56
|
+
note: string;
|
|
57
|
+
/** Wraps the plaintext (a JSON template, a KEY=VALUE line) before it is sent. */
|
|
58
|
+
payload?: (value: string) => string;
|
|
59
|
+
} & ({
|
|
60
|
+
kind: "stdin";
|
|
61
|
+
args: string[];
|
|
62
|
+
} | {
|
|
63
|
+
kind: "path";
|
|
64
|
+
args: string[];
|
|
65
|
+
});
|
|
66
|
+
export interface Gateway {
|
|
67
|
+
/** OpenAI-compatible base, e.g. https://inference.heyditto.ai/v1 */
|
|
68
|
+
openaiBaseUrl: string;
|
|
69
|
+
/** Anthropic base (no /v1), e.g. https://inference.heyditto.ai */
|
|
70
|
+
anthropicBaseUrl: string;
|
|
71
|
+
}
|
|
72
|
+
export interface SecretStore {
|
|
73
|
+
id: StoreId;
|
|
74
|
+
/** Human label, e.g. "GitHub Actions". */
|
|
75
|
+
label: string;
|
|
76
|
+
/** Executable the CLI delegates to. */
|
|
77
|
+
bin: string;
|
|
78
|
+
/** Other names the same CLI ships under, e.g. flyctl for fly. */
|
|
79
|
+
altBins?: readonly string[];
|
|
80
|
+
/** How this CLI reports its version (az and vault do not take --version). */
|
|
81
|
+
versionArgs?: readonly string[];
|
|
82
|
+
/** Shorthand flag that both selects this store and names the secret. */
|
|
83
|
+
shorthand: string;
|
|
84
|
+
/** What the shorthand's value is called in help text, e.g. "NAME" or "TITLE". */
|
|
85
|
+
nameLabel: string;
|
|
86
|
+
/** How to get the CLI and sign in, quoted in errors when it is missing. */
|
|
87
|
+
installHint: string;
|
|
88
|
+
/** Scoping options this store understands; anything else is rejected. */
|
|
89
|
+
options: readonly StoreOptionKey[];
|
|
90
|
+
/** Rejects names the platform will not accept. Returns the trimmed name. */
|
|
91
|
+
validateName(name: string): string;
|
|
92
|
+
/** Cheap failure before anything is minted: binary present and signed in. */
|
|
93
|
+
preflight(): void;
|
|
94
|
+
/** Reads the scoping flags; may infer from the cwd the way `gh` does. */
|
|
95
|
+
resolveTarget(options: StoreOptions): StoreTarget;
|
|
96
|
+
/**
|
|
97
|
+
* Attempts, in order, for storing `name` at `target`. Several platforms
|
|
98
|
+
* separate "create" from "add a new version", so the second attempt runs
|
|
99
|
+
* only when the first fails (e.g. the secret already exists).
|
|
100
|
+
*/
|
|
101
|
+
deliveries(name: string, target: StoreTarget): Delivery[];
|
|
102
|
+
/** How to read the secret back / wire it into a runtime. */
|
|
103
|
+
usage(name: string, target: StoreTarget, gateway: Gateway): string[];
|
|
104
|
+
/** Key label in the Ditto app. Defaults to `<store>:<target>:<name>`. */
|
|
105
|
+
keyName?(name: string, target: StoreTarget): string;
|
|
106
|
+
/** Platform reference for the stored value, echoed in `--output json`. */
|
|
107
|
+
snippet?(name: string, target: StoreTarget): string;
|
|
108
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared shape for every secret store the CLI can hand a freshly minted key to.
|
|
3
|
+
*
|
|
4
|
+
* The contract every store must honour: the plaintext key travels to the
|
|
5
|
+
* platform CLI over stdin (directly, or through a path the CLI reads such as
|
|
6
|
+
* `/dev/stdin`), never through argv. Anything in argv is visible to every
|
|
7
|
+
* process on the machine via `ps`, and lands in shell history when a human
|
|
8
|
+
* copies the command.
|
|
9
|
+
*/
|
|
10
|
+
/** Stable ids, also the values accepted by `--store`. */
|
|
11
|
+
export const STORE_IDS = [
|
|
12
|
+
"github",
|
|
13
|
+
"gitlab",
|
|
14
|
+
"aws",
|
|
15
|
+
"gcloud",
|
|
16
|
+
"azure",
|
|
17
|
+
"1password",
|
|
18
|
+
"vault",
|
|
19
|
+
"doppler",
|
|
20
|
+
"cloudflare",
|
|
21
|
+
"vercel",
|
|
22
|
+
"kubernetes",
|
|
23
|
+
"fly",
|
|
24
|
+
];
|
|
25
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/secret-stores/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yDAAyD;AACzD,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,OAAO;IACP,WAAW;IACX,OAAO;IACP,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,YAAY;IACZ,KAAK;CACG,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* HashiCorp Vault kv. `FIELD=-` makes Vault read that single field's value
|
|
4
|
+
* from stdin. `kv patch` leaves the path's other fields alone but needs the
|
|
5
|
+
* path to exist, so `kv put` is the fallback that creates it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const vault: SecretStore;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { preflight } from "./exec.js";
|
|
2
|
+
import { secretPath, slug } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install the Vault CLI from https://developer.hashicorp.com/vault/install (brew install hashicorp/tap/vault), then export VAULT_ADDR and run `vault login`";
|
|
4
|
+
function target(options) {
|
|
5
|
+
const mount = options.mount ? slug("--mount", options.mount, /^[A-Za-z0-9_.\-/]+$/) : "secret";
|
|
6
|
+
const field = options.field ? slug("--field", options.field, /^[A-Za-z0-9_.-]+$/) : "token";
|
|
7
|
+
return { describe: `Vault ${mount}/ (field ${field})`, fields: { mount, field } };
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* HashiCorp Vault kv. `FIELD=-` makes Vault read that single field's value
|
|
11
|
+
* from stdin. `kv patch` leaves the path's other fields alone but needs the
|
|
12
|
+
* path to exist, so `kv put` is the fallback that creates it.
|
|
13
|
+
*/
|
|
14
|
+
export const vault = {
|
|
15
|
+
id: "vault",
|
|
16
|
+
label: "HashiCorp Vault",
|
|
17
|
+
bin: "vault",
|
|
18
|
+
shorthand: "--vault-secret",
|
|
19
|
+
nameLabel: "PATH",
|
|
20
|
+
installHint: INSTALL_HINT,
|
|
21
|
+
versionArgs: ["version"],
|
|
22
|
+
options: ["mount", "field"],
|
|
23
|
+
validateName: (name) => secretPath("Vault kv path", name),
|
|
24
|
+
preflight: () => preflight({
|
|
25
|
+
bin: "vault",
|
|
26
|
+
label: "HashiCorp Vault",
|
|
27
|
+
installHint: INSTALL_HINT,
|
|
28
|
+
versionArgs: vault.versionArgs,
|
|
29
|
+
authArgs: ["token", "lookup"],
|
|
30
|
+
authHint: "Set VAULT_ADDR and run `vault login` first.",
|
|
31
|
+
}),
|
|
32
|
+
resolveTarget: target,
|
|
33
|
+
deliveries: (path, t) => {
|
|
34
|
+
const args = (verb) => ["kv", verb, `-mount=${t.fields.mount}`, path, `${t.fields.field}=-`];
|
|
35
|
+
return [
|
|
36
|
+
{ note: "vault kv patch", kind: "stdin", args: args("patch") },
|
|
37
|
+
{ note: "vault kv put", kind: "stdin", args: args("put") },
|
|
38
|
+
];
|
|
39
|
+
},
|
|
40
|
+
usage: (path, t, gateway) => [
|
|
41
|
+
"Read it back at runtime:",
|
|
42
|
+
` vault kv get -mount=${t.fields.mount} -field=${t.fields.field} ${path}`,
|
|
43
|
+
` # export OPENAI_API_KEY=$(…) with OPENAI_BASE_URL=${gateway.openaiBaseUrl}`,
|
|
44
|
+
` # or ANTHROPIC_AUTH_TOKEN with ANTHROPIC_BASE_URL=${gateway.anthropicBaseUrl}`,
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/secret-stores/vault.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,YAAY,GAChB,2JAA2J,CAAC;AAE9J,SAAS,MAAM,CAAC,OAAqB;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/F,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5F,OAAO,EAAE,QAAQ,EAAE,SAAS,KAAK,YAAY,KAAK,GAAG,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAgB;IAChC,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,iBAAiB;IACxB,GAAG,EAAE,OAAO;IACZ,SAAS,EAAE,gBAAgB;IAC3B,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,YAAY;IACzB,WAAW,EAAE,CAAC,SAAS,CAAC;IACxB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC;IACzD,SAAS,EAAE,GAAG,EAAE,CACd,SAAS,CAAC;QACR,GAAG,EAAE,OAAO;QACZ,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC7B,QAAQ,EAAE,6CAA6C;KACxD,CAAC;IACJ,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACtB,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QACrG,OAAO;YACL,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;YAC9D,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE;SAC3D,CAAC;IACJ,CAAC;IACD,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3B,0BAA0B;QAC1B,yBAAyB,CAAC,CAAC,MAAM,CAAC,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE;QAC1E,uDAAuD,OAAO,CAAC,aAAa,EAAE;QAC9E,uDAAuD,OAAO,CAAC,gBAAgB,EAAE;KAClF;CACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SecretStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Vercel environment variables. `vercel env add NAME <target>` takes the value
|
|
4
|
+
* from stdin (its `--value` flag is the argv-leaking alternative); `--force`
|
|
5
|
+
* replaces an existing variable and `--sensitive` hides it from the dashboard.
|
|
6
|
+
*/
|
|
7
|
+
export declare const vercel: SecretStore;
|
|
8
|
+
/** Exported for the flag's help text and tests. */
|
|
9
|
+
export declare const VERCEL_TARGETS: readonly ["production", "preview", "development"];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { preflight } from "./exec.js";
|
|
2
|
+
import { envStyleName } from "./naming.js";
|
|
3
|
+
const INSTALL_HINT = "install the Vercel CLI from https://vercel.com/docs/cli (npm i -g vercel), then run `vercel login` and `vercel link`";
|
|
4
|
+
const TARGETS = ["production", "preview", "development"];
|
|
5
|
+
function target(options) {
|
|
6
|
+
const raw = options.vercelTarget?.trim() ?? "production";
|
|
7
|
+
if (!TARGETS.includes(raw)) {
|
|
8
|
+
throw new Error(`--vercel-target must be one of: ${TARGETS.join(", ")}`);
|
|
9
|
+
}
|
|
10
|
+
return { describe: `Vercel ${raw} environment`, fields: { target: raw } };
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Vercel environment variables. `vercel env add NAME <target>` takes the value
|
|
14
|
+
* from stdin (its `--value` flag is the argv-leaking alternative); `--force`
|
|
15
|
+
* replaces an existing variable and `--sensitive` hides it from the dashboard.
|
|
16
|
+
*/
|
|
17
|
+
export const vercel = {
|
|
18
|
+
id: "vercel",
|
|
19
|
+
label: "Vercel",
|
|
20
|
+
bin: "vercel",
|
|
21
|
+
shorthand: "--vercel-env",
|
|
22
|
+
nameLabel: "NAME",
|
|
23
|
+
installHint: INSTALL_HINT,
|
|
24
|
+
options: ["vercelTarget"],
|
|
25
|
+
validateName: (name) => envStyleName("Vercel environment variable", name),
|
|
26
|
+
preflight: () => preflight({
|
|
27
|
+
bin: "vercel",
|
|
28
|
+
label: "Vercel",
|
|
29
|
+
installHint: INSTALL_HINT,
|
|
30
|
+
authArgs: ["whoami"],
|
|
31
|
+
authHint: "Run `vercel login` first, or set VERCEL_TOKEN.",
|
|
32
|
+
}),
|
|
33
|
+
resolveTarget: target,
|
|
34
|
+
deliveries: (name, t) => [
|
|
35
|
+
{
|
|
36
|
+
note: "vercel env add",
|
|
37
|
+
kind: "stdin",
|
|
38
|
+
args: ["env", "add", name, t.fields.target, "--force", "--sensitive", "--yes", "--non-interactive"],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
usage: (name, t, gateway) => [
|
|
42
|
+
`Pull it into a local .env: vercel env pull --environment=${t.fields.target}`,
|
|
43
|
+
` # ${name} is in the ${t.fields.target} environment of the linked project`,
|
|
44
|
+
` # point clients at OPENAI_BASE_URL=${gateway.openaiBaseUrl}`,
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
/** Exported for the flag's help text and tests. */
|
|
48
|
+
export const VERCEL_TARGETS = TARGETS;
|
|
49
|
+
//# sourceMappingURL=vercel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../src/secret-stores/vercel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,YAAY,GAChB,sHAAsH,CAAC;AAEzH,MAAM,OAAO,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,aAAa,CAAU,CAAC;AAElE,SAAS,MAAM,CAAC,OAAqB;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,YAAY,CAAC;IACzD,IAAI,CAAE,OAA6B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,UAAU,GAAG,cAAc,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;AAC5E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAgB;IACjC,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,QAAQ;IACf,GAAG,EAAE,QAAQ;IACb,SAAS,EAAE,cAAc;IACzB,SAAS,EAAE,MAAM;IACjB,WAAW,EAAE,YAAY;IACzB,OAAO,EAAE,CAAC,cAAc,CAAC;IACzB,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,6BAA6B,EAAE,IAAI,CAAC;IACzE,SAAS,EAAE,GAAG,EAAE,CACd,SAAS,CAAC;QACR,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,QAAQ;QACf,WAAW,EAAE,YAAY;QACzB,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,QAAQ,EAAE,gDAAgD;KAC3D,CAAC;IACJ,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QACvB;YACE,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,CAAC;SACpG;KACF;IACD,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3B,4DAA4D,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE;QAC7E,OAAO,IAAI,cAAc,CAAC,CAAC,MAAM,CAAC,MAAM,oCAAoC;QAC5E,wCAAwC,OAAO,CAAC,aAAa,EAAE;KAChE;CACF,CAAC;AAEF,mDAAmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC"}
|
package/package.json
CHANGED
package/dist/gh-secret.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thin wrapper over the GitHub CLI for storing a freshly minted endpoint key
|
|
3
|
-
* as an Actions secret. The plaintext only ever travels over `gh`'s stdin:
|
|
4
|
-
* `gh secret set` reads the value from stdin when `--body` is omitted, so the
|
|
5
|
-
* key never appears in argv, `ps`, shell history or our own output.
|
|
6
|
-
*/
|
|
7
|
-
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`";
|
|
8
|
-
/** Where the secret lands. Exactly one of repo (with optional env) or org. */
|
|
9
|
-
export type SecretTarget = {
|
|
10
|
-
kind: "repo";
|
|
11
|
-
repo: string;
|
|
12
|
-
} | {
|
|
13
|
-
kind: "env";
|
|
14
|
-
repo: string;
|
|
15
|
-
env: string;
|
|
16
|
-
} | {
|
|
17
|
-
kind: "org";
|
|
18
|
-
org: string;
|
|
19
|
-
};
|
|
20
|
-
/** GitHub Actions secret names: letters, digits, underscores; not starting with a digit or GITHUB_. */
|
|
21
|
-
export declare function validateSecretName(name: string): string;
|
|
22
|
-
export declare function validateRepo(repo: string): string;
|
|
23
|
-
/** Fails fast when `gh` is missing or not signed in; nothing has been minted at this point. */
|
|
24
|
-
export declare function preflightGh(): void;
|
|
25
|
-
/** Resolves owner/repo for the current directory the same way `gh` does (git remotes + gh config). */
|
|
26
|
-
export declare function resolveRepoFromCwd(): string;
|
|
27
|
-
export declare function describeTarget(target: SecretTarget): string;
|
|
28
|
-
/** Argv for `gh secret set`; the value is deliberately absent (it goes on stdin). */
|
|
29
|
-
export declare function secretSetArgs(name: string, target: SecretTarget): string[];
|
|
30
|
-
/** Stores `value` as a GitHub Actions secret. Throws with gh's last stderr lines on failure. */
|
|
31
|
-
export declare function setGitHubSecret(name: string, target: SecretTarget, value: string): void;
|
package/dist/gh-secret.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from "node:child_process";
|
|
2
|
-
/**
|
|
3
|
-
* Thin wrapper over the GitHub CLI for storing a freshly minted endpoint key
|
|
4
|
-
* as an Actions secret. The plaintext only ever travels over `gh`'s stdin:
|
|
5
|
-
* `gh secret set` reads the value from stdin when `--body` is omitted, so the
|
|
6
|
-
* key never appears in argv, `ps`, shell history or our own output.
|
|
7
|
-
*/
|
|
8
|
-
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`";
|
|
9
|
-
/** GitHub Actions secret names: letters, digits, underscores; not starting with a digit or GITHUB_. */
|
|
10
|
-
export function validateSecretName(name) {
|
|
11
|
-
const trimmed = name.trim();
|
|
12
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed)) {
|
|
13
|
-
throw new Error(`--gh-secret "${name}" is not a valid secret name (letters, digits and underscores; cannot start with a digit)`);
|
|
14
|
-
}
|
|
15
|
-
if (/^GITHUB_/i.test(trimmed))
|
|
16
|
-
throw new Error(`--gh-secret "${name}" is reserved: secret names cannot start with GITHUB_`);
|
|
17
|
-
return trimmed;
|
|
18
|
-
}
|
|
19
|
-
export function validateRepo(repo) {
|
|
20
|
-
const trimmed = repo.trim();
|
|
21
|
-
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(trimmed)) {
|
|
22
|
-
throw new Error(`--repo must be owner/repo, got "${repo}"`);
|
|
23
|
-
}
|
|
24
|
-
return trimmed;
|
|
25
|
-
}
|
|
26
|
-
function gh(args, input) {
|
|
27
|
-
const res = spawnSync("gh", args, {
|
|
28
|
-
encoding: "utf8",
|
|
29
|
-
input,
|
|
30
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
31
|
-
env: { ...process.env, GH_NO_UPDATE_NOTIFIER: "1", GH_PROMPT_DISABLED: "1" },
|
|
32
|
-
});
|
|
33
|
-
const missing = res.error !== undefined && res.error.code === "ENOENT";
|
|
34
|
-
return { status: res.status, stdout: res.stdout ?? "", stderr: res.stderr ?? "", missing };
|
|
35
|
-
}
|
|
36
|
-
function trimmedStderr(res) {
|
|
37
|
-
return (res.stderr || res.stdout).trim().split("\n").slice(-3).join(" ").slice(0, 300);
|
|
38
|
-
}
|
|
39
|
-
/** Fails fast when `gh` is missing or not signed in; nothing has been minted at this point. */
|
|
40
|
-
export function preflightGh() {
|
|
41
|
-
const version = gh(["--version"]);
|
|
42
|
-
if (version.missing || version.status !== 0) {
|
|
43
|
-
throw new Error(`--gh-secret needs the GitHub CLI (gh) on PATH; ${GH_INSTALL_HINT}`);
|
|
44
|
-
}
|
|
45
|
-
const auth = gh(["auth", "status"]);
|
|
46
|
-
if (auth.status !== 0) {
|
|
47
|
-
throw new Error(`gh is not signed in (\`gh auth status\` failed${trimmedStderr(auth) ? `: ${trimmedStderr(auth)}` : ""}). Run \`gh auth login\` first.`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
/** Resolves owner/repo for the current directory the same way `gh` does (git remotes + gh config). */
|
|
51
|
-
export function resolveRepoFromCwd() {
|
|
52
|
-
const res = gh(["repo", "view", "--json", "nameWithOwner", "-q", ".nameWithOwner"]);
|
|
53
|
-
const repo = res.stdout.trim();
|
|
54
|
-
if (res.status !== 0 || !repo) {
|
|
55
|
-
throw new Error(`could not determine the GitHub repository from the current directory${trimmedStderr(res) ? ` (${trimmedStderr(res)})` : ""}. Pass --repo owner/repo, or run from inside a clone with a GitHub remote.`);
|
|
56
|
-
}
|
|
57
|
-
return repo;
|
|
58
|
-
}
|
|
59
|
-
export function describeTarget(target) {
|
|
60
|
-
switch (target.kind) {
|
|
61
|
-
case "repo":
|
|
62
|
-
return `${target.repo} (repository secret)`;
|
|
63
|
-
case "env":
|
|
64
|
-
return `${target.repo}, environment ${target.env}`;
|
|
65
|
-
case "org":
|
|
66
|
-
return `organization ${target.org}`;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/** Argv for `gh secret set`; the value is deliberately absent (it goes on stdin). */
|
|
70
|
-
export function secretSetArgs(name, target) {
|
|
71
|
-
const args = ["secret", "set", name];
|
|
72
|
-
switch (target.kind) {
|
|
73
|
-
case "repo":
|
|
74
|
-
args.push("--repo", target.repo);
|
|
75
|
-
break;
|
|
76
|
-
case "env":
|
|
77
|
-
args.push("--repo", target.repo, "--env", target.env);
|
|
78
|
-
break;
|
|
79
|
-
case "org":
|
|
80
|
-
args.push("--org", target.org);
|
|
81
|
-
break;
|
|
82
|
-
}
|
|
83
|
-
return args;
|
|
84
|
-
}
|
|
85
|
-
/** Stores `value` as a GitHub Actions secret. Throws with gh's last stderr lines on failure. */
|
|
86
|
-
export function setGitHubSecret(name, target, value) {
|
|
87
|
-
const res = gh(secretSetArgs(name, target), value);
|
|
88
|
-
if (res.missing)
|
|
89
|
-
throw new Error(`gh disappeared from PATH while setting the secret; ${GH_INSTALL_HINT}`);
|
|
90
|
-
if (res.status !== 0) {
|
|
91
|
-
throw new Error(`gh secret set ${name} failed${trimmedStderr(res) ? `: ${trimmedStderr(res)}` : ` (exit ${res.status})`}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=gh-secret.js.map
|
package/dist/gh-secret.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"gh-secret.js","sourceRoot":"","sources":["../src/gh-secret.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,eAAe,GAC1B,4HAA4H,CAAC;AAK/H,uGAAuG;AACvG,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,2FAA2F,CAAC,CAAC;IACnI,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,uDAAuD,CAAC,CAAC;IAC5H,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,mCAAmC,IAAI,GAAG,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AASD,SAAS,EAAE,CAAC,IAAc,EAAE,KAAc;IACxC,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE;QAChC,QAAQ,EAAE,MAAM;QAChB,KAAK;QACL,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,qBAAqB,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE;KAC7E,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,SAAS,aAAa,CAAC,GAAa;IAClC,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,+FAA+F;AAC/F,MAAM,UAAU,WAAW;IACzB,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAClC,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,kDAAkD,eAAe,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iDAAiD,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iCAAiC,CAAC,CAAC;IAC3J,CAAC;AACH,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,uEAAuE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,4EAA4E,CACxM,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM;YACT,OAAO,GAAG,MAAM,CAAC,IAAI,sBAAsB,CAAC;QAC9C,KAAK,KAAK;YACR,OAAO,GAAG,MAAM,CAAC,IAAI,iBAAiB,MAAM,CAAC,GAAG,EAAE,CAAC;QACrD,KAAK,KAAK;YACR,OAAO,gBAAgB,MAAM,CAAC,GAAG,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAoB;IAC9D,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACrC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM;YACT,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM;QACR,KAAK,KAAK;YACR,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YACtD,MAAM;QACR,KAAK,KAAK;YACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM;IACV,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,MAAoB,EAAE,KAAa;IAC/E,MAAM,GAAG,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;IACnD,IAAI,GAAG,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,eAAe,EAAE,CAAC,CAAC;IAC1G,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,UAAU,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC7H,CAAC;AACH,CAAC"}
|