@secr/cli 0.1.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 +64 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +51 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +66 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/delete.d.ts +3 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +58 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/diff.d.ts +3 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +68 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/env.d.ts +3 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +59 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/guard.d.ts +3 -0
- package/dist/commands/guard.d.ts.map +1 -0
- package/dist/commands/guard.js +108 -0
- package/dist/commands/guard.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +107 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/link.d.ts +3 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +34 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/log.d.ts +3 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +42 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +101 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +10 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/ls.d.ts +3 -0
- package/dist/commands/ls.d.ts.map +1 -0
- package/dist/commands/ls.js +43 -0
- package/dist/commands/ls.js.map +1 -0
- package/dist/commands/org.d.ts +3 -0
- package/dist/commands/org.d.ts.map +1 -0
- package/dist/commands/org.js +67 -0
- package/dist/commands/org.js.map +1 -0
- package/dist/commands/promote.d.ts +3 -0
- package/dist/commands/promote.d.ts.map +1 -0
- package/dist/commands/promote.js +75 -0
- package/dist/commands/promote.js.map +1 -0
- package/dist/commands/pull.d.ts +3 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +48 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/rotate-key.d.ts +3 -0
- package/dist/commands/rotate-key.d.ts.map +1 -0
- package/dist/commands/rotate-key.js +39 -0
- package/dist/commands/rotate-key.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +47 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +83 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/set.d.ts +3 -0
- package/dist/commands/set.d.ts.map +1 -0
- package/dist/commands/set.js +54 -0
- package/dist/commands/set.js.map +1 -0
- package/dist/commands/template.d.ts +3 -0
- package/dist/commands/template.d.ts.map +1 -0
- package/dist/commands/template.js +109 -0
- package/dist/commands/template.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +32 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/completions/bash.sh +49 -0
- package/dist/completions/fish.fish +62 -0
- package/dist/completions/zsh.sh +106 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +94 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +185 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +18 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +81 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/scanner.d.ts +29 -0
- package/dist/lib/scanner.d.ts.map +1 -0
- package/dist/lib/scanner.js +211 -0
- package/dist/lib/scanner.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import readline from "node:readline";
|
|
5
|
+
import { apiGetMe, apiCreateProject } from "../lib/api.js";
|
|
6
|
+
import { saveProjectConfig, loadProjectConfig } from "../lib/config.js";
|
|
7
|
+
function prompt(question) {
|
|
8
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
rl.question(question, (answer) => {
|
|
11
|
+
rl.close();
|
|
12
|
+
resolve(answer.trim());
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function toSlug(name) {
|
|
17
|
+
return name
|
|
18
|
+
.toLowerCase()
|
|
19
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
20
|
+
.replace(/^-|-$/g, "");
|
|
21
|
+
}
|
|
22
|
+
export const initCommand = new Command("init")
|
|
23
|
+
.description("Create a new project and link this directory")
|
|
24
|
+
.action(async () => {
|
|
25
|
+
// Check if already linked
|
|
26
|
+
const existing = loadProjectConfig();
|
|
27
|
+
if (existing) {
|
|
28
|
+
const overwrite = await prompt(chalk.yellow(`This directory is already linked to ${existing.project}. Overwrite? (y/N) `));
|
|
29
|
+
if (overwrite.toLowerCase() !== "y") {
|
|
30
|
+
console.log(chalk.dim(" Cancelled."));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const spinner = ora("Checking authentication...").start();
|
|
35
|
+
let me;
|
|
36
|
+
try {
|
|
37
|
+
me = await apiGetMe();
|
|
38
|
+
spinner.stop();
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
spinner.fail(chalk.red(err.message));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
if (me.orgs.length === 0) {
|
|
45
|
+
console.error(chalk.red(" No organizations found. Create one first."));
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
// Select org
|
|
49
|
+
let org;
|
|
50
|
+
if (me.orgs.length === 1) {
|
|
51
|
+
org = me.orgs[0];
|
|
52
|
+
console.log(chalk.dim(` Organization: ${chalk.white(org.name)} (${org.slug})`));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.log("\n Select an organization:\n");
|
|
56
|
+
me.orgs.forEach((o, i) => {
|
|
57
|
+
console.log(chalk.dim(` ${chalk.white(i + 1)}. ${o.name} (${o.slug})`));
|
|
58
|
+
});
|
|
59
|
+
console.log();
|
|
60
|
+
const choice = await prompt(" Enter number: ");
|
|
61
|
+
const idx = parseInt(choice, 10) - 1;
|
|
62
|
+
if (isNaN(idx) || idx < 0 || idx >= me.orgs.length) {
|
|
63
|
+
console.error(chalk.red(" Invalid selection."));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
org = me.orgs[idx];
|
|
67
|
+
}
|
|
68
|
+
// Project name
|
|
69
|
+
const name = await prompt("\n Project name: ");
|
|
70
|
+
if (!name) {
|
|
71
|
+
console.error(chalk.red(" Project name is required."));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
const slug = toSlug(name);
|
|
75
|
+
if (!slug || slug.length < 2) {
|
|
76
|
+
console.error(chalk.red(" Could not generate a valid slug from that name. Try a different name."));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
console.log(chalk.dim(` Slug: ${chalk.white(slug)}`));
|
|
80
|
+
// Create project
|
|
81
|
+
const createSpinner = ora("Creating project...").start();
|
|
82
|
+
try {
|
|
83
|
+
await apiCreateProject(org.id, { name, slug });
|
|
84
|
+
createSpinner.succeed(chalk.green("Project created"));
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
createSpinner.fail(chalk.red(err.message));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
// Save config
|
|
91
|
+
saveProjectConfig({
|
|
92
|
+
project: slug,
|
|
93
|
+
defaultEnvironment: "development",
|
|
94
|
+
org: org.slug,
|
|
95
|
+
});
|
|
96
|
+
console.log();
|
|
97
|
+
console.log(chalk.green(" Linked to project"));
|
|
98
|
+
console.log();
|
|
99
|
+
console.log(chalk.dim(` Project: ${chalk.white(slug)}`));
|
|
100
|
+
console.log(chalk.dim(` Environment: ${chalk.white("development")}`));
|
|
101
|
+
console.log(chalk.dim(` Org: ${chalk.white(org.slug)}`));
|
|
102
|
+
console.log();
|
|
103
|
+
console.log(chalk.dim(` Created .secr.json — commit this file to your repo.`));
|
|
104
|
+
console.log(chalk.dim(` Run ${chalk.cyan("secr set KEY=value")} to add secrets or ${chalk.cyan('secr run "npm start"')} to start with secrets injected.`));
|
|
105
|
+
console.log();
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,WAAW,SA+BpB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { SecrConfigSchema } from "@secr/shared";
|
|
4
|
+
import { saveProjectConfig } from "../lib/config.js";
|
|
5
|
+
export const linkCommand = new Command("link")
|
|
6
|
+
.description("Link this directory to a secr project and environment")
|
|
7
|
+
.requiredOption("--project <slug>", "Project slug")
|
|
8
|
+
.option("--env <environment>", "Default environment", "development")
|
|
9
|
+
.requiredOption("--org <slug>", "Organization slug")
|
|
10
|
+
.action(async (opts) => {
|
|
11
|
+
const config = {
|
|
12
|
+
project: opts.project.toLowerCase(),
|
|
13
|
+
defaultEnvironment: opts.env.toLowerCase(),
|
|
14
|
+
org: opts.org.toLowerCase(),
|
|
15
|
+
};
|
|
16
|
+
const result = SecrConfigSchema.safeParse(config);
|
|
17
|
+
if (!result.success) {
|
|
18
|
+
const issue = result.error.issues[0];
|
|
19
|
+
console.error(chalk.red(`\n ${issue.path.join(".")}: ${issue.message}\n`));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
saveProjectConfig(result.data);
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(chalk.green(" Linked to project"));
|
|
25
|
+
console.log();
|
|
26
|
+
console.log(chalk.dim(` Project: ${chalk.white(result.data.project)}`));
|
|
27
|
+
console.log(chalk.dim(` Environment: ${chalk.white(result.data.defaultEnvironment)}`));
|
|
28
|
+
console.log(chalk.dim(` Org: ${chalk.white(result.data.org)}`));
|
|
29
|
+
console.log();
|
|
30
|
+
console.log(chalk.dim(` Created .secr.json — commit this file to your repo.`));
|
|
31
|
+
console.log(chalk.dim(` Run ${chalk.cyan("secr pull")} to fetch secrets or ${chalk.cyan('secr run "npm start"')} to start with secrets injected.`));
|
|
32
|
+
console.log();
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,uDAAuD,CAAC;KACpE,cAAc,CAAC,kBAAkB,EAAE,cAAc,CAAC;KAClD,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,EAAE,aAAa,CAAC;KACnE,cAAc,CAAC,cAAc,EAAE,mBAAmB,CAAC;KACnD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;QACnC,kBAAkB,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;QAC1C,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;KAC5B,CAAC;IAEF,MAAM,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAE/B,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,kCAAkC,CAAC,CAAC,CAAC;IACrJ,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,UAAU,SAuCnB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import { requireProjectConfig } from "../lib/config.js";
|
|
5
|
+
import { apiGetMe, apiGetAuditLog } from "../lib/api.js";
|
|
6
|
+
export const logCommand = new Command("log")
|
|
7
|
+
.description("Show recent audit log entries")
|
|
8
|
+
.option("-n, --limit <number>", "Number of entries", "20")
|
|
9
|
+
.action(async (opts) => {
|
|
10
|
+
const config = requireProjectConfig();
|
|
11
|
+
const spinner = ora(chalk.dim("Fetching audit log...")).start();
|
|
12
|
+
try {
|
|
13
|
+
// We need the orgId — get it from /auth/me
|
|
14
|
+
const me = await apiGetMe();
|
|
15
|
+
const org = me.orgs.find((o) => o.slug === config.org);
|
|
16
|
+
if (!org)
|
|
17
|
+
throw new Error(`Org "${config.org}" not found`);
|
|
18
|
+
const { entries } = await apiGetAuditLog(org.id, { limit: parseInt(opts.limit) });
|
|
19
|
+
spinner.stop();
|
|
20
|
+
console.log();
|
|
21
|
+
if (entries.length === 0) {
|
|
22
|
+
console.log(chalk.dim(" No audit log entries found."));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
for (const e of entries) {
|
|
26
|
+
const time = new Date(e.timestamp).toLocaleString();
|
|
27
|
+
const actor = e.actor.email || "system";
|
|
28
|
+
const actionColor = e.action.includes("create") ? chalk.green :
|
|
29
|
+
e.action.includes("update") ? chalk.yellow :
|
|
30
|
+
e.action.includes("delete") ? chalk.red :
|
|
31
|
+
chalk.dim;
|
|
32
|
+
console.log(` ${chalk.dim(time)} ${chalk.cyan(actor.padEnd(24))} ${actionColor(e.action.padEnd(18))} ${chalk.white(e.resourceLabel || "")}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
console.log();
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
spinner.fail(chalk.red(err.message));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,sBAAsB,EAAE,mBAAmB,EAAE,IAAI,CAAC;KACzD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IAEtC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;IAChE,IAAI,CAAC;QACH,2CAA2C;QAC3C,MAAM,EAAE,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;QAC5D,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC;QAE3D,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClF,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;gBACpD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC;gBACxC,MAAM,WAAW,GACf,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC3C,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;wBAC5C,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;4BACzC,KAAK,CAAC,GAAG,CAAC;gBAEZ,OAAO,CAAC,GAAG,CACT,KAAK,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,EAAE,CACpI,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,YAAY,SA6FrB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import open from "open";
|
|
5
|
+
import { createServer } from "node:http";
|
|
6
|
+
import { saveCredentials } from "../lib/config.js";
|
|
7
|
+
export const loginCommand = new Command("login")
|
|
8
|
+
.description("Authenticate with secr.dev")
|
|
9
|
+
.option("--token <token>", "Authenticate with a pre-generated token")
|
|
10
|
+
.action(async (opts) => {
|
|
11
|
+
if (opts.token) {
|
|
12
|
+
// Direct token auth (for CI or manual setup)
|
|
13
|
+
const spinner = ora("Verifying token...").start();
|
|
14
|
+
try {
|
|
15
|
+
// Verify token works by calling /auth/me
|
|
16
|
+
const res = await fetch(`${process.env.SECR_API_URL || "https://api.secr.dev"}/auth/me`, { headers: { Authorization: `Bearer ${opts.token}` } });
|
|
17
|
+
if (!res.ok)
|
|
18
|
+
throw new Error("Invalid token");
|
|
19
|
+
const user = await res.json();
|
|
20
|
+
saveCredentials({ token: opts.token, email: user.email });
|
|
21
|
+
spinner.succeed(chalk.green(`Authenticated as ${chalk.bold(user.email)}`));
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
spinner.fail(chalk.red(err.message || "Authentication failed"));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// Browser-based login flow
|
|
30
|
+
// 1. Start a local HTTP server to receive the callback
|
|
31
|
+
// 2. Open the browser to the dashboard login page
|
|
32
|
+
// 3. Dashboard redirects back with a token
|
|
33
|
+
const port = await findFreePort(9876);
|
|
34
|
+
const dashboardUrl = process.env.SECR_DASHBOARD_URL || "https://app.secr.dev";
|
|
35
|
+
console.log();
|
|
36
|
+
console.log(chalk.dim(" Opening browser to authenticate..."));
|
|
37
|
+
console.log();
|
|
38
|
+
const tokenPromise = new Promise((resolve, reject) => {
|
|
39
|
+
const timeout = setTimeout(() => {
|
|
40
|
+
server.close();
|
|
41
|
+
reject(new Error("Login timed out after 5 minutes"));
|
|
42
|
+
}, 5 * 60 * 1000);
|
|
43
|
+
const server = createServer((req, res) => {
|
|
44
|
+
const url = new URL(req.url, `http://localhost:${port}`);
|
|
45
|
+
const token = url.searchParams.get("token");
|
|
46
|
+
const email = url.searchParams.get("email");
|
|
47
|
+
if (token && email) {
|
|
48
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
49
|
+
res.end(`
|
|
50
|
+
<html>
|
|
51
|
+
<head><meta charset="utf-8"></head>
|
|
52
|
+
<body style="font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; background: #0a0a0f; color: #e2e8f0;">
|
|
53
|
+
<div style="text-align: center;">
|
|
54
|
+
<h1>✓ Authenticated</h1>
|
|
55
|
+
<p>You can close this window and return to your terminal.</p>
|
|
56
|
+
</div>
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
59
|
+
`);
|
|
60
|
+
clearTimeout(timeout);
|
|
61
|
+
server.close();
|
|
62
|
+
saveCredentials({ token, email });
|
|
63
|
+
resolve(email);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
res.writeHead(400);
|
|
67
|
+
res.end("Missing token or email");
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
server.listen(port, () => {
|
|
71
|
+
const loginUrl = `${dashboardUrl}/cli-auth?callback=http://localhost:${port}`;
|
|
72
|
+
open(loginUrl).catch(() => {
|
|
73
|
+
console.log(chalk.yellow(` Could not open browser. Visit this URL manually:`));
|
|
74
|
+
console.log(chalk.cyan(` ${loginUrl}`));
|
|
75
|
+
console.log();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
const spinner = ora("Waiting for browser authentication...").start();
|
|
80
|
+
try {
|
|
81
|
+
const email = await tokenPromise;
|
|
82
|
+
spinner.succeed(chalk.green(`Authenticated as ${chalk.bold(email)}`));
|
|
83
|
+
console.log();
|
|
84
|
+
console.log(chalk.dim(" Run `secr link` to connect a project, or `secr init` for guided setup."));
|
|
85
|
+
console.log();
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
spinner.fail(chalk.red(err.message));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
async function findFreePort(startPort) {
|
|
93
|
+
return new Promise((resolve) => {
|
|
94
|
+
const server = createServer();
|
|
95
|
+
server.listen(startPort, () => {
|
|
96
|
+
server.close(() => resolve(startPort));
|
|
97
|
+
});
|
|
98
|
+
server.on("error", () => resolve(findFreePort(startPort + 1)));
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,4BAA4B,CAAC;KACzC,MAAM,CAAC,iBAAiB,EAAE,yCAAyC,CAAC;KACpE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,6CAA6C;QAC7C,MAAM,OAAO,GAAG,GAAG,CAAC,oBAAoB,CAAC,CAAC,KAAK,EAAE,CAAC;QAClD,IAAI,CAAC;YACH,yCAAyC;YACzC,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,sBAAsB,UAAU,EAC/D,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,CACvD,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;YAC9C,MAAM,IAAI,GAAQ,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAEnC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1D,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO;IACT,CAAC;IAED,2BAA2B;IAC3B,uDAAuD;IACvD,kDAAkD;IAClD,2CAA2C;IAE3C,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,sBAAsB,CAAC;IAE9E,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,MAAM,YAAY,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3D,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;QACvD,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAElB,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAI,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;YAC1D,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAE5C,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;gBACnB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;gBACnE,GAAG,CAAC,GAAG,CAAC;;;;;;;;;;WAUP,CAAC,CAAC;gBACH,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;gBACf,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;gBAClC,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YACpC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACvB,MAAM,QAAQ,GAAG,GAAG,YAAY,uCAAuC,IAAI,EAAE,CAAC;YAC9E,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,oDAAoD,CAAC,CAAC,CAAC;gBAChF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC,CAAC;gBACzC,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,GAAG,CAAC,uCAAuC,CAAC,CAAC,KAAK,EAAE,CAAC;IAErE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC;QACjC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC,CAAC;QACnG,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,KAAK,UAAU,YAAY,CAAC,SAAiB;IAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAKtB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { clearCredentials } from "../lib/config.js";
|
|
4
|
+
export const logoutCommand = new Command("logout")
|
|
5
|
+
.description("Log out and clear local credentials")
|
|
6
|
+
.action(async () => {
|
|
7
|
+
clearCredentials();
|
|
8
|
+
console.log(chalk.green("\n Logged out. Credentials cleared.\n"));
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,gBAAgB,EAAE,CAAC;IACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,SAAS,SAwClB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import { requireProjectConfig } from "../lib/config.js";
|
|
5
|
+
import { apiListKeys } from "../lib/api.js";
|
|
6
|
+
export const lsCommand = new Command("ls")
|
|
7
|
+
.description("List secret keys (without values) for the linked environment")
|
|
8
|
+
.option("--env <environment>", "Override the default environment")
|
|
9
|
+
.option("--search <prefix>", "Filter keys by prefix")
|
|
10
|
+
.action(async (opts) => {
|
|
11
|
+
const config = requireProjectConfig();
|
|
12
|
+
const env = opts.env || config.defaultEnvironment;
|
|
13
|
+
const spinner = ora(chalk.dim("Fetching keys...")).start();
|
|
14
|
+
try {
|
|
15
|
+
const { keys } = await apiListKeys(config.org, config.project, env, {
|
|
16
|
+
search: opts.search,
|
|
17
|
+
});
|
|
18
|
+
spinner.stop();
|
|
19
|
+
const label = opts.search
|
|
20
|
+
? `${keys.length} keys matching "${opts.search}"`
|
|
21
|
+
: `${keys.length} secrets`;
|
|
22
|
+
console.log();
|
|
23
|
+
console.log(chalk.dim(` ${config.project}/${env} — ${label}`));
|
|
24
|
+
console.log();
|
|
25
|
+
if (keys.length === 0) {
|
|
26
|
+
console.log(chalk.dim(opts.search
|
|
27
|
+
? ` No keys matching "${opts.search}".`
|
|
28
|
+
: " No secrets yet. Use `secr set KEY=value` to add one."));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const maxKeyLen = Math.max(...keys.map((k) => k.key.length));
|
|
32
|
+
for (const k of keys) {
|
|
33
|
+
console.log(` ${chalk.white(k.key.padEnd(maxKeyLen + 2))}${chalk.dim(`v${k.version}`)}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
console.log();
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
spinner.fail(chalk.red(err.message));
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=ls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ls.js","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;KACvC,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,qBAAqB,EAAE,kCAAkC,CAAC;KACjE,MAAM,CAAC,mBAAmB,EAAE,uBAAuB,CAAC;KACpD,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,kBAAkB,CAAC;IAElD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE;YAClE,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM;YACvB,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,mBAAmB,IAAI,CAAC,MAAM,GAAG;YACjD,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,UAAU,CAAC;QAE7B,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,IAAI,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,EAAE,CAAC;QAEd,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM;gBAC/B,CAAC,CAAC,uBAAuB,IAAI,CAAC,MAAM,IAAI;gBACxC,CAAC,CAAC,wDAAwD,CAAC,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7D,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,CACT,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAC7E,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org.d.ts","sourceRoot":"","sources":["../../src/commands/org.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyEpC,eAAO,MAAM,UAAU,SAGQ,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import readline from "node:readline";
|
|
5
|
+
import { resolveOrgId, apiCreateOrg, apiDeleteOrg } from "../lib/api.js";
|
|
6
|
+
function prompt(question) {
|
|
7
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
rl.question(question, (answer) => {
|
|
10
|
+
rl.close();
|
|
11
|
+
resolve(answer.trim());
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const deleteOrgCommand = new Command("delete")
|
|
16
|
+
.description("Permanently delete an organization and all its data")
|
|
17
|
+
.argument("<org-slug>", "Organization slug to delete")
|
|
18
|
+
.option("--force", "Skip confirmation prompt")
|
|
19
|
+
.action(async (orgSlug, opts) => {
|
|
20
|
+
if (!opts.force) {
|
|
21
|
+
console.log(chalk.red.bold("\n WARNING: ") +
|
|
22
|
+
chalk.red(`This will permanently delete org '${orgSlug}', all its projects, secrets, and members.\n`));
|
|
23
|
+
const answer = await prompt(chalk.yellow(` Type the org slug to confirm: `));
|
|
24
|
+
if (answer !== orgSlug) {
|
|
25
|
+
console.log(chalk.dim(" Cancelled."));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const spinner = ora(`Resolving organization...`).start();
|
|
30
|
+
try {
|
|
31
|
+
const orgId = await resolveOrgId(orgSlug);
|
|
32
|
+
spinner.text = `Deleting organization ${chalk.cyan(orgSlug)}...`;
|
|
33
|
+
const result = await apiDeleteOrg(orgId);
|
|
34
|
+
spinner.succeed(chalk.green(`Organization ${chalk.bold(result.slug)} deleted permanently`));
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
spinner.fail(chalk.red(err.message));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const createOrgCommand = new Command("create")
|
|
42
|
+
.description("Create a new organization")
|
|
43
|
+
.argument("<name>", "Organization name")
|
|
44
|
+
.option("-s, --slug <slug>", "Organization slug (auto-generated from name if not provided)")
|
|
45
|
+
.action(async (name, opts) => {
|
|
46
|
+
const slug = opts.slug ||
|
|
47
|
+
name
|
|
48
|
+
.toLowerCase()
|
|
49
|
+
.replace(/[^a-z0-9-]/g, "-")
|
|
50
|
+
.replace(/-+/g, "-")
|
|
51
|
+
.replace(/^-|-$/g, "");
|
|
52
|
+
const spinner = ora("Creating organization...").start();
|
|
53
|
+
try {
|
|
54
|
+
const org = await apiCreateOrg({ name, slug });
|
|
55
|
+
spinner.succeed(chalk.green(`Organization ${chalk.bold(org.name)} created`) +
|
|
56
|
+
chalk.dim(` (${org.slug})`));
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
spinner.fail(chalk.red(err.message));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
export const orgCommand = new Command("org")
|
|
64
|
+
.description("Manage organizations")
|
|
65
|
+
.addCommand(createOrgCommand)
|
|
66
|
+
.addCommand(deleteOrgCommand);
|
|
67
|
+
//# sourceMappingURL=org.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org.js","sourceRoot":"","sources":["../../src/commands/org.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote.d.ts","sourceRoot":"","sources":["../../src/commands/promote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,cAAc,SAiFvB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import ora from "ora";
|
|
4
|
+
import { requireProjectConfig } from "../lib/config.js";
|
|
5
|
+
import { apiPromoteSecrets, apiPullSecrets } from "../lib/api.js";
|
|
6
|
+
export const promoteCommand = new Command("promote")
|
|
7
|
+
.description("Promote (copy) secrets from one environment to another")
|
|
8
|
+
.requiredOption("--from <env>", "Source environment slug")
|
|
9
|
+
.requiredOption("--to <env>", "Target environment slug")
|
|
10
|
+
.option("--keys <keys>", "Comma-separated list of keys to promote (default: all)")
|
|
11
|
+
.option("--overwrite", "Overwrite existing secrets in target environment", false)
|
|
12
|
+
.option("--dry-run", "Preview what would change without making changes", false)
|
|
13
|
+
.action(async (opts) => {
|
|
14
|
+
const config = requireProjectConfig();
|
|
15
|
+
if (opts.from === opts.to) {
|
|
16
|
+
console.error(chalk.red(" Source and target environments must be different."));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const keys = opts.keys ? opts.keys.split(",").map((k) => k.trim()) : undefined;
|
|
20
|
+
if (opts.dryRun) {
|
|
21
|
+
const spinner = ora("Fetching secrets for dry run...").start();
|
|
22
|
+
try {
|
|
23
|
+
const [srcData, targetData] = await Promise.all([
|
|
24
|
+
apiPullSecrets(config.org, config.project, opts.from),
|
|
25
|
+
apiPullSecrets(config.org, config.project, opts.to),
|
|
26
|
+
]);
|
|
27
|
+
const srcSecrets = keys
|
|
28
|
+
? srcData.secrets.filter((s) => keys.includes(s.key))
|
|
29
|
+
: srcData.secrets;
|
|
30
|
+
const targetKeys = new Set(targetData.secrets.map((s) => s.key));
|
|
31
|
+
let wouldCreate = 0;
|
|
32
|
+
let wouldUpdate = 0;
|
|
33
|
+
let wouldSkip = 0;
|
|
34
|
+
spinner.stop();
|
|
35
|
+
console.log(chalk.bold(`\n Dry run: ${opts.from} → ${opts.to}\n`));
|
|
36
|
+
for (const src of srcSecrets) {
|
|
37
|
+
const exists = targetKeys.has(src.key);
|
|
38
|
+
if (exists && !opts.overwrite) {
|
|
39
|
+
console.log(chalk.dim(` SKIP ${src.key} (exists in target)`));
|
|
40
|
+
wouldSkip++;
|
|
41
|
+
}
|
|
42
|
+
else if (exists) {
|
|
43
|
+
console.log(chalk.yellow(` UPDATE ${src.key}`));
|
|
44
|
+
wouldUpdate++;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.log(chalk.green(` CREATE ${src.key}`));
|
|
48
|
+
wouldCreate++;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
console.log(chalk.dim(`\n Summary: ${wouldCreate} create, ${wouldUpdate} update, ${wouldSkip} skip\n`));
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
spinner.fail(chalk.red(err.message));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const spinner = ora(`Promoting secrets from ${chalk.cyan(opts.from)} → ${chalk.cyan(opts.to)}...`).start();
|
|
60
|
+
try {
|
|
61
|
+
const result = await apiPromoteSecrets(config.org, config.project, {
|
|
62
|
+
fromEnv: opts.from,
|
|
63
|
+
toEnv: opts.to,
|
|
64
|
+
keys,
|
|
65
|
+
overwrite: opts.overwrite,
|
|
66
|
+
});
|
|
67
|
+
spinner.succeed(chalk.green(`Promoted ${chalk.bold(result.promoted.toString())} secrets from ${opts.from} → ${opts.to}` +
|
|
68
|
+
` (${result.created} created, ${result.updated} updated, ${result.skipped} skipped)`));
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
spinner.fail(chalk.red(err.message));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
//# sourceMappingURL=promote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote.js","sourceRoot":"","sources":["../../src/commands/promote.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,WAAW,SAyCpB,CAAC"}
|