@keynv/cli 0.1.0-rc.12 → 0.1.0-rc.13
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/dist/index.js +454 -326
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1056,7 +1056,7 @@ var require_lib = __commonJS({
|
|
|
1056
1056
|
var VERSION, AGENT;
|
|
1057
1057
|
var init_version = __esm({
|
|
1058
1058
|
"src/version.ts"() {
|
|
1059
|
-
VERSION = "0.1.0-rc.
|
|
1059
|
+
VERSION = "0.1.0-rc.13" ;
|
|
1060
1060
|
AGENT = `keynv-cli/${VERSION}`;
|
|
1061
1061
|
}
|
|
1062
1062
|
});
|
|
@@ -5599,6 +5599,9 @@ var init_store = __esm({
|
|
|
5599
5599
|
});
|
|
5600
5600
|
|
|
5601
5601
|
// src/client/http.ts
|
|
5602
|
+
function isClientError(err) {
|
|
5603
|
+
return err instanceof Error && typeof err.status === "number";
|
|
5604
|
+
}
|
|
5602
5605
|
function clientError(status, code, message, details) {
|
|
5603
5606
|
const err = Object.assign(new Error(message), { status, code, details });
|
|
5604
5607
|
return err;
|
|
@@ -5728,8 +5731,23 @@ function fmtError(err) {
|
|
|
5728
5731
|
const status = err.status ? ` (${err.status})` : "";
|
|
5729
5732
|
return `keynv:${code}${status} ${err.message}`;
|
|
5730
5733
|
}
|
|
5734
|
+
function handleExecError(stderr, err) {
|
|
5735
|
+
if (isClientError(err)) {
|
|
5736
|
+
const code = err.code ? `[${err.code}] ` : "";
|
|
5737
|
+
stderr.write(`keynv: ${code}${err.message}
|
|
5738
|
+
`);
|
|
5739
|
+
} else if (err instanceof Error) {
|
|
5740
|
+
stderr.write(`keynv: ${err.message}
|
|
5741
|
+
`);
|
|
5742
|
+
} else {
|
|
5743
|
+
stderr.write(`keynv: unexpected error
|
|
5744
|
+
`);
|
|
5745
|
+
}
|
|
5746
|
+
return 1;
|
|
5747
|
+
}
|
|
5731
5748
|
var init_format = __esm({
|
|
5732
5749
|
"src/ui/format.ts"() {
|
|
5750
|
+
init_http();
|
|
5733
5751
|
}
|
|
5734
5752
|
});
|
|
5735
5753
|
function walkUp(startDir, predicate) {
|
|
@@ -44657,44 +44675,48 @@ var AuditListCommand = class extends Command {
|
|
|
44657
44675
|
sinceId = options_exports.String("--since-id");
|
|
44658
44676
|
json = options_exports.Boolean("--json", false);
|
|
44659
44677
|
async execute() {
|
|
44660
|
-
|
|
44661
|
-
|
|
44662
|
-
|
|
44663
|
-
|
|
44664
|
-
|
|
44665
|
-
|
|
44666
|
-
|
|
44667
|
-
|
|
44678
|
+
try {
|
|
44679
|
+
const client = new ApiClient();
|
|
44680
|
+
const data = await client.request(
|
|
44681
|
+
"/v1/audit",
|
|
44682
|
+
{
|
|
44683
|
+
query: {
|
|
44684
|
+
event_type: this.eventType,
|
|
44685
|
+
limit: this.limit,
|
|
44686
|
+
since_id: this.sinceId
|
|
44687
|
+
}
|
|
44668
44688
|
}
|
|
44669
|
-
|
|
44670
|
-
|
|
44671
|
-
|
|
44672
|
-
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
44689
|
+
);
|
|
44690
|
+
if (this.json) {
|
|
44691
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
44673
44692
|
`);
|
|
44674
|
-
|
|
44675
|
-
|
|
44676
|
-
|
|
44677
|
-
|
|
44678
|
-
|
|
44679
|
-
|
|
44680
|
-
|
|
44681
|
-
|
|
44682
|
-
|
|
44683
|
-
|
|
44684
|
-
|
|
44685
|
-
|
|
44686
|
-
|
|
44687
|
-
|
|
44688
|
-
|
|
44689
|
-
|
|
44690
|
-
|
|
44693
|
+
return 0;
|
|
44694
|
+
}
|
|
44695
|
+
if (data.entries.length === 0) {
|
|
44696
|
+
this.context.stdout.write("no audit entries\n");
|
|
44697
|
+
return 0;
|
|
44698
|
+
}
|
|
44699
|
+
this.context.stdout.write(
|
|
44700
|
+
`${table(
|
|
44701
|
+
["id", "ts", "actor", "agent", "event"],
|
|
44702
|
+
data.entries.map((e2) => [
|
|
44703
|
+
String(e2.id),
|
|
44704
|
+
e2.ts,
|
|
44705
|
+
e2.actor_user_id ?? "(none)",
|
|
44706
|
+
e2.actor_agent,
|
|
44707
|
+
e2.event_type
|
|
44708
|
+
])
|
|
44709
|
+
)}
|
|
44691
44710
|
`
|
|
44692
|
-
|
|
44693
|
-
|
|
44694
|
-
|
|
44711
|
+
);
|
|
44712
|
+
if (data.next_cursor) {
|
|
44713
|
+
this.context.stdout.write(`(next: --since-id ${data.next_cursor})
|
|
44695
44714
|
`);
|
|
44715
|
+
}
|
|
44716
|
+
return 0;
|
|
44717
|
+
} catch (err) {
|
|
44718
|
+
return handleExecError(this.context.stderr, err);
|
|
44696
44719
|
}
|
|
44697
|
-
return 0;
|
|
44698
44720
|
}
|
|
44699
44721
|
};
|
|
44700
44722
|
var AuditVerifyCommand = class extends Command {
|
|
@@ -44704,23 +44726,27 @@ var AuditVerifyCommand = class extends Command {
|
|
|
44704
44726
|
});
|
|
44705
44727
|
json = options_exports.Boolean("--json", false);
|
|
44706
44728
|
async execute() {
|
|
44707
|
-
|
|
44708
|
-
|
|
44709
|
-
|
|
44710
|
-
this.
|
|
44729
|
+
try {
|
|
44730
|
+
const client = new ApiClient();
|
|
44731
|
+
const data = await client.request("/v1/audit/verify", { method: "POST" });
|
|
44732
|
+
if (this.json) {
|
|
44733
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
44711
44734
|
`);
|
|
44712
|
-
|
|
44713
|
-
|
|
44714
|
-
|
|
44715
|
-
|
|
44735
|
+
return data.ok ? 0 : 1;
|
|
44736
|
+
}
|
|
44737
|
+
if (data.ok) {
|
|
44738
|
+
this.context.stdout.write(`OK: ${data.checked} entries verified
|
|
44716
44739
|
`);
|
|
44717
|
-
|
|
44718
|
-
|
|
44719
|
-
|
|
44720
|
-
|
|
44740
|
+
return 0;
|
|
44741
|
+
}
|
|
44742
|
+
this.context.stdout.write(
|
|
44743
|
+
`FAIL: chain broken at id ${data.broken_at_id} (${data.reason}); ${data.checked} entries verified before break
|
|
44721
44744
|
`
|
|
44722
|
-
|
|
44723
|
-
|
|
44745
|
+
);
|
|
44746
|
+
return 1;
|
|
44747
|
+
} catch (err) {
|
|
44748
|
+
return handleExecError(this.context.stderr, err);
|
|
44749
|
+
}
|
|
44724
44750
|
}
|
|
44725
44751
|
};
|
|
44726
44752
|
|
|
@@ -45086,11 +45112,35 @@ function spawnPrivileged(opts) {
|
|
|
45086
45112
|
for (const [k2, v2] of Object.entries(opts.injectedEnv)) env2[k2] = v2;
|
|
45087
45113
|
}
|
|
45088
45114
|
const stdio = ["inherit", "pipe", "pipe"];
|
|
45089
|
-
const
|
|
45115
|
+
const WIN_BUILTINS = /* @__PURE__ */ new Set([
|
|
45116
|
+
"echo",
|
|
45117
|
+
"dir",
|
|
45118
|
+
"type",
|
|
45119
|
+
"copy",
|
|
45120
|
+
"del",
|
|
45121
|
+
"move",
|
|
45122
|
+
"ren",
|
|
45123
|
+
"md",
|
|
45124
|
+
"mkdir",
|
|
45125
|
+
"rd",
|
|
45126
|
+
"rmdir",
|
|
45127
|
+
"cd",
|
|
45128
|
+
"cls",
|
|
45129
|
+
"set",
|
|
45130
|
+
"pause",
|
|
45131
|
+
"find",
|
|
45132
|
+
"where"
|
|
45133
|
+
]);
|
|
45134
|
+
let spawnCmd = opts.command;
|
|
45135
|
+
let spawnArgs = opts.args;
|
|
45136
|
+
if (process.platform === "win32" && WIN_BUILTINS.has(opts.command.toLowerCase())) {
|
|
45137
|
+
spawnCmd = process.env.COMSPEC ?? "cmd.exe";
|
|
45138
|
+
spawnArgs = ["/d", "/s", "/c", opts.command, ...opts.args];
|
|
45139
|
+
}
|
|
45140
|
+
const child = spawn(spawnCmd, spawnArgs, {
|
|
45090
45141
|
env: env2,
|
|
45091
45142
|
stdio,
|
|
45092
|
-
detached: false
|
|
45093
|
-
shell: process.platform === "win32"
|
|
45143
|
+
detached: false
|
|
45094
45144
|
});
|
|
45095
45145
|
const literals = opts.resolved.map((r) => r.value).filter((v2) => v2.length > 0);
|
|
45096
45146
|
if (!opts.noRedact && child.stdout) {
|
|
@@ -45375,25 +45425,29 @@ var ProjectListCommand = class extends Command {
|
|
|
45375
45425
|
});
|
|
45376
45426
|
json = options_exports.Boolean("--json", false);
|
|
45377
45427
|
async execute() {
|
|
45378
|
-
|
|
45379
|
-
|
|
45380
|
-
|
|
45381
|
-
this.
|
|
45428
|
+
try {
|
|
45429
|
+
const client = new ApiClient();
|
|
45430
|
+
const data = await client.request("/v1/projects");
|
|
45431
|
+
if (this.json) {
|
|
45432
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45382
45433
|
`);
|
|
45434
|
+
return 0;
|
|
45435
|
+
}
|
|
45436
|
+
if (data.projects.length === 0) {
|
|
45437
|
+
this.context.stdout.write("no projects\n");
|
|
45438
|
+
return 0;
|
|
45439
|
+
}
|
|
45440
|
+
this.context.stdout.write(
|
|
45441
|
+
`${table(
|
|
45442
|
+
["name", "id", "created_at"],
|
|
45443
|
+
data.projects.map((p2) => [p2.name, p2.id, p2.created_at])
|
|
45444
|
+
)}
|
|
45445
|
+
`
|
|
45446
|
+
);
|
|
45383
45447
|
return 0;
|
|
45448
|
+
} catch (err) {
|
|
45449
|
+
return handleExecError(this.context.stderr, err);
|
|
45384
45450
|
}
|
|
45385
|
-
if (data.projects.length === 0) {
|
|
45386
|
-
this.context.stdout.write("no projects\n");
|
|
45387
|
-
return 0;
|
|
45388
|
-
}
|
|
45389
|
-
this.context.stdout.write(
|
|
45390
|
-
`${table(
|
|
45391
|
-
["name", "id", "created_at"],
|
|
45392
|
-
data.projects.map((p2) => [p2.name, p2.id, p2.created_at])
|
|
45393
|
-
)}
|
|
45394
|
-
`
|
|
45395
|
-
);
|
|
45396
|
-
return 0;
|
|
45397
45451
|
}
|
|
45398
45452
|
};
|
|
45399
45453
|
var ProjectCreateCommand = class extends Command {
|
|
@@ -45407,28 +45461,32 @@ var ProjectCreateCommand = class extends Command {
|
|
|
45407
45461
|
description: 'Environment spec: name[:tier[:approval]]. Tier \u2208 {production,non-production}; "approval" sets require_approval=true.'
|
|
45408
45462
|
});
|
|
45409
45463
|
async execute() {
|
|
45410
|
-
|
|
45411
|
-
const
|
|
45412
|
-
|
|
45413
|
-
|
|
45414
|
-
|
|
45415
|
-
|
|
45416
|
-
|
|
45417
|
-
|
|
45418
|
-
|
|
45419
|
-
|
|
45420
|
-
|
|
45421
|
-
|
|
45422
|
-
|
|
45423
|
-
|
|
45464
|
+
try {
|
|
45465
|
+
const envs = (this.envs ?? ["dev"]).map((spec) => {
|
|
45466
|
+
const [name, tier, approval] = spec.split(":");
|
|
45467
|
+
return {
|
|
45468
|
+
name: name ?? "",
|
|
45469
|
+
tier: tier ?? "non-production",
|
|
45470
|
+
require_approval: approval === "approval"
|
|
45471
|
+
};
|
|
45472
|
+
});
|
|
45473
|
+
const client = new ApiClient();
|
|
45474
|
+
const result = await client.request("/v1/projects", {
|
|
45475
|
+
method: "POST",
|
|
45476
|
+
body: { name: this.name, environments: envs }
|
|
45477
|
+
});
|
|
45478
|
+
this.context.stdout.write(`created project ${result.name} (${result.id})
|
|
45424
45479
|
`);
|
|
45425
|
-
|
|
45426
|
-
|
|
45427
|
-
|
|
45480
|
+
for (const e2 of envs) {
|
|
45481
|
+
this.context.stdout.write(
|
|
45482
|
+
` env: ${e2.name} (tier=${e2.tier}, approval=${e2.require_approval})
|
|
45428
45483
|
`
|
|
45429
|
-
|
|
45484
|
+
);
|
|
45485
|
+
}
|
|
45486
|
+
return 0;
|
|
45487
|
+
} catch (err) {
|
|
45488
|
+
return handleExecError(this.context.stderr, err);
|
|
45430
45489
|
}
|
|
45431
|
-
return 0;
|
|
45432
45490
|
}
|
|
45433
45491
|
};
|
|
45434
45492
|
var ProjectDescribeCommand = class extends Command {
|
|
@@ -45443,23 +45501,27 @@ var ProjectDescribeCommand = class extends Command {
|
|
|
45443
45501
|
id = options_exports.String();
|
|
45444
45502
|
json = options_exports.Boolean("--json", false);
|
|
45445
45503
|
async execute() {
|
|
45446
|
-
|
|
45447
|
-
|
|
45448
|
-
|
|
45449
|
-
|
|
45450
|
-
this.
|
|
45504
|
+
try {
|
|
45505
|
+
const client = new ApiClient();
|
|
45506
|
+
const projectId2 = await resolveProjectId(client, this.id);
|
|
45507
|
+
const data = await client.request(`/v1/projects/${projectId2}`);
|
|
45508
|
+
if (this.json) {
|
|
45509
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45451
45510
|
`);
|
|
45452
|
-
|
|
45453
|
-
|
|
45454
|
-
|
|
45511
|
+
return 0;
|
|
45512
|
+
}
|
|
45513
|
+
this.context.stdout.write(`project: ${data.name} (${data.id})
|
|
45455
45514
|
`);
|
|
45456
|
-
|
|
45457
|
-
|
|
45458
|
-
|
|
45515
|
+
for (const e2 of data.environments) {
|
|
45516
|
+
this.context.stdout.write(
|
|
45517
|
+
` env: ${e2.name} (tier=${e2.tier}, approval=${e2.require_approval})
|
|
45459
45518
|
`
|
|
45460
|
-
|
|
45519
|
+
);
|
|
45520
|
+
}
|
|
45521
|
+
return 0;
|
|
45522
|
+
} catch (err) {
|
|
45523
|
+
return handleExecError(this.context.stderr, err);
|
|
45461
45524
|
}
|
|
45462
|
-
return 0;
|
|
45463
45525
|
}
|
|
45464
45526
|
};
|
|
45465
45527
|
var ProjectDeleteCommand = class extends Command {
|
|
@@ -45472,11 +45534,15 @@ var ProjectDeleteCommand = class extends Command {
|
|
|
45472
45534
|
this.context.stderr.write("keynv: refusing to delete without --force\n");
|
|
45473
45535
|
return 2;
|
|
45474
45536
|
}
|
|
45475
|
-
|
|
45476
|
-
|
|
45477
|
-
|
|
45537
|
+
try {
|
|
45538
|
+
const client = new ApiClient();
|
|
45539
|
+
await client.request(`/v1/projects/${this.id}`, { method: "DELETE" });
|
|
45540
|
+
this.context.stdout.write(`deleted project ${this.id}
|
|
45478
45541
|
`);
|
|
45479
|
-
|
|
45542
|
+
return 0;
|
|
45543
|
+
} catch (err) {
|
|
45544
|
+
return handleExecError(this.context.stderr, err);
|
|
45545
|
+
}
|
|
45480
45546
|
}
|
|
45481
45547
|
};
|
|
45482
45548
|
|
|
@@ -45582,7 +45648,7 @@ commands directly.
|
|
|
45582
45648
|
const content = readFileSync(this.envFile, "utf8");
|
|
45583
45649
|
const entries = parseEnvFile(content, this.envFile);
|
|
45584
45650
|
for (const e2 of entries) {
|
|
45585
|
-
if (classifyEntry(e2.name, e2.value).verdict
|
|
45651
|
+
if (classifyEntry(e2.name, e2.value).verdict === "secret") {
|
|
45586
45652
|
secrets.push({ name: e2.name, value: e2.value });
|
|
45587
45653
|
}
|
|
45588
45654
|
}
|
|
@@ -45732,6 +45798,13 @@ var LoginCommand = class extends Command {
|
|
|
45732
45798
|
});
|
|
45733
45799
|
async execute() {
|
|
45734
45800
|
const finalServerUrl = this.server ?? DEFAULT_SERVER_URL;
|
|
45801
|
+
try {
|
|
45802
|
+
new URL(finalServerUrl);
|
|
45803
|
+
} catch {
|
|
45804
|
+
this.context.stderr.write(`keynv: invalid server URL '${finalServerUrl}'
|
|
45805
|
+
`);
|
|
45806
|
+
return 1;
|
|
45807
|
+
}
|
|
45735
45808
|
if (this.token) {
|
|
45736
45809
|
return this.loginWithToken(finalServerUrl, this.token);
|
|
45737
45810
|
}
|
|
@@ -45754,11 +45827,20 @@ var LoginCommand = class extends Command {
|
|
|
45754
45827
|
}
|
|
45755
45828
|
const email2 = this.email ?? await promptLine("email: ");
|
|
45756
45829
|
const password = this.password ?? await promptHidden("password: ");
|
|
45757
|
-
|
|
45758
|
-
|
|
45759
|
-
|
|
45760
|
-
|
|
45761
|
-
|
|
45830
|
+
let res;
|
|
45831
|
+
try {
|
|
45832
|
+
res = await fetch(new URL("/v1/auth/login", finalServerUrl).toString(), {
|
|
45833
|
+
method: "POST",
|
|
45834
|
+
headers: { "content-type": "application/json", "x-keynv-agent": AGENT },
|
|
45835
|
+
body: JSON.stringify({ email: email2, password })
|
|
45836
|
+
});
|
|
45837
|
+
} catch (err) {
|
|
45838
|
+
this.context.stderr.write(
|
|
45839
|
+
`keynv: cannot reach server '${finalServerUrl}' \u2014 ${err instanceof Error ? err.message : String(err)}
|
|
45840
|
+
`
|
|
45841
|
+
);
|
|
45842
|
+
return 1;
|
|
45843
|
+
}
|
|
45762
45844
|
if (!res.ok) {
|
|
45763
45845
|
const text = await res.text();
|
|
45764
45846
|
let msg = `login failed (${res.status})`;
|
|
@@ -45804,9 +45886,18 @@ var LoginCommand = class extends Command {
|
|
|
45804
45886
|
return 0;
|
|
45805
45887
|
}
|
|
45806
45888
|
async loginWithToken(serverUrl, token) {
|
|
45807
|
-
|
|
45808
|
-
|
|
45809
|
-
|
|
45889
|
+
let res;
|
|
45890
|
+
try {
|
|
45891
|
+
res = await fetch(new URL("/v1/whoami", serverUrl).toString(), {
|
|
45892
|
+
headers: { authorization: `Bearer ${token}`, "x-keynv-agent": AGENT }
|
|
45893
|
+
});
|
|
45894
|
+
} catch (err) {
|
|
45895
|
+
this.context.stderr.write(
|
|
45896
|
+
`keynv: cannot reach server '${serverUrl}' \u2014 ${err instanceof Error ? err.message : String(err)}
|
|
45897
|
+
`
|
|
45898
|
+
);
|
|
45899
|
+
return 1;
|
|
45900
|
+
}
|
|
45810
45901
|
if (!res.ok) {
|
|
45811
45902
|
const text = await res.text();
|
|
45812
45903
|
let msg = `token login failed (${res.status})`;
|
|
@@ -45884,36 +45975,40 @@ var WhoamiCommand = class extends Command {
|
|
|
45884
45975
|
});
|
|
45885
45976
|
json = options_exports.Boolean("--json", false);
|
|
45886
45977
|
async execute() {
|
|
45887
|
-
|
|
45888
|
-
|
|
45889
|
-
|
|
45890
|
-
|
|
45891
|
-
|
|
45892
|
-
|
|
45893
|
-
|
|
45894
|
-
|
|
45895
|
-
this.
|
|
45978
|
+
try {
|
|
45979
|
+
const client = new ApiClient();
|
|
45980
|
+
await client.ensureHydrated();
|
|
45981
|
+
if (!client.isLoggedIn) {
|
|
45982
|
+
this.context.stderr.write("keynv: not logged in. Run `keynv login`.\n");
|
|
45983
|
+
return 1;
|
|
45984
|
+
}
|
|
45985
|
+
const data = await client.request("/v1/whoami");
|
|
45986
|
+
if (this.json) {
|
|
45987
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45896
45988
|
`);
|
|
45897
|
-
|
|
45898
|
-
|
|
45899
|
-
|
|
45989
|
+
return 0;
|
|
45990
|
+
}
|
|
45991
|
+
this.context.stdout.write(`user: ${data.email} (${data.id})
|
|
45900
45992
|
`);
|
|
45901
|
-
|
|
45902
|
-
|
|
45993
|
+
const orgDisplay = data.org_name ? `${data.org_name} (${data.org_id})` : data.org_id;
|
|
45994
|
+
this.context.stdout.write(`org: ${orgDisplay}
|
|
45903
45995
|
`);
|
|
45904
|
-
|
|
45996
|
+
this.context.stdout.write(`role: ${data.org_role}
|
|
45905
45997
|
`);
|
|
45906
|
-
|
|
45907
|
-
|
|
45908
|
-
|
|
45909
|
-
|
|
45910
|
-
|
|
45911
|
-
|
|
45912
|
-
|
|
45998
|
+
if (data.memberships.length === 0) {
|
|
45999
|
+
this.context.stdout.write("memberships: (none)\n");
|
|
46000
|
+
} else {
|
|
46001
|
+
this.context.stdout.write("memberships:\n");
|
|
46002
|
+
for (const m of data.memberships) {
|
|
46003
|
+
const proj = m.project_name ? `${m.project_name} (${m.project_id})` : m.project_id;
|
|
46004
|
+
this.context.stdout.write(` ${proj}: ${m.role}
|
|
45913
46005
|
`);
|
|
46006
|
+
}
|
|
45914
46007
|
}
|
|
46008
|
+
return 0;
|
|
46009
|
+
} catch (err) {
|
|
46010
|
+
return handleExecError(this.context.stderr, err);
|
|
45915
46011
|
}
|
|
45916
|
-
return 0;
|
|
45917
46012
|
}
|
|
45918
46013
|
};
|
|
45919
46014
|
|
|
@@ -45935,15 +46030,19 @@ var MemberAddCommand = class extends Command {
|
|
|
45935
46030
|
this.context.stderr.write("keynv: --role must be one of lead, developer, reader\n");
|
|
45936
46031
|
return 1;
|
|
45937
46032
|
}
|
|
45938
|
-
|
|
45939
|
-
|
|
45940
|
-
|
|
45941
|
-
|
|
45942
|
-
|
|
45943
|
-
|
|
45944
|
-
|
|
46033
|
+
try {
|
|
46034
|
+
const client = new ApiClient();
|
|
46035
|
+
const projectId2 = await resolveProjectId(client, this.project);
|
|
46036
|
+
await client.request(`/v1/projects/${projectId2}/members`, {
|
|
46037
|
+
method: "POST",
|
|
46038
|
+
body: { email: this.email, role: role2 }
|
|
46039
|
+
});
|
|
46040
|
+
this.context.stdout.write(`added ${this.email} to ${this.project} as ${role2}
|
|
45945
46041
|
`);
|
|
45946
|
-
|
|
46042
|
+
return 0;
|
|
46043
|
+
} catch (err) {
|
|
46044
|
+
return handleExecError(this.context.stderr, err);
|
|
46045
|
+
}
|
|
45947
46046
|
}
|
|
45948
46047
|
};
|
|
45949
46048
|
var MemberRemoveCommand = class extends Command {
|
|
@@ -45952,21 +46051,25 @@ var MemberRemoveCommand = class extends Command {
|
|
|
45952
46051
|
project = options_exports.String();
|
|
45953
46052
|
email = options_exports.String();
|
|
45954
46053
|
async execute() {
|
|
45955
|
-
|
|
45956
|
-
|
|
45957
|
-
|
|
45958
|
-
|
|
45959
|
-
|
|
45960
|
-
|
|
46054
|
+
try {
|
|
46055
|
+
const client = new ApiClient();
|
|
46056
|
+
const projectId2 = await resolveProjectId(client, this.project);
|
|
46057
|
+
const members = await client.request(`/v1/projects/${projectId2}/members`);
|
|
46058
|
+
const target = members.members.find((m) => m.email === this.email);
|
|
46059
|
+
if (!target) {
|
|
46060
|
+
this.context.stderr.write(`keynv: ${this.email} is not a member of ${this.project}
|
|
45961
46061
|
`);
|
|
45962
|
-
|
|
45963
|
-
|
|
45964
|
-
|
|
45965
|
-
|
|
45966
|
-
|
|
45967
|
-
|
|
46062
|
+
return 1;
|
|
46063
|
+
}
|
|
46064
|
+
await client.request(`/v1/projects/${projectId2}/members/${target.user_id}`, {
|
|
46065
|
+
method: "DELETE"
|
|
46066
|
+
});
|
|
46067
|
+
this.context.stdout.write(`removed ${this.email} from ${this.project}
|
|
45968
46068
|
`);
|
|
45969
|
-
|
|
46069
|
+
return 0;
|
|
46070
|
+
} catch (err) {
|
|
46071
|
+
return handleExecError(this.context.stderr, err);
|
|
46072
|
+
}
|
|
45970
46073
|
}
|
|
45971
46074
|
};
|
|
45972
46075
|
var MemberListCommand = class extends Command {
|
|
@@ -45975,26 +46078,30 @@ var MemberListCommand = class extends Command {
|
|
|
45975
46078
|
project = options_exports.String();
|
|
45976
46079
|
json = options_exports.Boolean("--json", false);
|
|
45977
46080
|
async execute() {
|
|
45978
|
-
|
|
45979
|
-
|
|
45980
|
-
|
|
45981
|
-
|
|
45982
|
-
this.
|
|
46081
|
+
try {
|
|
46082
|
+
const client = new ApiClient();
|
|
46083
|
+
const projectId2 = await resolveProjectId(client, this.project);
|
|
46084
|
+
const data = await client.request(`/v1/projects/${projectId2}/members`);
|
|
46085
|
+
if (this.json) {
|
|
46086
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45983
46087
|
`);
|
|
46088
|
+
return 0;
|
|
46089
|
+
}
|
|
46090
|
+
if (data.members.length === 0) {
|
|
46091
|
+
this.context.stdout.write("no members\n");
|
|
46092
|
+
return 0;
|
|
46093
|
+
}
|
|
46094
|
+
this.context.stdout.write(
|
|
46095
|
+
`${table(
|
|
46096
|
+
["email", "role", "granted_at"],
|
|
46097
|
+
data.members.map((m) => [m.email, m.role, m.granted_at])
|
|
46098
|
+
)}
|
|
46099
|
+
`
|
|
46100
|
+
);
|
|
45984
46101
|
return 0;
|
|
46102
|
+
} catch (err) {
|
|
46103
|
+
return handleExecError(this.context.stderr, err);
|
|
45985
46104
|
}
|
|
45986
|
-
if (data.members.length === 0) {
|
|
45987
|
-
this.context.stdout.write("no members\n");
|
|
45988
|
-
return 0;
|
|
45989
|
-
}
|
|
45990
|
-
this.context.stdout.write(
|
|
45991
|
-
`${table(
|
|
45992
|
-
["email", "role", "granted_at"],
|
|
45993
|
-
data.members.map((m) => [m.email, m.role, m.granted_at])
|
|
45994
|
-
)}
|
|
45995
|
-
`
|
|
45996
|
-
);
|
|
45997
|
-
return 0;
|
|
45998
46105
|
}
|
|
45999
46106
|
};
|
|
46000
46107
|
var RedactCommand = class extends Command {
|
|
@@ -46093,46 +46200,50 @@ var SecretCreateCommand = class extends Command {
|
|
|
46093
46200
|
});
|
|
46094
46201
|
stdin = options_exports.Boolean("--stdin", false);
|
|
46095
46202
|
async execute() {
|
|
46096
|
-
|
|
46097
|
-
|
|
46098
|
-
|
|
46099
|
-
|
|
46100
|
-
|
|
46101
|
-
if (!
|
|
46102
|
-
|
|
46103
|
-
|
|
46104
|
-
|
|
46105
|
-
|
|
46106
|
-
|
|
46107
|
-
|
|
46108
|
-
|
|
46109
|
-
|
|
46203
|
+
try {
|
|
46204
|
+
const client = new ApiClient();
|
|
46205
|
+
await client.ensureHydrated();
|
|
46206
|
+
let alias2 = this.alias;
|
|
46207
|
+
let value = this.value;
|
|
46208
|
+
if (!alias2) {
|
|
46209
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46210
|
+
try {
|
|
46211
|
+
const built = await promptNewSecret(client);
|
|
46212
|
+
if (!built) return 1;
|
|
46213
|
+
alias2 = built.alias;
|
|
46214
|
+
value = built.value;
|
|
46215
|
+
} catch (err) {
|
|
46216
|
+
if (err instanceof UserCancelled) return 130;
|
|
46217
|
+
throw err;
|
|
46218
|
+
}
|
|
46110
46219
|
}
|
|
46111
|
-
|
|
46112
|
-
|
|
46113
|
-
|
|
46114
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46220
|
+
const parsed = parseAlias(alias2);
|
|
46221
|
+
if (!parsed) {
|
|
46222
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46115
46223
|
${ALIAS_FORMAT_HINT}
|
|
46116
46224
|
`);
|
|
46117
|
-
|
|
46118
|
-
}
|
|
46119
|
-
if (this.stdin) {
|
|
46120
|
-
const chunks = [];
|
|
46121
|
-
for await (const chunk of this.context.stdin) {
|
|
46122
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
46225
|
+
return 1;
|
|
46123
46226
|
}
|
|
46124
|
-
|
|
46125
|
-
|
|
46126
|
-
|
|
46127
|
-
|
|
46128
|
-
|
|
46129
|
-
|
|
46130
|
-
|
|
46131
|
-
|
|
46132
|
-
|
|
46133
|
-
|
|
46227
|
+
if (this.stdin) {
|
|
46228
|
+
const chunks = [];
|
|
46229
|
+
for await (const chunk of this.context.stdin) {
|
|
46230
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
46231
|
+
}
|
|
46232
|
+
value = Buffer.concat(chunks).toString("utf8").replace(/\n$/, "");
|
|
46233
|
+
} else if (value === void 0) {
|
|
46234
|
+
value = await promptHidden("value: ");
|
|
46235
|
+
}
|
|
46236
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46237
|
+
await client.request(`/v1/projects/${projectId2}/secrets`, {
|
|
46238
|
+
method: "POST",
|
|
46239
|
+
body: { env: parsed.environment, key: parsed.key, value }
|
|
46240
|
+
});
|
|
46241
|
+
this.context.stdout.write(`created ${parsed.literal}
|
|
46134
46242
|
`);
|
|
46135
|
-
|
|
46243
|
+
return 0;
|
|
46244
|
+
} catch (err) {
|
|
46245
|
+
return handleExecError(this.context.stderr, err);
|
|
46246
|
+
}
|
|
46136
46247
|
}
|
|
46137
46248
|
};
|
|
46138
46249
|
var SecretGetCommand = class extends Command {
|
|
@@ -46143,40 +46254,44 @@ var SecretGetCommand = class extends Command {
|
|
|
46143
46254
|
alias = options_exports.String({ required: false });
|
|
46144
46255
|
json = options_exports.Boolean("--json", false);
|
|
46145
46256
|
async execute() {
|
|
46146
|
-
|
|
46147
|
-
|
|
46148
|
-
|
|
46149
|
-
|
|
46150
|
-
if (!
|
|
46151
|
-
|
|
46152
|
-
|
|
46153
|
-
|
|
46154
|
-
|
|
46155
|
-
|
|
46257
|
+
try {
|
|
46258
|
+
const client = new ApiClient();
|
|
46259
|
+
await client.ensureHydrated();
|
|
46260
|
+
let alias2 = this.alias;
|
|
46261
|
+
if (!alias2) {
|
|
46262
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46263
|
+
try {
|
|
46264
|
+
alias2 = await pickAliasInteractive(client) ?? void 0;
|
|
46265
|
+
} catch (err) {
|
|
46266
|
+
if (err instanceof UserCancelled) return 130;
|
|
46267
|
+
throw err;
|
|
46268
|
+
}
|
|
46269
|
+
if (!alias2) return 1;
|
|
46156
46270
|
}
|
|
46157
|
-
|
|
46158
|
-
|
|
46159
|
-
|
|
46160
|
-
if (!parsed) {
|
|
46161
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46271
|
+
const parsed = parseAlias(alias2);
|
|
46272
|
+
if (!parsed) {
|
|
46273
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46162
46274
|
${ALIAS_FORMAT_HINT}
|
|
46163
46275
|
`);
|
|
46164
|
-
|
|
46165
|
-
|
|
46166
|
-
|
|
46167
|
-
|
|
46168
|
-
|
|
46169
|
-
);
|
|
46170
|
-
if (this.json) {
|
|
46171
|
-
this.context.stdout.write(
|
|
46172
|
-
`${JSON.stringify({ alias: data.alias, version: data.version, value: data.value })}
|
|
46173
|
-
`
|
|
46276
|
+
return 1;
|
|
46277
|
+
}
|
|
46278
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46279
|
+
const data = await client.request(
|
|
46280
|
+
`/v1/projects/${projectId2}/secrets/${parsed.environment}/${parsed.key}`
|
|
46174
46281
|
);
|
|
46175
|
-
|
|
46176
|
-
|
|
46282
|
+
if (this.json) {
|
|
46283
|
+
this.context.stdout.write(
|
|
46284
|
+
`${JSON.stringify({ alias: data.alias, version: data.version, value: data.value })}
|
|
46285
|
+
`
|
|
46286
|
+
);
|
|
46287
|
+
} else {
|
|
46288
|
+
this.context.stdout.write(`${data.value}
|
|
46177
46289
|
`);
|
|
46290
|
+
}
|
|
46291
|
+
return 0;
|
|
46292
|
+
} catch (err) {
|
|
46293
|
+
return handleExecError(this.context.stderr, err);
|
|
46178
46294
|
}
|
|
46179
|
-
return 0;
|
|
46180
46295
|
}
|
|
46181
46296
|
};
|
|
46182
46297
|
var SecretListCommand = class extends Command {
|
|
@@ -46187,42 +46302,47 @@ var SecretListCommand = class extends Command {
|
|
|
46187
46302
|
project = options_exports.String({ required: false });
|
|
46188
46303
|
json = options_exports.Boolean("--json", false);
|
|
46189
46304
|
async execute() {
|
|
46190
|
-
|
|
46191
|
-
|
|
46192
|
-
|
|
46193
|
-
|
|
46194
|
-
if (!
|
|
46195
|
-
|
|
46196
|
-
|
|
46197
|
-
|
|
46198
|
-
|
|
46199
|
-
|
|
46200
|
-
|
|
46201
|
-
|
|
46202
|
-
|
|
46203
|
-
|
|
46204
|
-
|
|
46305
|
+
try {
|
|
46306
|
+
const client = new ApiClient();
|
|
46307
|
+
await client.ensureHydrated();
|
|
46308
|
+
let projectName = this.project;
|
|
46309
|
+
if (!projectName) {
|
|
46310
|
+
if (!isInteractive()) {
|
|
46311
|
+
this.context.stderr.write("keynv: missing <project>.\n");
|
|
46312
|
+
return 1;
|
|
46313
|
+
}
|
|
46314
|
+
try {
|
|
46315
|
+
const picked = await pickProject(client, "Project");
|
|
46316
|
+
if (!picked) return 1;
|
|
46317
|
+
projectName = picked.name;
|
|
46318
|
+
} catch (err) {
|
|
46319
|
+
if (err instanceof UserCancelled) return 130;
|
|
46320
|
+
throw err;
|
|
46321
|
+
}
|
|
46205
46322
|
}
|
|
46206
|
-
|
|
46207
|
-
|
|
46208
|
-
|
|
46209
|
-
|
|
46210
|
-
|
|
46323
|
+
const resolvedProjectName = projectName.startsWith("@") ? projectName.slice(1).split(".")[0] ?? projectName : projectName;
|
|
46324
|
+
const projectId2 = await resolveProjectId(client, resolvedProjectName);
|
|
46325
|
+
const data = await client.request(`/v1/projects/${projectId2}/secrets`);
|
|
46326
|
+
if (this.json) {
|
|
46327
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
46211
46328
|
`);
|
|
46329
|
+
return 0;
|
|
46330
|
+
}
|
|
46331
|
+
if (data.secrets.length === 0) {
|
|
46332
|
+
this.context.stdout.write("no secrets\n");
|
|
46333
|
+
return 0;
|
|
46334
|
+
}
|
|
46335
|
+
this.context.stdout.write(
|
|
46336
|
+
`${table(
|
|
46337
|
+
["alias", "version", "created_at"],
|
|
46338
|
+
data.secrets.map((s) => [s.alias, String(s.version), s.created_at])
|
|
46339
|
+
)}
|
|
46340
|
+
`
|
|
46341
|
+
);
|
|
46212
46342
|
return 0;
|
|
46343
|
+
} catch (err) {
|
|
46344
|
+
return handleExecError(this.context.stderr, err);
|
|
46213
46345
|
}
|
|
46214
|
-
if (data.secrets.length === 0) {
|
|
46215
|
-
this.context.stdout.write("no secrets\n");
|
|
46216
|
-
return 0;
|
|
46217
|
-
}
|
|
46218
|
-
this.context.stdout.write(
|
|
46219
|
-
`${table(
|
|
46220
|
-
["alias", "version", "created_at"],
|
|
46221
|
-
data.secrets.map((s) => [s.alias, String(s.version), s.created_at])
|
|
46222
|
-
)}
|
|
46223
|
-
`
|
|
46224
|
-
);
|
|
46225
|
-
return 0;
|
|
46226
46346
|
}
|
|
46227
46347
|
};
|
|
46228
46348
|
var SecretRotateCommand = class extends Command {
|
|
@@ -46232,46 +46352,50 @@ var SecretRotateCommand = class extends Command {
|
|
|
46232
46352
|
value = options_exports.String("--value");
|
|
46233
46353
|
stdin = options_exports.Boolean("--stdin", false);
|
|
46234
46354
|
async execute() {
|
|
46235
|
-
|
|
46236
|
-
|
|
46237
|
-
|
|
46238
|
-
|
|
46239
|
-
if (!
|
|
46240
|
-
|
|
46241
|
-
|
|
46242
|
-
|
|
46243
|
-
|
|
46244
|
-
|
|
46355
|
+
try {
|
|
46356
|
+
const client = new ApiClient();
|
|
46357
|
+
await client.ensureHydrated();
|
|
46358
|
+
let alias2 = this.alias;
|
|
46359
|
+
if (!alias2) {
|
|
46360
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46361
|
+
try {
|
|
46362
|
+
alias2 = await pickAliasInteractive(client) ?? void 0;
|
|
46363
|
+
} catch (err) {
|
|
46364
|
+
if (err instanceof UserCancelled) return 130;
|
|
46365
|
+
throw err;
|
|
46366
|
+
}
|
|
46367
|
+
if (!alias2) return 1;
|
|
46245
46368
|
}
|
|
46246
|
-
|
|
46247
|
-
|
|
46248
|
-
|
|
46249
|
-
if (!parsed) {
|
|
46250
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46369
|
+
const parsed = parseAlias(alias2);
|
|
46370
|
+
if (!parsed) {
|
|
46371
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46251
46372
|
${ALIAS_FORMAT_HINT}
|
|
46252
46373
|
`);
|
|
46253
|
-
|
|
46254
|
-
}
|
|
46255
|
-
let value;
|
|
46256
|
-
if (this.stdin) {
|
|
46257
|
-
const chunks = [];
|
|
46258
|
-
for await (const chunk of this.context.stdin) {
|
|
46259
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
46374
|
+
return 1;
|
|
46260
46375
|
}
|
|
46261
|
-
value
|
|
46262
|
-
|
|
46263
|
-
|
|
46264
|
-
|
|
46265
|
-
|
|
46266
|
-
|
|
46267
|
-
|
|
46268
|
-
|
|
46269
|
-
|
|
46270
|
-
|
|
46271
|
-
|
|
46272
|
-
|
|
46376
|
+
let value;
|
|
46377
|
+
if (this.stdin) {
|
|
46378
|
+
const chunks = [];
|
|
46379
|
+
for await (const chunk of this.context.stdin) {
|
|
46380
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
46381
|
+
}
|
|
46382
|
+
value = Buffer.concat(chunks).toString("utf8").replace(/\n$/, "");
|
|
46383
|
+
} else if (this.value !== void 0) {
|
|
46384
|
+
value = this.value;
|
|
46385
|
+
} else {
|
|
46386
|
+
value = await promptHidden("new value: ");
|
|
46387
|
+
}
|
|
46388
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46389
|
+
const data = await client.request(
|
|
46390
|
+
`/v1/projects/${projectId2}/secrets/${parsed.environment}/${parsed.key}/rotate`,
|
|
46391
|
+
{ method: "POST", body: { new_value: value } }
|
|
46392
|
+
);
|
|
46393
|
+
this.context.stdout.write(`rotated ${data.alias} \u2192 v${data.version}
|
|
46273
46394
|
`);
|
|
46274
|
-
|
|
46395
|
+
return 0;
|
|
46396
|
+
} catch (err) {
|
|
46397
|
+
return handleExecError(this.context.stderr, err);
|
|
46398
|
+
}
|
|
46275
46399
|
}
|
|
46276
46400
|
};
|
|
46277
46401
|
var SecretDeleteCommand = class extends Command {
|
|
@@ -46279,33 +46403,37 @@ var SecretDeleteCommand = class extends Command {
|
|
|
46279
46403
|
static usage = Command.Usage({ description: "Soft-delete a secret." });
|
|
46280
46404
|
alias = options_exports.String({ required: false });
|
|
46281
46405
|
async execute() {
|
|
46282
|
-
|
|
46283
|
-
|
|
46284
|
-
|
|
46285
|
-
|
|
46286
|
-
if (!
|
|
46287
|
-
|
|
46288
|
-
|
|
46289
|
-
|
|
46290
|
-
|
|
46291
|
-
|
|
46406
|
+
try {
|
|
46407
|
+
const client = new ApiClient();
|
|
46408
|
+
await client.ensureHydrated();
|
|
46409
|
+
let alias2 = this.alias;
|
|
46410
|
+
if (!alias2) {
|
|
46411
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46412
|
+
try {
|
|
46413
|
+
alias2 = await pickAliasInteractive(client) ?? void 0;
|
|
46414
|
+
} catch (err) {
|
|
46415
|
+
if (err instanceof UserCancelled) return 130;
|
|
46416
|
+
throw err;
|
|
46417
|
+
}
|
|
46418
|
+
if (!alias2) return 1;
|
|
46292
46419
|
}
|
|
46293
|
-
|
|
46294
|
-
|
|
46295
|
-
|
|
46296
|
-
if (!parsed) {
|
|
46297
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46420
|
+
const parsed = parseAlias(alias2);
|
|
46421
|
+
if (!parsed) {
|
|
46422
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46298
46423
|
${ALIAS_FORMAT_HINT}
|
|
46299
46424
|
`);
|
|
46300
|
-
|
|
46301
|
-
|
|
46302
|
-
|
|
46303
|
-
|
|
46304
|
-
|
|
46305
|
-
|
|
46306
|
-
|
|
46425
|
+
return 1;
|
|
46426
|
+
}
|
|
46427
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46428
|
+
await client.request(`/v1/projects/${projectId2}/secrets/${parsed.environment}/${parsed.key}`, {
|
|
46429
|
+
method: "DELETE"
|
|
46430
|
+
});
|
|
46431
|
+
this.context.stdout.write(`deleted ${parsed.literal}
|
|
46307
46432
|
`);
|
|
46308
|
-
|
|
46433
|
+
return 0;
|
|
46434
|
+
} catch (err) {
|
|
46435
|
+
return handleExecError(this.context.stderr, err);
|
|
46436
|
+
}
|
|
46309
46437
|
}
|
|
46310
46438
|
};
|
|
46311
46439
|
function generateSecret(bytes = 32) {
|