@mp-lb/arcnet 0.1.0 → 0.2.1
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 +37 -4
- package/dist/createCli.d.ts.map +1 -1
- package/dist/createCli.js +14 -5
- package/dist/createCli.js.map +1 -1
- package/dist/secrets/assertNewSource.d.ts +3 -0
- package/dist/secrets/assertNewSource.d.ts.map +1 -0
- package/dist/secrets/assertNewSource.js +32 -0
- package/dist/secrets/assertNewSource.js.map +1 -0
- package/dist/secrets/config.d.ts +37 -0
- package/dist/secrets/config.d.ts.map +1 -0
- package/dist/secrets/config.js +67 -0
- package/dist/secrets/config.js.map +1 -0
- package/dist/secrets/createSecretsCommands.d.ts +3 -0
- package/dist/secrets/createSecretsCommands.d.ts.map +1 -0
- package/dist/secrets/createSecretsCommands.js +100 -0
- package/dist/secrets/createSecretsCommands.js.map +1 -0
- package/dist/secrets/loadSecrets.d.ts +3 -0
- package/dist/secrets/loadSecrets.d.ts.map +1 -0
- package/dist/secrets/loadSecrets.js +53 -0
- package/dist/secrets/loadSecrets.js.map +1 -0
- package/dist/secrets/promptPassword.d.ts +2 -0
- package/dist/secrets/promptPassword.d.ts.map +1 -0
- package/dist/secrets/promptPassword.js +42 -0
- package/dist/secrets/promptPassword.js.map +1 -0
- package/dist/secrets/provisionSource.d.ts +25 -0
- package/dist/secrets/provisionSource.d.ts.map +1 -0
- package/dist/secrets/provisionSource.js +141 -0
- package/dist/secrets/provisionSource.js.map +1 -0
- package/dist/secrets/readRemoteSource.d.ts +7 -0
- package/dist/secrets/readRemoteSource.d.ts.map +1 -0
- package/dist/secrets/readRemoteSource.js +32 -0
- package/dist/secrets/readRemoteSource.js.map +1 -0
- package/dist/secrets/runWithSecrets.d.ts +6 -0
- package/dist/secrets/runWithSecrets.d.ts.map +1 -0
- package/dist/secrets/runWithSecrets.js +59 -0
- package/dist/secrets/runWithSecrets.js.map +1 -0
- package/dist/secrets/secretCommand.d.ts +2 -0
- package/dist/secrets/secretCommand.d.ts.map +1 -0
- package/dist/secrets/secretCommand.js +17 -0
- package/dist/secrets/secretCommand.js.map +1 -0
- package/dist/secrets/selectSecrets.d.ts +3 -0
- package/dist/secrets/selectSecrets.d.ts.map +1 -0
- package/dist/secrets/selectSecrets.js +18 -0
- package/dist/secrets/selectSecrets.js.map +1 -0
- package/dist/secrets/syncSecrets.d.ts +10 -0
- package/dist/secrets/syncSecrets.d.ts.map +1 -0
- package/dist/secrets/syncSecrets.js +43 -0
- package/dist/secrets/syncSecrets.js.map +1 -0
- package/dist/secrets/wireSecretsWorkflows.d.ts +2 -0
- package/dist/secrets/wireSecretsWorkflows.d.ts.map +1 -0
- package/dist/secrets/wireSecretsWorkflows.js +48 -0
- package/dist/secrets/wireSecretsWorkflows.js.map +1 -0
- package/dist/secrets/withDeploymentSecrets.d.ts +2 -0
- package/dist/secrets/withDeploymentSecrets.d.ts.map +1 -0
- package/dist/secrets/withDeploymentSecrets.js +62 -0
- package/dist/secrets/withDeploymentSecrets.js.map +1 -0
- package/dist/secrets/writeSecretsWorkflow.d.ts +3 -0
- package/dist/secrets/writeSecretsWorkflow.d.ts.map +1 -0
- package/dist/secrets/writeSecretsWorkflow.js +60 -0
- package/dist/secrets/writeSecretsWorkflow.js.map +1 -0
- package/docs/public/commands.md +85 -0
- package/docs/public/llms-full.txt +122 -4
- package/package.json +2 -1
- package/src/createCli.ts +29 -8
- package/src/secrets/assertNewSource.ts +40 -0
- package/src/secrets/config.ts +91 -0
- package/src/secrets/createSecretsCommands.ts +206 -0
- package/src/secrets/loadSecrets.ts +69 -0
- package/src/secrets/promptPassword.ts +46 -0
- package/src/secrets/provisionSource.ts +238 -0
- package/src/secrets/readRemoteSource.ts +73 -0
- package/src/secrets/runWithSecrets.ts +71 -0
- package/src/secrets/secretCommand.ts +26 -0
- package/src/secrets/selectSecrets.ts +33 -0
- package/src/secrets/syncSecrets.ts +60 -0
- package/src/secrets/wireSecretsWorkflows.ts +57 -0
- package/src/secrets/withDeploymentSecrets.ts +83 -0
- package/src/secrets/writeSecretsWorkflow.ts +83 -0
package/README.md
CHANGED
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
ArcNet's TypeScript CLI for installing deployment configuration and deploying projects. The package owns shared runners, validation, workflow templates and the Vercel Terraform module; projects keep configuration and application-specific Dockerfiles.
|
|
4
4
|
|
|
5
|
-
**Release status:** implementation and checks are complete; the first npm publication is blocked by registry authentication. The commands below target the pending `0.1.0` release.
|
|
6
|
-
|
|
7
5
|
From an existing project with Zap, GitHub, and pinned pnpm:
|
|
8
6
|
|
|
9
7
|
```sh
|
|
10
|
-
pnpm dlx @mp-lb/arcnet@0.
|
|
11
|
-
pnpm dlx @mp-lb/arcnet@0.
|
|
8
|
+
pnpm dlx @mp-lb/arcnet@0.2.0 setup hello-world --dry-run
|
|
9
|
+
pnpm dlx @mp-lb/arcnet@0.2.0 setup hello-world
|
|
12
10
|
pnpm install
|
|
13
11
|
pnpm exec arcnet check
|
|
14
12
|
```
|
|
@@ -18,3 +16,38 @@ Setup pins this package in the existing root manifest. Commit the resulting lock
|
|
|
18
16
|
[Project setup](https://github.com/mp-lb/stackforge/blob/main/arcnet/SETUP.md) · [Environment setup](https://github.com/mp-lb/stackforge/blob/main/arcnet/environment/setup.md) · [Audit](https://github.com/mp-lb/stackforge/blob/main/arcnet/AUDIT.md) · [Command reference](docs/public/commands.md)
|
|
19
17
|
|
|
20
18
|
Zap Arc remains the pinned Terraform engine dependency. Environment bootstrap, health checks and teardown are not implemented by this package yet. The static Vercel adapter retains its existing static-only and explicit-project-reference limitations.
|
|
19
|
+
|
|
20
|
+
## Layered secrets
|
|
21
|
+
|
|
22
|
+
`arcnet secrets add` attaches an existing Forum encrypted JSON file. `arcnet secrets init` creates one. Both register a file-specific decryption key in the selected GitHub repository, save an encrypted snapshot, and generate a validation workflow. Setup prompts for your Forum encryption password locally; it never prints the password or recipient key. Use `--existing-key` when the GitHub secret already exists. The local `fm` and `gh` CLIs must be authenticated; the selected Forum parent directory must exist.
|
|
23
|
+
|
|
24
|
+
Use `/projects/<project-slug>/secrets.json.enc` for project files in the company Forum store.
|
|
25
|
+
|
|
26
|
+
The project keeps only `.arcnet/secrets.json`, encrypted snapshots under `.arcnet/secrets/`, and workflow references. Sources merge left to right, with later values winning. Each source names its own key environment variable. JSON must be an object; unused structured values are allowed, while selected environment values must be nonempty strings. Consumer mappings select and rename fields; an array of source names accepts aliases only when their values agree.
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"version": 1,
|
|
31
|
+
"repository": "example/hello-world",
|
|
32
|
+
"sources": [
|
|
33
|
+
{ "name": "standard", "store": "example/company", "path": "/admin/standard.json.enc", "keyEnv": "STANDARD_SECRETS_KEY" },
|
|
34
|
+
{ "name": "project", "store": "example/company", "path": "/projects/hello-world/secrets.json.enc", "keyEnv": "PROJECT_SECRETS_KEY" }
|
|
35
|
+
],
|
|
36
|
+
"consumers": {
|
|
37
|
+
"publish": { "NODE_AUTH_TOKEN": ["NPM_TOKEN", "NODE_AUTH_TOKEN"] },
|
|
38
|
+
"deploy": { "VERCEL_TOKEN": "VERCEL_API_TOKEN" }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`secrets sync` fetches ciphertext and adds snapshot identity, revision and checksum to this configuration. Commit config and ciphertext together. CI uses the reviewed snapshots and needs only each file's decryption key, not a Forum login. Sync after editing or rotating a source; obsolete snapshots can be removed after checking that no configuration references them. Setup/sync also wire source-key references into workflow steps that call ArcNet's env or deployment commands.
|
|
44
|
+
|
|
45
|
+
For live loading, omit a snapshot or select `--live`: the installed `fm` CLI fetches each source using its local login or the source's optional `tokenEnv` access credential. A decryption recipient is **not** a Forum read token. Live CI therefore needs an installed, authenticated `fm` as well as the independent decryption keys. Generated CI intentionally uses snapshots.
|
|
46
|
+
|
|
47
|
+
`arcnet env check` reports source names and selected key names, never values. `arcnet env export` explicitly emits selected plaintext JSON. `arcnet env run` gives a subprocess only the selected values and a small execution environment; it removes file keys, isolates temporary HOME/cache paths, and withholds subprocess output. Keep npm publishing mappings scoped to publishing credentials. The command reference documents the exact options.
|
|
48
|
+
|
|
49
|
+
For the first local Terraform plan and deploy, GitHub's file keys cannot be read back. Run `arcnet plan --password` or `arcnet deploy --password` in your terminal: ArcNet prompts once for your Forum encryption password and decrypts the reviewed snapshots locally. `arcnet env check --password` validates them the same way. CI still uses the independent file keys and rejects password mode.
|
|
50
|
+
|
|
51
|
+
When `.arcnet/secrets.json` exists, deployment commands automatically load it. The `deploy` consumer selects operator credentials; Terraform application values are selected using the existing service env lists in `zap.yaml`. No duplicated application map is required. Offline project checks remain offline. Secrets commands in GitHub Actions require the configured repository's main branch.
|
|
52
|
+
|
|
53
|
+
Provisioning modifies Forum and GitHub separately. A failed GitHub upload leaves an unused Forum recipient; rerun `secrets add` to create/upload another and remove the unused recipient later. If upload succeeded but snapshot/config writing failed, attach the file with `--existing-key`. Existing sources are not silently rotated on reruns. Provision while nobody else is editing that file: the current fm write interface does not offer atomic revision-conditional writes, though ArcNet checks identity/revision before updating and refuses occupied init paths. GitHub secret names are repository-scoped; environment-level overrides take precedence in jobs that use an environment.
|
package/dist/createCli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createCli.d.ts","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"createCli.d.ts","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,eAAO,MAAM,SAAS,eA4HrB,CAAC"}
|
package/dist/createCli.js
CHANGED
|
@@ -9,6 +9,8 @@ import { renderResult } from "./renderResult.js";
|
|
|
9
9
|
import { runTerraform } from "./runTerraform.js";
|
|
10
10
|
import { runVercel } from "./runVercel.js";
|
|
11
11
|
import { setup } from "./setup.js";
|
|
12
|
+
import { createSecretsCommands } from "./secrets/createSecretsCommands.js";
|
|
13
|
+
import { withDeploymentSecrets } from "./secrets/withDeploymentSecrets.js";
|
|
12
14
|
export const createCli = () => {
|
|
13
15
|
const cli = new Command("arcnet")
|
|
14
16
|
.description("Install and deploy ArcNet projects.")
|
|
@@ -24,6 +26,7 @@ export const createCli = () => {
|
|
|
24
26
|
const output = (result) => {
|
|
25
27
|
process.stdout.write(renderResult(result, cli.opts()) + "\n");
|
|
26
28
|
};
|
|
29
|
+
createSecretsCommands(cli, output);
|
|
27
30
|
cli
|
|
28
31
|
.command("version")
|
|
29
32
|
.description("Show the installed package version.")
|
|
@@ -50,6 +53,8 @@ export const createCli = () => {
|
|
|
50
53
|
create: "Create one explicitly approved Vercel project.",
|
|
51
54
|
})) {
|
|
52
55
|
const command = cli.command(name).description(description);
|
|
56
|
+
if (name === "plan" || name === "deploy")
|
|
57
|
+
command.option("--password", "Prompt for the Forum encryption password locally instead of using file keys");
|
|
53
58
|
if (name === "create")
|
|
54
59
|
command.argument("<site>", "Configured site name");
|
|
55
60
|
command.action(async (site) => {
|
|
@@ -58,12 +63,16 @@ export const createCli = () => {
|
|
|
58
63
|
.object({ mode: z.string().optional() })
|
|
59
64
|
.parse(JSON.parse(readFileSync(join(root, ".arcnet/project.json"), "utf8"))).mode;
|
|
60
65
|
const machine = Boolean(cli.opts().json || cli.opts().jsonl);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
const execute = async () => {
|
|
67
|
+
if (mode === "vercel")
|
|
68
|
+
return runVercel(name, root, typeof site === "string" ? site : undefined, machine);
|
|
69
|
+
if (name === "check" || name === "plan" || name === "deploy")
|
|
70
|
+
return runTerraform(name, root, machine);
|
|
66
71
|
throw new Error(`${name} is only supported for static Vercel references.`);
|
|
72
|
+
};
|
|
73
|
+
output(await (name === "check" || (name === "plan" && mode === "vercel")
|
|
74
|
+
? execute()
|
|
75
|
+
: withDeploymentSecrets(root, mode, execute, Boolean(command.opts().password), Boolean(cli.opts().noninteractive))));
|
|
67
76
|
});
|
|
68
77
|
}
|
|
69
78
|
cli
|
package/dist/createCli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createCli.js","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"createCli.js","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertNewSource.d.ts","sourceRoot":"","sources":["../../src/secrets/assertNewSource.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,eAAO,MAAM,eAAe,GAAI,QAAQ,YAAY,EAAE,MAAM,MAAM,SAkCjE,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { posix } from "node:path";
|
|
2
|
+
import { secretCommand } from "./secretCommand.js";
|
|
3
|
+
// fm's write API can overwrite without --force, so its default is not create-only.
|
|
4
|
+
export const assertNewSource = (source, root) => {
|
|
5
|
+
const listing = secretCommand("fm", [
|
|
6
|
+
"file",
|
|
7
|
+
"ls",
|
|
8
|
+
posix.dirname(source.path),
|
|
9
|
+
"--store",
|
|
10
|
+
source.store,
|
|
11
|
+
"--json",
|
|
12
|
+
], root);
|
|
13
|
+
let names;
|
|
14
|
+
try {
|
|
15
|
+
names = listing
|
|
16
|
+
.trim()
|
|
17
|
+
.split("\n")
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.map((line) => {
|
|
20
|
+
const entry = JSON.parse(line);
|
|
21
|
+
if (typeof entry.message !== "string")
|
|
22
|
+
throw new Error();
|
|
23
|
+
return entry.message;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error("Cannot verify that the new Forum path is unused.");
|
|
28
|
+
}
|
|
29
|
+
if (names.includes(posix.basename(source.path)))
|
|
30
|
+
throw new Error("Forum file already exists; use secrets add to attach it without replacing its contents.");
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=assertNewSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertNewSource.js","sourceRoot":"","sources":["../../src/secrets/assertNewSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,mFAAmF;AACnF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAoB,EAAE,IAAY,EAAE,EAAE;IACpE,MAAM,OAAO,GAAG,aAAa,CAC3B,IAAI,EACJ;QACE,MAAM;QACN,IAAI;QACJ,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;QAC1B,SAAS;QACT,MAAM,CAAC,KAAK;QACZ,QAAQ;KACT,EACD,IAAI,CACL,CAAC;IAEF,IAAI,KAAe,CAAC;IAEpB,IAAI,CAAC;QACH,KAAK,GAAG,OAAO;aACZ,IAAI,EAAE;aACN,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA0B,CAAC;YACxD,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,CAAC,CAAC,CAAC;IACP,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const envName: z.ZodString;
|
|
3
|
+
export declare const sourceSchema: z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
store: z.ZodString;
|
|
6
|
+
path: z.ZodString;
|
|
7
|
+
keyEnv: z.ZodString;
|
|
8
|
+
tokenEnv: z.ZodOptional<z.ZodString>;
|
|
9
|
+
snapshot: z.ZodOptional<z.ZodObject<{
|
|
10
|
+
file: z.ZodString;
|
|
11
|
+
fileId: z.ZodString;
|
|
12
|
+
revision: z.ZodNumber;
|
|
13
|
+
sha256: z.ZodString;
|
|
14
|
+
}, z.core.$strict>>;
|
|
15
|
+
}, z.core.$strict>;
|
|
16
|
+
export declare const secretsConfigSchema: z.ZodObject<{
|
|
17
|
+
version: z.ZodLiteral<1>;
|
|
18
|
+
repository: z.ZodString;
|
|
19
|
+
sources: z.ZodArray<z.ZodObject<{
|
|
20
|
+
name: z.ZodString;
|
|
21
|
+
store: z.ZodString;
|
|
22
|
+
path: z.ZodString;
|
|
23
|
+
keyEnv: z.ZodString;
|
|
24
|
+
tokenEnv: z.ZodOptional<z.ZodString>;
|
|
25
|
+
snapshot: z.ZodOptional<z.ZodObject<{
|
|
26
|
+
file: z.ZodString;
|
|
27
|
+
fileId: z.ZodString;
|
|
28
|
+
revision: z.ZodNumber;
|
|
29
|
+
sha256: z.ZodString;
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
|
+
}, z.core.$strict>>;
|
|
32
|
+
consumers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>>;
|
|
33
|
+
}, z.core.$strict>;
|
|
34
|
+
export type SecretsConfig = z.infer<typeof secretsConfigSchema>;
|
|
35
|
+
export type SecretSource = z.infer<typeof sourceSchema>;
|
|
36
|
+
export declare const readSecretsConfig: (root: string, file?: string) => SecretsConfig;
|
|
37
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/secrets/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,OAAO,aAAyC,CAAC;AAC9D,eAAO,MAAM,YAAY;;;;;;;;;;;;kBA4Bd,CAAC;AACZ,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;kBAuC5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,eAAO,MAAM,iBAAiB,GAC5B,MAAM,MAAM,EACZ,aAA6B,KAC5B,aAUF,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { safeTargetPath } from "../safeTargetPath.js";
|
|
4
|
+
export const envName = z.string().regex(/^[A-Z_][A-Z0-9_]*$/);
|
|
5
|
+
export const sourceSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
name: z.string().regex(/^[a-z][a-z0-9-]*$/),
|
|
8
|
+
store: z.string().regex(/^[\w-]+\/[\w-]+$/),
|
|
9
|
+
path: z
|
|
10
|
+
.string()
|
|
11
|
+
.startsWith("/")
|
|
12
|
+
.endsWith(".enc")
|
|
13
|
+
.refine((path) => !/[\r\n\0]/.test(path) &&
|
|
14
|
+
path
|
|
15
|
+
.split("/")
|
|
16
|
+
.slice(1)
|
|
17
|
+
.every((part) => part && part !== "." && part !== "..")),
|
|
18
|
+
keyEnv: envName,
|
|
19
|
+
tokenEnv: envName.optional(),
|
|
20
|
+
snapshot: z
|
|
21
|
+
.object({
|
|
22
|
+
file: z.string(),
|
|
23
|
+
fileId: z.string().min(1),
|
|
24
|
+
revision: z.number().int().nonnegative(),
|
|
25
|
+
sha256: z.string().regex(/^[a-f0-9]{64}$/),
|
|
26
|
+
})
|
|
27
|
+
.strict()
|
|
28
|
+
.optional(),
|
|
29
|
+
})
|
|
30
|
+
.strict();
|
|
31
|
+
export const secretsConfigSchema = z
|
|
32
|
+
.object({
|
|
33
|
+
version: z.literal(1),
|
|
34
|
+
repository: z.string().regex(/^[\w.-]+\/[\w.-]+$/),
|
|
35
|
+
sources: z.array(sourceSchema).min(1),
|
|
36
|
+
consumers: z
|
|
37
|
+
.record(z.string(), z.record(z.string().min(1), z.union([envName, z.array(envName).min(1)])))
|
|
38
|
+
.default({}),
|
|
39
|
+
})
|
|
40
|
+
.strict()
|
|
41
|
+
.superRefine((config, ctx) => {
|
|
42
|
+
if (new Set(config.sources.map((s) => s.name)).size !== config.sources.length)
|
|
43
|
+
ctx.addIssue({ code: "custom", message: "Source names must be unique." });
|
|
44
|
+
if (new Set(config.sources.map((s) => s.keyEnv)).size !==
|
|
45
|
+
config.sources.length)
|
|
46
|
+
ctx.addIssue({
|
|
47
|
+
code: "custom",
|
|
48
|
+
message: "Each source needs its own key environment name.",
|
|
49
|
+
});
|
|
50
|
+
for (const mapping of Object.values(config.consumers))
|
|
51
|
+
for (const name of Object.keys(mapping))
|
|
52
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name) &&
|
|
53
|
+
name !== "pnpm_config_//registry.npmjs.org/:_authToken")
|
|
54
|
+
ctx.addIssue({
|
|
55
|
+
code: "custom",
|
|
56
|
+
message: "Invalid output environment name.",
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
export const readSecretsConfig = (root, file = ".arcnet/secrets.json") => {
|
|
60
|
+
try {
|
|
61
|
+
return secretsConfigSchema.parse(JSON.parse(readFileSync(safeTargetPath(root, file), "utf8")));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw new Error("Missing or invalid secrets configuration (values omitted).");
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/secrets/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createSecretsCommands.d.ts","sourceRoot":"","sources":["../../src/secrets/createSecretsCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,qBAAqB,GAChC,KAAK,OAAO,EACZ,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,SAgMjC,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { realpathSync } from "node:fs";
|
|
2
|
+
import { readSecretsConfig } from "./config.js";
|
|
3
|
+
import { loadSecrets } from "./loadSecrets.js";
|
|
4
|
+
import { provisionSource } from "./provisionSource.js";
|
|
5
|
+
import { runWithSecrets } from "./runWithSecrets.js";
|
|
6
|
+
import { selectSecrets } from "./selectSecrets.js";
|
|
7
|
+
import { syncSecrets } from "./syncSecrets.js";
|
|
8
|
+
import { writeSecretsWorkflow } from "./writeSecretsWorkflow.js";
|
|
9
|
+
import { promptPassword } from "./promptPassword.js";
|
|
10
|
+
export const createSecretsCommands = (cli, output) => {
|
|
11
|
+
const env = cli
|
|
12
|
+
.command("env")
|
|
13
|
+
.description("Load ordered encrypted Forum sources and select environment values.");
|
|
14
|
+
for (const action of ["check", "export", "run"]) {
|
|
15
|
+
const command = env
|
|
16
|
+
.command(action)
|
|
17
|
+
.description({
|
|
18
|
+
check: "Validate decryption and mappings; report key names only.",
|
|
19
|
+
export: "Write selected plaintext JSON to stdout for an explicit pipeline.",
|
|
20
|
+
run: "Run a command with selected keys only; withhold child output.",
|
|
21
|
+
}[action])
|
|
22
|
+
.option("--config <file>", "Secrets source configuration", ".arcnet/secrets.json")
|
|
23
|
+
.option("--consumer <name>", "Named mapping in the secrets configuration")
|
|
24
|
+
.option("--live", "Fetch current ciphertext through the installed fm CLI instead of snapshots")
|
|
25
|
+
.option("--password", "Prompt for the Forum encryption password locally instead of using file keys");
|
|
26
|
+
if (action === "run")
|
|
27
|
+
command.argument("<command...>", "Executable and arguments after --");
|
|
28
|
+
command.action(async (...args) => {
|
|
29
|
+
const options = command.opts();
|
|
30
|
+
const root = realpathSync(cli.opts().root);
|
|
31
|
+
const config = readSecretsConfig(root, options.config);
|
|
32
|
+
if (process.env.GITHUB_ACTIONS === "true" &&
|
|
33
|
+
(process.env.GITHUB_REPOSITORY !== config.repository ||
|
|
34
|
+
process.env.GITHUB_REF !== "refs/heads/main"))
|
|
35
|
+
throw new Error("Secrets commands in CI require the configured repository main branch.");
|
|
36
|
+
if (options.password && process.env.GITHUB_ACTIONS === "true")
|
|
37
|
+
throw new Error("Password decryption is local-only; CI must use file keys.");
|
|
38
|
+
if (action !== "check" && !options.consumer)
|
|
39
|
+
throw new Error("Choose --consumer to explicitly select output keys.");
|
|
40
|
+
const password = options.password
|
|
41
|
+
? await promptPassword(Boolean(cli.opts().noninteractive))
|
|
42
|
+
: undefined;
|
|
43
|
+
const values = await loadSecrets(config, root, process.env, options.live, password);
|
|
44
|
+
const names = options.consumer
|
|
45
|
+
? [options.consumer]
|
|
46
|
+
: Object.keys(config.consumers);
|
|
47
|
+
const selected = Object.fromEntries(names.map((name) => [name, selectSecrets(values, config, name)]));
|
|
48
|
+
if (action === "export")
|
|
49
|
+
process.stdout.write(JSON.stringify(selected[options.consumer]) + "\n");
|
|
50
|
+
else if (action === "run")
|
|
51
|
+
output(runWithSecrets(args[0], selected[options.consumer], root));
|
|
52
|
+
else
|
|
53
|
+
output({
|
|
54
|
+
operation: "env.check",
|
|
55
|
+
status: "passed",
|
|
56
|
+
sources: config.sources.map((source) => source.name),
|
|
57
|
+
consumers: Object.fromEntries(Object.entries(selected).map(([name, value]) => [
|
|
58
|
+
name,
|
|
59
|
+
Object.keys(value),
|
|
60
|
+
])),
|
|
61
|
+
message: "Decryption, merge and required-key checks passed; provider authorization was not tested.",
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const secrets = cli
|
|
66
|
+
.command("secrets")
|
|
67
|
+
.description("Attach Forum files, provision GitHub keys and refresh encrypted snapshots.");
|
|
68
|
+
for (const mode of ["add", "init"]) {
|
|
69
|
+
const command = secrets
|
|
70
|
+
.command(mode)
|
|
71
|
+
.description(mode === "add"
|
|
72
|
+
? "Attach an existing Forum file and provision its CI key."
|
|
73
|
+
: "Create a Forum secrets file, prompt for your password and provision its CI key.")
|
|
74
|
+
.requiredOption("--name <name>", "Unique source name; sources merge in installation order")
|
|
75
|
+
.requiredOption("--store <workspace/store>", "Forum store")
|
|
76
|
+
.requiredOption("--path <path>", "Encrypted file path in Forum")
|
|
77
|
+
.requiredOption("--key-env <name>", "GitHub repository secret / environment variable for this file's key")
|
|
78
|
+
.requiredOption("--repository <owner/repo>", "GitHub repository receiving the key")
|
|
79
|
+
.option("--config <file>", "Secrets source configuration", ".arcnet/secrets.json");
|
|
80
|
+
if (mode === "add")
|
|
81
|
+
command.option("--existing-key", "Reuse an existing GitHub secret without creating a recipient");
|
|
82
|
+
else
|
|
83
|
+
command.option("--input <file>", "Initial plaintext JSON file; defaults to an empty object");
|
|
84
|
+
command.action(async () => output(await provisionSource(mode, {
|
|
85
|
+
...command.opts(),
|
|
86
|
+
noninteractive: cli.opts().noninteractive,
|
|
87
|
+
}, realpathSync(cli.opts().root), command.opts().config)));
|
|
88
|
+
}
|
|
89
|
+
secrets
|
|
90
|
+
.command("sync")
|
|
91
|
+
.description("Refresh encrypted snapshots from Forum and regenerate validation CI; no decryption.")
|
|
92
|
+
.option("--config <file>", "Secrets source configuration", ".arcnet/secrets.json")
|
|
93
|
+
.action((options) => {
|
|
94
|
+
const root = realpathSync(cli.opts().root);
|
|
95
|
+
const result = syncSecrets(readSecretsConfig(root, options.config), root, options.config);
|
|
96
|
+
writeSecretsWorkflow(readSecretsConfig(root, options.config), root, options.config);
|
|
97
|
+
output(result);
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=createSecretsCommands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createSecretsCommands.js","sourceRoot":"","sources":["../../src/secrets/createSecretsCommands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadSecrets.d.ts","sourceRoot":"","sources":["../../src/secrets/loadSecrets.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,eAAO,MAAM,WAAW,GACtB,QAAQ,aAAa,EACrB,MAAM,MAAM,EACZ,+BAAyB,EACzB,cAAY,EACZ,WAAW,MAAM,qCAqDlB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { decryptForumEncryptedFileText } from "@mp-lb/forum-secrets";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { safeTargetPath } from "../safeTargetPath.js";
|
|
7
|
+
import { readRemoteSource } from "./readRemoteSource.js";
|
|
8
|
+
import { secretCommand } from "./secretCommand.js";
|
|
9
|
+
export const loadSecrets = async (config, root, environment = process.env, live = false, password) => {
|
|
10
|
+
let values = {};
|
|
11
|
+
for (const source of config.sources) {
|
|
12
|
+
const key = environment[source.keyEnv];
|
|
13
|
+
if (!key && !password)
|
|
14
|
+
throw new Error(`Missing decryption credential: ${source.keyEnv}.`);
|
|
15
|
+
try {
|
|
16
|
+
const text = !live && source.snapshot
|
|
17
|
+
? readFileSync(safeTargetPath(root, source.snapshot.file), "utf8")
|
|
18
|
+
: readRemoteSource(source, root, environment).text;
|
|
19
|
+
if (!live &&
|
|
20
|
+
source.snapshot &&
|
|
21
|
+
createHash("sha256").update(text).digest("hex") !==
|
|
22
|
+
source.snapshot.sha256)
|
|
23
|
+
throw new Error("Snapshot integrity mismatch");
|
|
24
|
+
let plaintext;
|
|
25
|
+
if (password) {
|
|
26
|
+
const temporary = mkdtempSync(join(tmpdir(), "arcnet-decrypt-"));
|
|
27
|
+
try {
|
|
28
|
+
const file = join(temporary, "source.json.enc");
|
|
29
|
+
writeFileSync(file, text, { mode: 0o600 });
|
|
30
|
+
plaintext = secretCommand("fm", ["decrypt", "--file", file], root, undefined, { ...environment, DOCTRINE_ENCRYPTION_PASSWORD: password });
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
rmSync(temporary, { recursive: true, force: true });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
plaintext = await decryptForumEncryptedFileText({
|
|
38
|
+
encryptedText: text,
|
|
39
|
+
recipientSecret: key,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const decoded = JSON.parse(plaintext);
|
|
43
|
+
if (!decoded || Array.isArray(decoded) || typeof decoded !== "object")
|
|
44
|
+
throw new Error("Not an object");
|
|
45
|
+
values = { ...values, ...decoded };
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
throw new Error(`Source ${source.name} failed to load or decrypt; check its key and snapshot integrity (values omitted).`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return values;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=loadSecrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadSecrets.js","sourceRoot":"","sources":["../../src/secrets/loadSecrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,MAAqB,EACrB,IAAY,EACZ,WAAW,GAAG,OAAO,CAAC,GAAG,EACzB,IAAI,GAAG,KAAK,EACZ,QAAiB,EACjB,EAAE;IACF,IAAI,MAAM,GAA4B,EAAE,CAAC;IAEzC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ;YACnB,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAEtE,IAAI,CAAC;YACH,MAAM,IAAI,GACR,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ;gBACtB,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAClE,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC;YAEvD,IACE,CAAC,IAAI;gBACL,MAAM,CAAC,QAAQ;gBACf,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBAC7C,MAAM,CAAC,QAAQ,CAAC,MAAM;gBAExB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAEjD,IAAI,SAAiB,CAAC;YACtB,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBACjE,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;oBAChD,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC3C,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,IAAI,EAC/D,SAAS,EAAE,EAAE,GAAG,WAAW,EAAE,4BAA4B,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC3E,CAAC;wBAAS,CAAC;oBACT,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,SAAS,GAAG,MAAM,6BAA6B,CAAC;oBAC9C,aAAa,EAAE,IAAI;oBACnB,eAAe,EAAE,GAAI;iBACtB,CAAC,CAAC;YACL,CAAC;YACD,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAE/C,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,OAAO,KAAK,QAAQ;gBACnE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;YACnC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,UAAU,MAAM,CAAC,IAAI,oFAAoF,CAC1G,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptPassword.d.ts","sourceRoot":"","sources":["../../src/secrets/promptPassword.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,GACzB,wBAAsB,KACrB,OAAO,CAAC,MAAM,CA2ChB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const promptPassword = async (noninteractive = false) => {
|
|
2
|
+
if (process.env.DOCTRINE_ENCRYPTION_PASSWORD)
|
|
3
|
+
return process.env.DOCTRINE_ENCRYPTION_PASSWORD;
|
|
4
|
+
if (noninteractive || !process.stdin.isTTY || !process.stderr.isTTY)
|
|
5
|
+
throw new Error("Run this command in your terminal to enter the Forum encryption password, or set DOCTRINE_ENCRYPTION_PASSWORD.");
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
let value = "";
|
|
8
|
+
const input = process.stdin;
|
|
9
|
+
const wasRaw = input.isRaw;
|
|
10
|
+
const finish = (cancel = false) => {
|
|
11
|
+
input.off("data", read);
|
|
12
|
+
input.setRawMode(wasRaw);
|
|
13
|
+
input.pause();
|
|
14
|
+
process.stderr.write("\n");
|
|
15
|
+
if (cancel || !value)
|
|
16
|
+
reject(new Error("Password entry cancelled."));
|
|
17
|
+
else
|
|
18
|
+
resolve(value);
|
|
19
|
+
};
|
|
20
|
+
const read = (chunk) => {
|
|
21
|
+
for (const character of chunk.toString("utf8")) {
|
|
22
|
+
if (character === "\u0003") {
|
|
23
|
+
finish(true);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (character === "\r" || character === "\n") {
|
|
27
|
+
finish();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (character === "\u007f")
|
|
31
|
+
value = [...value].slice(0, -1).join("");
|
|
32
|
+
else
|
|
33
|
+
value += character;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
process.stderr.write("Forum encryption password: ");
|
|
37
|
+
input.setRawMode(true);
|
|
38
|
+
input.on("data", read);
|
|
39
|
+
input.resume();
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=promptPassword.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptPassword.js","sourceRoot":"","sources":["../../src/secrets/promptPassword.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,cAAc,GAAG,KAAK,EACL,EAAE;IACnB,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B;QAC1C,OAAO,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;IAClD,IAAI,cAAc,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QACjE,MAAM,IAAI,KAAK,CACb,gHAAgH,CACjH,CAAC;IACJ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;QAE3B,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,KAAK,EAAE,EAAE;YAChC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACxB,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACzB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,MAAM,IAAI,CAAC,KAAK;gBAAE,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;;gBAChE,OAAO,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC;QAEF,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE;YAC7B,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,CAAC,CAAC;oBACb,OAAO;gBACT,CAAC;gBAED,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;oBAC7C,MAAM,EAAE,CAAC;oBACT,OAAO;gBACT,CAAC;gBAED,IAAI,SAAS,KAAK,QAAQ;oBAAE,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;oBAChE,KAAK,IAAI,SAAS,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;QAEF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACpD,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACvB,KAAK,CAAC,MAAM,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ProvisionOptions {
|
|
2
|
+
name: string;
|
|
3
|
+
store: string;
|
|
4
|
+
path: string;
|
|
5
|
+
keyEnv: string;
|
|
6
|
+
repository: string;
|
|
7
|
+
existingKey?: boolean;
|
|
8
|
+
input?: string;
|
|
9
|
+
noninteractive?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const provisionSource: (mode: "add" | "init", options: ProvisionOptions, root: string, configFile: string) => Promise<{
|
|
12
|
+
operation: string;
|
|
13
|
+
status: string;
|
|
14
|
+
message: string;
|
|
15
|
+
} | {
|
|
16
|
+
operation: string;
|
|
17
|
+
githubSecret: string;
|
|
18
|
+
sources: {
|
|
19
|
+
name: string;
|
|
20
|
+
revision: number;
|
|
21
|
+
}[];
|
|
22
|
+
message: string;
|
|
23
|
+
status?: undefined;
|
|
24
|
+
}>;
|
|
25
|
+
//# sourceMappingURL=provisionSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisionSource.d.ts","sourceRoot":"","sources":["../../src/secrets/provisionSource.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,eAAe,GAC1B,MAAM,KAAK,GAAG,MAAM,EACpB,SAAS,gBAAgB,EACzB,MAAM,MAAM,EACZ,YAAY,MAAM;;;;;;;;;;;;;EAuMnB,CAAC"}
|