@keynv/cli 0.1.0-rc.12 → 0.1.0-rc.14
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 +1094 -698
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import { randomBytes } from 'crypto';
|
|
4
|
-
import { readFileSync, existsSync, statSync,
|
|
4
|
+
import { readFileSync, writeFileSync, unlinkSync, existsSync, statSync, readdirSync, mkdirSync, rmSync } from 'fs';
|
|
5
5
|
import { hostname, platform, homedir } from 'os';
|
|
6
|
-
import
|
|
6
|
+
import * as nodePath from 'path';
|
|
7
|
+
import { relative, join, isAbsolute, resolve, dirname, basename } from 'path';
|
|
7
8
|
import { Entry } from '@napi-rs/keyring';
|
|
8
9
|
import { styleText } from 'util';
|
|
9
10
|
import j2, { stdin, stdout } from 'process';
|
|
@@ -301,16 +302,16 @@ var require_lib = __commonJS({
|
|
|
301
302
|
}
|
|
302
303
|
});
|
|
303
304
|
}
|
|
304
|
-
function isArray(spec, { delimiter } = {}) {
|
|
305
|
+
function isArray(spec, { delimiter: delimiter2 } = {}) {
|
|
305
306
|
return makeValidator({
|
|
306
307
|
test: (value, state) => {
|
|
307
308
|
var _a;
|
|
308
309
|
const originalValue = value;
|
|
309
|
-
if (typeof value === `string` && typeof
|
|
310
|
+
if (typeof value === `string` && typeof delimiter2 !== `undefined`) {
|
|
310
311
|
if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
|
|
311
312
|
if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
|
|
312
313
|
return pushError(state, `Unbound coercion result`);
|
|
313
|
-
value = value.split(
|
|
314
|
+
value = value.split(delimiter2);
|
|
314
315
|
}
|
|
315
316
|
}
|
|
316
317
|
if (!Array.isArray(value))
|
|
@@ -328,8 +329,8 @@ var require_lib = __commonJS({
|
|
|
328
329
|
}
|
|
329
330
|
});
|
|
330
331
|
}
|
|
331
|
-
function isSet(spec, { delimiter } = {}) {
|
|
332
|
-
const isArrayValidator = isArray(spec, { delimiter });
|
|
332
|
+
function isSet(spec, { delimiter: delimiter2 } = {}) {
|
|
333
|
+
const isArrayValidator = isArray(spec, { delimiter: delimiter2 });
|
|
333
334
|
return makeValidator({
|
|
334
335
|
test: (value, state) => {
|
|
335
336
|
var _a, _b;
|
|
@@ -420,16 +421,16 @@ var require_lib = __commonJS({
|
|
|
420
421
|
}
|
|
421
422
|
});
|
|
422
423
|
}
|
|
423
|
-
function isTuple(spec, { delimiter } = {}) {
|
|
424
|
+
function isTuple(spec, { delimiter: delimiter2 } = {}) {
|
|
424
425
|
const lengthValidator = hasExactLength(spec.length);
|
|
425
426
|
return makeValidator({
|
|
426
427
|
test: (value, state) => {
|
|
427
428
|
var _a;
|
|
428
|
-
if (typeof value === `string` && typeof
|
|
429
|
+
if (typeof value === `string` && typeof delimiter2 !== `undefined`) {
|
|
429
430
|
if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
|
|
430
431
|
if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
|
|
431
432
|
return pushError(state, `Unbound coercion result`);
|
|
432
|
-
value = value.split(
|
|
433
|
+
value = value.split(delimiter2);
|
|
433
434
|
state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, value)]);
|
|
434
435
|
}
|
|
435
436
|
}
|
|
@@ -1056,7 +1057,7 @@ var require_lib = __commonJS({
|
|
|
1056
1057
|
var VERSION, AGENT;
|
|
1057
1058
|
var init_version = __esm({
|
|
1058
1059
|
"src/version.ts"() {
|
|
1059
|
-
VERSION = "0.1.0-rc.
|
|
1060
|
+
VERSION = "0.1.0-rc.14" ;
|
|
1060
1061
|
AGENT = `keynv-cli/${VERSION}`;
|
|
1061
1062
|
}
|
|
1062
1063
|
});
|
|
@@ -5599,6 +5600,9 @@ var init_store = __esm({
|
|
|
5599
5600
|
});
|
|
5600
5601
|
|
|
5601
5602
|
// src/client/http.ts
|
|
5603
|
+
function isClientError(err) {
|
|
5604
|
+
return err instanceof Error && typeof err.status === "number";
|
|
5605
|
+
}
|
|
5602
5606
|
function clientError(status, code, message, details) {
|
|
5603
5607
|
const err = Object.assign(new Error(message), { status, code, details });
|
|
5604
5608
|
return err;
|
|
@@ -5653,7 +5657,16 @@ var init_http = __esm({
|
|
|
5653
5657
|
return this.creds;
|
|
5654
5658
|
}
|
|
5655
5659
|
async ensureHydrated() {
|
|
5656
|
-
if (this.hydrated)
|
|
5660
|
+
if (this.hydrated) {
|
|
5661
|
+
try {
|
|
5662
|
+
await this.hydrated;
|
|
5663
|
+
} catch (err) {
|
|
5664
|
+
process.stderr.write(
|
|
5665
|
+
`${err instanceof Error ? err.message : `keynv: credential load failed \u2014 ${String(err)}`}
|
|
5666
|
+
`
|
|
5667
|
+
);
|
|
5668
|
+
}
|
|
5669
|
+
}
|
|
5657
5670
|
}
|
|
5658
5671
|
async setCredentials(creds) {
|
|
5659
5672
|
this.creds = creds;
|
|
@@ -5675,21 +5688,40 @@ var init_http = __esm({
|
|
|
5675
5688
|
headers.authorization = `Bearer ${this.creds.access_token}`;
|
|
5676
5689
|
}
|
|
5677
5690
|
const url = this.creds ? buildUrl(this.creds.server_url, path, opts.query) : path;
|
|
5678
|
-
let res
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5691
|
+
let res;
|
|
5692
|
+
try {
|
|
5693
|
+
res = await fetch(url, {
|
|
5694
|
+
method: opts.method ?? "GET",
|
|
5695
|
+
headers,
|
|
5696
|
+
...opts.body !== void 0 ? { body: JSON.stringify(opts.body) } : {}
|
|
5697
|
+
});
|
|
5698
|
+
} catch (err) {
|
|
5699
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
5700
|
+
const serverUrl = this.creds?.server_url ?? url;
|
|
5701
|
+
throw new Error(
|
|
5702
|
+
`keynv: cannot reach server '${serverUrl}' \u2014 ${cause}
|
|
5703
|
+
Check the server is running: curl ${serverUrl}/v1/health`
|
|
5704
|
+
);
|
|
5705
|
+
}
|
|
5683
5706
|
if (res.status === 401 && this.creds && opts.authed !== false) {
|
|
5684
5707
|
const refreshed = await tryRefresh(this.creds);
|
|
5685
5708
|
if (refreshed) {
|
|
5686
5709
|
this.creds = refreshed;
|
|
5687
5710
|
headers.authorization = `Bearer ${refreshed.access_token}`;
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5711
|
+
try {
|
|
5712
|
+
res = await fetch(url, {
|
|
5713
|
+
method: opts.method ?? "GET",
|
|
5714
|
+
headers,
|
|
5715
|
+
...opts.body !== void 0 ? { body: JSON.stringify(opts.body) } : {}
|
|
5716
|
+
});
|
|
5717
|
+
} catch (err) {
|
|
5718
|
+
const cause = err instanceof Error ? err.message : String(err);
|
|
5719
|
+
const serverUrl = this.creds?.server_url ?? url;
|
|
5720
|
+
throw new Error(
|
|
5721
|
+
`keynv: cannot reach server '${serverUrl}' \u2014 ${cause}
|
|
5722
|
+
Check the server is running: curl ${serverUrl}/v1/health`
|
|
5723
|
+
);
|
|
5724
|
+
}
|
|
5693
5725
|
}
|
|
5694
5726
|
}
|
|
5695
5727
|
if (res.status === 204) return void 0;
|
|
@@ -5728,8 +5760,23 @@ function fmtError(err) {
|
|
|
5728
5760
|
const status = err.status ? ` (${err.status})` : "";
|
|
5729
5761
|
return `keynv:${code}${status} ${err.message}`;
|
|
5730
5762
|
}
|
|
5763
|
+
function handleExecError(stderr, err) {
|
|
5764
|
+
if (isClientError(err)) {
|
|
5765
|
+
const code = err.code ? `[${err.code}] ` : "";
|
|
5766
|
+
stderr.write(`keynv: ${code}${err.message}
|
|
5767
|
+
`);
|
|
5768
|
+
} else if (err instanceof Error) {
|
|
5769
|
+
stderr.write(`keynv: ${err.message}
|
|
5770
|
+
`);
|
|
5771
|
+
} else {
|
|
5772
|
+
stderr.write(`keynv: unexpected error
|
|
5773
|
+
`);
|
|
5774
|
+
}
|
|
5775
|
+
return 1;
|
|
5776
|
+
}
|
|
5731
5777
|
var init_format = __esm({
|
|
5732
5778
|
"src/ui/format.ts"() {
|
|
5779
|
+
init_http();
|
|
5733
5780
|
}
|
|
5734
5781
|
});
|
|
5735
5782
|
function walkUp(startDir, predicate) {
|
|
@@ -5873,6 +5920,121 @@ var init_envFile = __esm({
|
|
|
5873
5920
|
};
|
|
5874
5921
|
}
|
|
5875
5922
|
});
|
|
5923
|
+
function findProjectRoot(startDir) {
|
|
5924
|
+
const result = walkUp(startDir, (dir) => {
|
|
5925
|
+
for (const marker of PROJECT_MARKERS) {
|
|
5926
|
+
if (existsSync(join(dir, marker))) {
|
|
5927
|
+
return { dir, marker };
|
|
5928
|
+
}
|
|
5929
|
+
}
|
|
5930
|
+
if (existsSync(join(dir, GIT_MARKER))) {
|
|
5931
|
+
return { dir, marker: GIT_MARKER };
|
|
5932
|
+
}
|
|
5933
|
+
return null;
|
|
5934
|
+
});
|
|
5935
|
+
if (!result) return null;
|
|
5936
|
+
return buildRoot(result.dir, result.marker);
|
|
5937
|
+
}
|
|
5938
|
+
function buildRoot(dir, marker) {
|
|
5939
|
+
let suggestedName = basename(dir);
|
|
5940
|
+
let scripts = null;
|
|
5941
|
+
let invalid = false;
|
|
5942
|
+
if (marker === "package.json" || existsSync(join(dir, "package.json"))) {
|
|
5943
|
+
try {
|
|
5944
|
+
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
5945
|
+
if (typeof pkg.name === "string" && pkg.name.length > 0) {
|
|
5946
|
+
suggestedName = pkg.name.replace(/^@[^/]+\//, "");
|
|
5947
|
+
}
|
|
5948
|
+
if (pkg.scripts && typeof pkg.scripts === "object") {
|
|
5949
|
+
scripts = Object.fromEntries(
|
|
5950
|
+
Object.entries(pkg.scripts).filter(([, v2]) => typeof v2 === "string")
|
|
5951
|
+
);
|
|
5952
|
+
}
|
|
5953
|
+
} catch {
|
|
5954
|
+
invalid = true;
|
|
5955
|
+
}
|
|
5956
|
+
}
|
|
5957
|
+
return {
|
|
5958
|
+
path: dir,
|
|
5959
|
+
suggestedName,
|
|
5960
|
+
marker,
|
|
5961
|
+
packageJsonScripts: scripts,
|
|
5962
|
+
packageJsonInvalid: invalid
|
|
5963
|
+
};
|
|
5964
|
+
}
|
|
5965
|
+
function findEnvFiles(rootDir) {
|
|
5966
|
+
let entries;
|
|
5967
|
+
try {
|
|
5968
|
+
entries = readdirSync(rootDir);
|
|
5969
|
+
} catch {
|
|
5970
|
+
return [];
|
|
5971
|
+
}
|
|
5972
|
+
const hits = [];
|
|
5973
|
+
for (const name of entries) {
|
|
5974
|
+
if (!ENV_GLOB.test(name)) continue;
|
|
5975
|
+
if (ENV_EXAMPLE.test(name)) continue;
|
|
5976
|
+
if (name === KEYNV_ENV_BASENAME) continue;
|
|
5977
|
+
const full = join(rootDir, name);
|
|
5978
|
+
try {
|
|
5979
|
+
if (!statSync(full).isFile()) continue;
|
|
5980
|
+
} catch {
|
|
5981
|
+
continue;
|
|
5982
|
+
}
|
|
5983
|
+
const suffixMatch = name.match(/^\.env\.(.+)$/);
|
|
5984
|
+
const suffix = suffixMatch ? suffixMatch[1] : null;
|
|
5985
|
+
hits.push({ path: full, name, suffix, suggestedEnv: suggestedEnvForSuffix(suffix) });
|
|
5986
|
+
}
|
|
5987
|
+
hits.sort((a, b2) => {
|
|
5988
|
+
if (a.suffix === null) return -1;
|
|
5989
|
+
if (b2.suffix === null) return 1;
|
|
5990
|
+
return a.name.localeCompare(b2.name);
|
|
5991
|
+
});
|
|
5992
|
+
return hits;
|
|
5993
|
+
}
|
|
5994
|
+
function suggestedEnvForSuffix(suffix) {
|
|
5995
|
+
if (suffix === null) return "dev";
|
|
5996
|
+
switch (suffix) {
|
|
5997
|
+
case "local":
|
|
5998
|
+
case "development":
|
|
5999
|
+
case "dev":
|
|
6000
|
+
return "dev";
|
|
6001
|
+
case "production":
|
|
6002
|
+
case "prod":
|
|
6003
|
+
return "prod";
|
|
6004
|
+
case "staging":
|
|
6005
|
+
case "stage":
|
|
6006
|
+
return "staging";
|
|
6007
|
+
case "test":
|
|
6008
|
+
return "test";
|
|
6009
|
+
case "preview":
|
|
6010
|
+
return "preview";
|
|
6011
|
+
default:
|
|
6012
|
+
return suffix;
|
|
6013
|
+
}
|
|
6014
|
+
}
|
|
6015
|
+
function hasExistingKeynvEnv(rootDir) {
|
|
6016
|
+
return existsSync(join(rootDir, KEYNV_ENV_BASENAME));
|
|
6017
|
+
}
|
|
6018
|
+
var PROJECT_MARKERS, GIT_MARKER, ENV_GLOB, ENV_EXAMPLE, KEYNV_ENV_BASENAME;
|
|
6019
|
+
var init_detect = __esm({
|
|
6020
|
+
"src/init/detect.ts"() {
|
|
6021
|
+
init_fs();
|
|
6022
|
+
PROJECT_MARKERS = [
|
|
6023
|
+
"package.json",
|
|
6024
|
+
"pyproject.toml",
|
|
6025
|
+
"Cargo.toml",
|
|
6026
|
+
"go.mod",
|
|
6027
|
+
"pnpm-workspace.yaml",
|
|
6028
|
+
"deno.json",
|
|
6029
|
+
"deno.jsonc",
|
|
6030
|
+
"requirements.txt"
|
|
6031
|
+
];
|
|
6032
|
+
GIT_MARKER = ".git";
|
|
6033
|
+
ENV_GLOB = /^\.env(\.[A-Za-z0-9_-]+)?$/;
|
|
6034
|
+
ENV_EXAMPLE = /^\.env\.(example|sample|template|dist|defaults)$/;
|
|
6035
|
+
KEYNV_ENV_BASENAME = ".keynv.env";
|
|
6036
|
+
}
|
|
6037
|
+
});
|
|
5876
6038
|
|
|
5877
6039
|
// src/init/heuristics.ts
|
|
5878
6040
|
function shannonEntropyBits(s) {
|
|
@@ -5999,6 +6161,95 @@ var init_heuristics = __esm({
|
|
|
5999
6161
|
];
|
|
6000
6162
|
}
|
|
6001
6163
|
});
|
|
6164
|
+
function aiContextBody() {
|
|
6165
|
+
return `## keynv (secrets)
|
|
6166
|
+
|
|
6167
|
+
This project uses [keynv](https://keynv.dev) for secrets. There is a \`.keynv.env\` file at the project root containing **alias references** like \`OPENAI_API_KEY=@projectname.dev.openai-key\` \u2014 these are NOT real values, they are references to secrets stored in the keynv vault.
|
|
6168
|
+
|
|
6169
|
+
### Mental model
|
|
6170
|
+
|
|
6171
|
+
- **\`.keynv.env\`** \u2014 checked into git, contains aliases. Safe to read, edit, commit.
|
|
6172
|
+
- **Vault** \u2014 holds the real values. The \`keynv\` CLI reads it on demand.
|
|
6173
|
+
- **\`keynv exec -- <command>\`** \u2014 forks the command in a subprocess where the real values are injected into env vars. The parent process (where you, the AI agent, run) NEVER sees the real values.
|
|
6174
|
+
- **Redactor** \u2014 pipes subprocess stdout/stderr through a masker before they reach this terminal. Even if a script accidentally echoes a secret, you see \`<REDACTED:...>\` here.
|
|
6175
|
+
|
|
6176
|
+
### What you should do
|
|
6177
|
+
|
|
6178
|
+
When the user asks about secrets or env vars, follow this decision tree:
|
|
6179
|
+
|
|
6180
|
+
| User intent | Run / suggest |
|
|
6181
|
+
|---|---|
|
|
6182
|
+
| "Add a new API key" / "set up a secret" | \`keynv secret create\` (interactive prompt picks project + env + key) |
|
|
6183
|
+
| "I have a \`.env\`, migrate it" | \`keynv init\` (you're seeing this file because that already happened) |
|
|
6184
|
+
| "Run the app / dev server / tests" | \`keynv exec -- <their existing command>\` (auto-loads \`.keynv.env\`) |
|
|
6185
|
+
| "Show me the value of X" | \`keynv secret get @alias\` \u2014 but copy to clipboard, do NOT print the value into chat / terminal |
|
|
6186
|
+
| "Rotate this key" | \`keynv secret rotate @alias\` |
|
|
6187
|
+
| "Add a new env var to the project" | Edit \`.keynv.env\` and add \`NAME=@project.env.key\` (after creating the secret with \`keynv secret create\`) |
|
|
6188
|
+
| "Who has access?" | \`keynv member list <project>\` |
|
|
6189
|
+
|
|
6190
|
+
### Hard rules \u2014 do not violate
|
|
6191
|
+
|
|
6192
|
+
1. **Never print resolved secret values** to the chat, terminal, log, or any file. The user's editor / scrollback / chat history is an attack surface.
|
|
6193
|
+
2. **Never write a \`.env\` file** (or any file) containing real secret values. The whole point of keynv is that those don't exist on disk.
|
|
6194
|
+
3. **Never edit \`.keynv.env\` to substitute resolved values for aliases.** The file should only ever contain \`@project.env.key\` references and plain non-secret literals.
|
|
6195
|
+
4. **Use \`keynv exec --\` to run commands that need env vars.** Don't try to load \`.keynv.env\` yourself by parsing it manually; the wrapper handles resolution + redaction + subprocess isolation.
|
|
6196
|
+
5. **If a tool fails with "blocked by keynv-guard" or similar**, do NOT try to work around it. Tell the user \u2014 that's a sign of a misconfiguration, not an obstacle to bypass.
|
|
6197
|
+
6. **Treat the alias literal (\`@project.env.key\`) as the canonical reference**, never the resolved value. When you write code, configs, or commands that need a secret, write the alias.
|
|
6198
|
+
|
|
6199
|
+
### Quick reference
|
|
6200
|
+
|
|
6201
|
+
\`\`\`bash
|
|
6202
|
+
keynv # interactive TUI menu (pick projects, secrets, members)
|
|
6203
|
+
keynv exec -- <cmd> # run cmd with .keynv.env loaded
|
|
6204
|
+
keynv secret create # walk through creating a new secret
|
|
6205
|
+
keynv secret list <project> # list aliases (no values)
|
|
6206
|
+
keynv whoami # who am I logged in as
|
|
6207
|
+
keynv --help # full command list
|
|
6208
|
+
\`\`\`
|
|
6209
|
+
|
|
6210
|
+
If \`.keynv.env\` is missing or empty, the user probably hasn't run \`keynv init\` yet \u2014 suggest they do so before they paste a secret into a \`.env\`.`;
|
|
6211
|
+
}
|
|
6212
|
+
function renderKeynvBlock() {
|
|
6213
|
+
return `${KEYNV_BLOCK_START}
|
|
6214
|
+
${aiContextBody()}
|
|
6215
|
+
${KEYNV_BLOCK_END}`;
|
|
6216
|
+
}
|
|
6217
|
+
function writeAiContext(rootPath) {
|
|
6218
|
+
const path = join(rootPath, AGENTS_FILE_BASENAME);
|
|
6219
|
+
const block = renderKeynvBlock();
|
|
6220
|
+
if (!existsSync(path)) {
|
|
6221
|
+
const initial = `# Agent guidance for this project
|
|
6222
|
+
|
|
6223
|
+
${block}
|
|
6224
|
+
`;
|
|
6225
|
+
writeFileSync(path, initial);
|
|
6226
|
+
return "created";
|
|
6227
|
+
}
|
|
6228
|
+
const existing = readFileSync(path, "utf8");
|
|
6229
|
+
const startIdx = existing.indexOf(KEYNV_BLOCK_START);
|
|
6230
|
+
const endIdx = existing.indexOf(KEYNV_BLOCK_END);
|
|
6231
|
+
if (startIdx >= 0 && endIdx > startIdx) {
|
|
6232
|
+
const before = existing.slice(0, startIdx);
|
|
6233
|
+
const after = existing.slice(endIdx + KEYNV_BLOCK_END.length);
|
|
6234
|
+
const next = `${before}${block}${after}`;
|
|
6235
|
+
if (next === existing) return "unchanged";
|
|
6236
|
+
writeFileSync(path, next);
|
|
6237
|
+
return "updated";
|
|
6238
|
+
}
|
|
6239
|
+
const sep = existing.length === 0 ? "" : existing.endsWith("\n\n") ? "" : existing.endsWith("\n") ? "\n" : "\n\n";
|
|
6240
|
+
const trailingNewline = existing.endsWith("\n") ? "" : "\n";
|
|
6241
|
+
writeFileSync(path, `${existing}${trailingNewline}${sep}${block}
|
|
6242
|
+
`);
|
|
6243
|
+
return "appended";
|
|
6244
|
+
}
|
|
6245
|
+
var AGENTS_FILE_BASENAME, KEYNV_BLOCK_START, KEYNV_BLOCK_END;
|
|
6246
|
+
var init_aiContext = __esm({
|
|
6247
|
+
"src/init/aiContext.ts"() {
|
|
6248
|
+
AGENTS_FILE_BASENAME = "AGENTS.md";
|
|
6249
|
+
KEYNV_BLOCK_START = "<!-- keynv:start -- generated by `keynv init`; safe to leave intact, will be refreshed on re-run -->";
|
|
6250
|
+
KEYNV_BLOCK_END = "<!-- keynv:end -->";
|
|
6251
|
+
}
|
|
6252
|
+
});
|
|
6002
6253
|
|
|
6003
6254
|
// ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
|
|
6004
6255
|
var getCodePointsLength, isFullWidth, isWideNotCJKTNotEmoji;
|
|
@@ -7154,210 +7405,6 @@ ${c2}
|
|
|
7154
7405
|
} }).prompt();
|
|
7155
7406
|
}
|
|
7156
7407
|
});
|
|
7157
|
-
function aiContextBody() {
|
|
7158
|
-
return `## keynv (secrets)
|
|
7159
|
-
|
|
7160
|
-
This project uses [keynv](https://keynv.dev) for secrets. There is a \`.keynv.env\` file at the project root containing **alias references** like \`OPENAI_API_KEY=@projectname.dev.openai-key\` \u2014 these are NOT real values, they are references to secrets stored in the keynv vault.
|
|
7161
|
-
|
|
7162
|
-
### Mental model
|
|
7163
|
-
|
|
7164
|
-
- **\`.keynv.env\`** \u2014 checked into git, contains aliases. Safe to read, edit, commit.
|
|
7165
|
-
- **Vault** \u2014 holds the real values. The \`keynv\` CLI reads it on demand.
|
|
7166
|
-
- **\`keynv exec -- <command>\`** \u2014 forks the command in a subprocess where the real values are injected into env vars. The parent process (where you, the AI agent, run) NEVER sees the real values.
|
|
7167
|
-
- **Redactor** \u2014 pipes subprocess stdout/stderr through a masker before they reach this terminal. Even if a script accidentally echoes a secret, you see \`<REDACTED:...>\` here.
|
|
7168
|
-
|
|
7169
|
-
### What you should do
|
|
7170
|
-
|
|
7171
|
-
When the user asks about secrets or env vars, follow this decision tree:
|
|
7172
|
-
|
|
7173
|
-
| User intent | Run / suggest |
|
|
7174
|
-
|---|---|
|
|
7175
|
-
| "Add a new API key" / "set up a secret" | \`keynv secret create\` (interactive prompt picks project + env + key) |
|
|
7176
|
-
| "I have a \`.env\`, migrate it" | \`keynv init\` (you're seeing this file because that already happened) |
|
|
7177
|
-
| "Run the app / dev server / tests" | \`keynv exec -- <their existing command>\` (auto-loads \`.keynv.env\`) |
|
|
7178
|
-
| "Show me the value of X" | \`keynv secret get @alias\` \u2014 but copy to clipboard, do NOT print the value into chat / terminal |
|
|
7179
|
-
| "Rotate this key" | \`keynv secret rotate @alias\` |
|
|
7180
|
-
| "Add a new env var to the project" | Edit \`.keynv.env\` and add \`NAME=@project.env.key\` (after creating the secret with \`keynv secret create\`) |
|
|
7181
|
-
| "Who has access?" | \`keynv member list <project>\` |
|
|
7182
|
-
|
|
7183
|
-
### Hard rules \u2014 do not violate
|
|
7184
|
-
|
|
7185
|
-
1. **Never print resolved secret values** to the chat, terminal, log, or any file. The user's editor / scrollback / chat history is an attack surface.
|
|
7186
|
-
2. **Never write a \`.env\` file** (or any file) containing real secret values. The whole point of keynv is that those don't exist on disk.
|
|
7187
|
-
3. **Never edit \`.keynv.env\` to substitute resolved values for aliases.** The file should only ever contain \`@project.env.key\` references and plain non-secret literals.
|
|
7188
|
-
4. **Use \`keynv exec --\` to run commands that need env vars.** Don't try to load \`.keynv.env\` yourself by parsing it manually; the wrapper handles resolution + redaction + subprocess isolation.
|
|
7189
|
-
5. **If a tool fails with "blocked by keynv-guard" or similar**, do NOT try to work around it. Tell the user \u2014 that's a sign of a misconfiguration, not an obstacle to bypass.
|
|
7190
|
-
6. **Treat the alias literal (\`@project.env.key\`) as the canonical reference**, never the resolved value. When you write code, configs, or commands that need a secret, write the alias.
|
|
7191
|
-
|
|
7192
|
-
### Quick reference
|
|
7193
|
-
|
|
7194
|
-
\`\`\`bash
|
|
7195
|
-
keynv # interactive TUI menu (pick projects, secrets, members)
|
|
7196
|
-
keynv exec -- <cmd> # run cmd with .keynv.env loaded
|
|
7197
|
-
keynv secret create # walk through creating a new secret
|
|
7198
|
-
keynv secret list <project> # list aliases (no values)
|
|
7199
|
-
keynv whoami # who am I logged in as
|
|
7200
|
-
keynv --help # full command list
|
|
7201
|
-
\`\`\`
|
|
7202
|
-
|
|
7203
|
-
If \`.keynv.env\` is missing or empty, the user probably hasn't run \`keynv init\` yet \u2014 suggest they do so before they paste a secret into a \`.env\`.`;
|
|
7204
|
-
}
|
|
7205
|
-
function renderKeynvBlock() {
|
|
7206
|
-
return `${KEYNV_BLOCK_START}
|
|
7207
|
-
${aiContextBody()}
|
|
7208
|
-
${KEYNV_BLOCK_END}`;
|
|
7209
|
-
}
|
|
7210
|
-
function writeAiContext(rootPath) {
|
|
7211
|
-
const path = join(rootPath, AGENTS_FILE_BASENAME);
|
|
7212
|
-
const block = renderKeynvBlock();
|
|
7213
|
-
if (!existsSync(path)) {
|
|
7214
|
-
const initial = `# Agent guidance for this project
|
|
7215
|
-
|
|
7216
|
-
${block}
|
|
7217
|
-
`;
|
|
7218
|
-
writeFileSync(path, initial);
|
|
7219
|
-
return "created";
|
|
7220
|
-
}
|
|
7221
|
-
const existing = readFileSync(path, "utf8");
|
|
7222
|
-
const startIdx = existing.indexOf(KEYNV_BLOCK_START);
|
|
7223
|
-
const endIdx = existing.indexOf(KEYNV_BLOCK_END);
|
|
7224
|
-
if (startIdx >= 0 && endIdx > startIdx) {
|
|
7225
|
-
const before = existing.slice(0, startIdx);
|
|
7226
|
-
const after = existing.slice(endIdx + KEYNV_BLOCK_END.length);
|
|
7227
|
-
const next = `${before}${block}${after}`;
|
|
7228
|
-
if (next === existing) return "unchanged";
|
|
7229
|
-
writeFileSync(path, next);
|
|
7230
|
-
return "updated";
|
|
7231
|
-
}
|
|
7232
|
-
const sep = existing.length === 0 ? "" : existing.endsWith("\n\n") ? "" : existing.endsWith("\n") ? "\n" : "\n\n";
|
|
7233
|
-
const trailingNewline = existing.endsWith("\n") ? "" : "\n";
|
|
7234
|
-
writeFileSync(path, `${existing}${trailingNewline}${sep}${block}
|
|
7235
|
-
`);
|
|
7236
|
-
return "appended";
|
|
7237
|
-
}
|
|
7238
|
-
var AGENTS_FILE_BASENAME, KEYNV_BLOCK_START, KEYNV_BLOCK_END;
|
|
7239
|
-
var init_aiContext = __esm({
|
|
7240
|
-
"src/init/aiContext.ts"() {
|
|
7241
|
-
AGENTS_FILE_BASENAME = "AGENTS.md";
|
|
7242
|
-
KEYNV_BLOCK_START = "<!-- keynv:start -- generated by `keynv init`; safe to leave intact, will be refreshed on re-run -->";
|
|
7243
|
-
KEYNV_BLOCK_END = "<!-- keynv:end -->";
|
|
7244
|
-
}
|
|
7245
|
-
});
|
|
7246
|
-
function findProjectRoot(startDir) {
|
|
7247
|
-
const result = walkUp(startDir, (dir) => {
|
|
7248
|
-
for (const marker of PROJECT_MARKERS) {
|
|
7249
|
-
if (existsSync(join(dir, marker))) {
|
|
7250
|
-
return { dir, marker };
|
|
7251
|
-
}
|
|
7252
|
-
}
|
|
7253
|
-
if (existsSync(join(dir, GIT_MARKER))) {
|
|
7254
|
-
return { dir, marker: GIT_MARKER };
|
|
7255
|
-
}
|
|
7256
|
-
return null;
|
|
7257
|
-
});
|
|
7258
|
-
if (!result) return null;
|
|
7259
|
-
return buildRoot(result.dir, result.marker);
|
|
7260
|
-
}
|
|
7261
|
-
function buildRoot(dir, marker) {
|
|
7262
|
-
let suggestedName = basename(dir);
|
|
7263
|
-
let scripts = null;
|
|
7264
|
-
let invalid = false;
|
|
7265
|
-
if (marker === "package.json" || existsSync(join(dir, "package.json"))) {
|
|
7266
|
-
try {
|
|
7267
|
-
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
7268
|
-
if (typeof pkg.name === "string" && pkg.name.length > 0) {
|
|
7269
|
-
suggestedName = pkg.name.replace(/^@[^/]+\//, "");
|
|
7270
|
-
}
|
|
7271
|
-
if (pkg.scripts && typeof pkg.scripts === "object") {
|
|
7272
|
-
scripts = Object.fromEntries(
|
|
7273
|
-
Object.entries(pkg.scripts).filter(([, v2]) => typeof v2 === "string")
|
|
7274
|
-
);
|
|
7275
|
-
}
|
|
7276
|
-
} catch {
|
|
7277
|
-
invalid = true;
|
|
7278
|
-
}
|
|
7279
|
-
}
|
|
7280
|
-
return {
|
|
7281
|
-
path: dir,
|
|
7282
|
-
suggestedName,
|
|
7283
|
-
marker,
|
|
7284
|
-
packageJsonScripts: scripts,
|
|
7285
|
-
packageJsonInvalid: invalid
|
|
7286
|
-
};
|
|
7287
|
-
}
|
|
7288
|
-
function findEnvFiles(rootDir) {
|
|
7289
|
-
let entries;
|
|
7290
|
-
try {
|
|
7291
|
-
entries = readdirSync(rootDir);
|
|
7292
|
-
} catch {
|
|
7293
|
-
return [];
|
|
7294
|
-
}
|
|
7295
|
-
const hits = [];
|
|
7296
|
-
for (const name of entries) {
|
|
7297
|
-
if (!ENV_GLOB.test(name)) continue;
|
|
7298
|
-
if (ENV_EXAMPLE.test(name)) continue;
|
|
7299
|
-
if (name === KEYNV_ENV_BASENAME) continue;
|
|
7300
|
-
const full = join(rootDir, name);
|
|
7301
|
-
try {
|
|
7302
|
-
if (!statSync(full).isFile()) continue;
|
|
7303
|
-
} catch {
|
|
7304
|
-
continue;
|
|
7305
|
-
}
|
|
7306
|
-
const suffixMatch = name.match(/^\.env\.(.+)$/);
|
|
7307
|
-
const suffix = suffixMatch ? suffixMatch[1] : null;
|
|
7308
|
-
hits.push({ path: full, name, suffix, suggestedEnv: suggestedEnvForSuffix(suffix) });
|
|
7309
|
-
}
|
|
7310
|
-
hits.sort((a, b2) => {
|
|
7311
|
-
if (a.suffix === null) return -1;
|
|
7312
|
-
if (b2.suffix === null) return 1;
|
|
7313
|
-
return a.name.localeCompare(b2.name);
|
|
7314
|
-
});
|
|
7315
|
-
return hits;
|
|
7316
|
-
}
|
|
7317
|
-
function suggestedEnvForSuffix(suffix) {
|
|
7318
|
-
if (suffix === null) return "dev";
|
|
7319
|
-
switch (suffix) {
|
|
7320
|
-
case "local":
|
|
7321
|
-
case "development":
|
|
7322
|
-
case "dev":
|
|
7323
|
-
return "dev";
|
|
7324
|
-
case "production":
|
|
7325
|
-
case "prod":
|
|
7326
|
-
return "prod";
|
|
7327
|
-
case "staging":
|
|
7328
|
-
case "stage":
|
|
7329
|
-
return "staging";
|
|
7330
|
-
case "test":
|
|
7331
|
-
return "test";
|
|
7332
|
-
case "preview":
|
|
7333
|
-
return "preview";
|
|
7334
|
-
default:
|
|
7335
|
-
return suffix;
|
|
7336
|
-
}
|
|
7337
|
-
}
|
|
7338
|
-
function hasExistingKeynvEnv(rootDir) {
|
|
7339
|
-
return existsSync(join(rootDir, KEYNV_ENV_BASENAME));
|
|
7340
|
-
}
|
|
7341
|
-
var PROJECT_MARKERS, GIT_MARKER, ENV_GLOB, ENV_EXAMPLE, KEYNV_ENV_BASENAME;
|
|
7342
|
-
var init_detect = __esm({
|
|
7343
|
-
"src/init/detect.ts"() {
|
|
7344
|
-
init_fs();
|
|
7345
|
-
PROJECT_MARKERS = [
|
|
7346
|
-
"package.json",
|
|
7347
|
-
"pyproject.toml",
|
|
7348
|
-
"Cargo.toml",
|
|
7349
|
-
"go.mod",
|
|
7350
|
-
"pnpm-workspace.yaml",
|
|
7351
|
-
"deno.json",
|
|
7352
|
-
"deno.jsonc",
|
|
7353
|
-
"requirements.txt"
|
|
7354
|
-
];
|
|
7355
|
-
GIT_MARKER = ".git";
|
|
7356
|
-
ENV_GLOB = /^\.env(\.[A-Za-z0-9_-]+)?$/;
|
|
7357
|
-
ENV_EXAMPLE = /^\.env\.(example|sample|template|dist|defaults)$/;
|
|
7358
|
-
KEYNV_ENV_BASENAME = ".keynv.env";
|
|
7359
|
-
}
|
|
7360
|
-
});
|
|
7361
7408
|
|
|
7362
7409
|
// src/init/scriptWrap.ts
|
|
7363
7410
|
function analyzeScript(name, command) {
|
|
@@ -7578,6 +7625,14 @@ __export(init_exports, {
|
|
|
7578
7625
|
UserCancelled: () => UserCancelled,
|
|
7579
7626
|
runInitFlow: () => runInitFlow
|
|
7580
7627
|
});
|
|
7628
|
+
function toAliasKey(name) {
|
|
7629
|
+
if (!name) return name;
|
|
7630
|
+
const KEY_RE3 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
|
|
7631
|
+
if (KEY_RE3.test(name)) return name;
|
|
7632
|
+
const normalised = name.toLowerCase().replace(/_/g, "-");
|
|
7633
|
+
if (KEY_RE3.test(normalised)) return normalised;
|
|
7634
|
+
return normalised.replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 64) || "key";
|
|
7635
|
+
}
|
|
7581
7636
|
async function runInitFlow(client, opts) {
|
|
7582
7637
|
ge("keynv init");
|
|
7583
7638
|
const root = findProjectRoot(opts.cwd);
|
|
@@ -7736,7 +7791,7 @@ ${detail}`
|
|
|
7736
7791
|
if (!selected.has(`${env2}|${e2.name}`)) continue;
|
|
7737
7792
|
i++;
|
|
7738
7793
|
s.message(`Uploading (${i}/${totalToUpload}) [${env2}] ${e2.name}`);
|
|
7739
|
-
const aliasKey = e2.name
|
|
7794
|
+
const aliasKey = toAliasKey(e2.name);
|
|
7740
7795
|
try {
|
|
7741
7796
|
await client.request(`/v1/projects/${projectId2}/secrets`, {
|
|
7742
7797
|
method: "POST",
|
|
@@ -7794,6 +7849,30 @@ ${detail}`
|
|
|
7794
7849
|
R2.error(`Failed to write .keynv.env: ${err instanceof Error ? err.message : String(err)}`);
|
|
7795
7850
|
return { exitCode: 1 };
|
|
7796
7851
|
}
|
|
7852
|
+
const otherEnvsWithAliases = distinctEnvs.filter(
|
|
7853
|
+
(env2) => env2 !== defaultEnv && (uploadedByEnv.get(env2)?.size ?? 0) > 0
|
|
7854
|
+
);
|
|
7855
|
+
for (const env2 of otherEnvsWithAliases) {
|
|
7856
|
+
const envUploaded = uploadedByEnv.get(env2) ?? /* @__PURE__ */ new Map();
|
|
7857
|
+
const envLiterals = (perEnv.get(env2) ?? []).filter((e2) => !selected.has(`${env2}|${e2.name}`));
|
|
7858
|
+
const envFilePath = join(root.path, `.keynv.${env2}.env`);
|
|
7859
|
+
try {
|
|
7860
|
+
const lines = composeKeynvEnv({
|
|
7861
|
+
uploadedAliases: envUploaded,
|
|
7862
|
+
literals: envLiterals,
|
|
7863
|
+
mergeWithExisting: null
|
|
7864
|
+
});
|
|
7865
|
+
writeFileSync(envFilePath, `${lines.join("\n")}
|
|
7866
|
+
`);
|
|
7867
|
+
R2.success(
|
|
7868
|
+
`Wrote .keynv.${env2}.env (${envUploaded.size} secret alias${envUploaded.size === 1 ? "" : "es"} from "${env2}")`
|
|
7869
|
+
);
|
|
7870
|
+
} catch (err) {
|
|
7871
|
+
R2.warn(
|
|
7872
|
+
`Could not write .keynv.${env2}.env: ${err instanceof Error ? err.message : String(err)}`
|
|
7873
|
+
);
|
|
7874
|
+
}
|
|
7875
|
+
}
|
|
7797
7876
|
try {
|
|
7798
7877
|
const outcome = writeAiContext(root.path);
|
|
7799
7878
|
if (outcome === "created") R2.success("Wrote AGENTS.md (so AI agents understand keynv)");
|
|
@@ -7830,7 +7909,8 @@ ${detail}`
|
|
|
7830
7909
|
if (otherEnvs.length > 0) {
|
|
7831
7910
|
const lines = otherEnvs.map((env2) => {
|
|
7832
7911
|
const count = uploadedByEnv.get(env2)?.size ?? 0;
|
|
7833
|
-
|
|
7912
|
+
const hasFile = count > 0;
|
|
7913
|
+
return hasFile ? ` ${env2}: ${count} secret${count === 1 ? "" : "s"} \u2192 .keynv.${env2}.env (use \`keynv exec --from .keynv.${env2}.env -- <cmd>\`)` : ` ${env2}: 0 secrets in vault (no alias file written)`;
|
|
7834
7914
|
});
|
|
7835
7915
|
Se(lines.join("\n"), "Secrets in other envs");
|
|
7836
7916
|
}
|
|
@@ -8080,7 +8160,7 @@ var init_tty = __esm({
|
|
|
8080
8160
|
}
|
|
8081
8161
|
});
|
|
8082
8162
|
function sleep(ms) {
|
|
8083
|
-
return new Promise((
|
|
8163
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
8084
8164
|
}
|
|
8085
8165
|
async function errorMessage(res, fallback) {
|
|
8086
8166
|
const text = await res.text();
|
|
@@ -8322,16 +8402,16 @@ async function runSecretMenu(client, project, alias2) {
|
|
|
8322
8402
|
async function copyToClipboard(value) {
|
|
8323
8403
|
const platform2 = process.platform;
|
|
8324
8404
|
const cmd = platform2 === "darwin" ? ["pbcopy", []] : platform2 === "win32" ? ["clip", []] : ["xclip", ["-selection", "clipboard"]];
|
|
8325
|
-
return new Promise((
|
|
8405
|
+
return new Promise((resolve4) => {
|
|
8326
8406
|
try {
|
|
8327
8407
|
const child = spawn(cmd[0], cmd[1], {
|
|
8328
8408
|
stdio: ["pipe", "ignore", "ignore"]
|
|
8329
8409
|
});
|
|
8330
|
-
child.on("error", () =>
|
|
8331
|
-
child.on("exit", (code) =>
|
|
8410
|
+
child.on("error", () => resolve4(false));
|
|
8411
|
+
child.on("exit", (code) => resolve4(code === 0));
|
|
8332
8412
|
child.stdin.end(value);
|
|
8333
8413
|
} catch {
|
|
8334
|
-
|
|
8414
|
+
resolve4(false);
|
|
8335
8415
|
}
|
|
8336
8416
|
});
|
|
8337
8417
|
}
|
|
@@ -25077,7 +25157,7 @@ var require_named_placeholders = __commonJS({
|
|
|
25077
25157
|
}
|
|
25078
25158
|
return s;
|
|
25079
25159
|
}
|
|
25080
|
-
function
|
|
25160
|
+
function join8(tree) {
|
|
25081
25161
|
if (tree.length === 1) {
|
|
25082
25162
|
return tree;
|
|
25083
25163
|
}
|
|
@@ -25103,7 +25183,7 @@ var require_named_placeholders = __commonJS({
|
|
|
25103
25183
|
if (cache2 && (tree = cache2.get(query))) {
|
|
25104
25184
|
return toArrayParams(tree, paramsObj);
|
|
25105
25185
|
}
|
|
25106
|
-
tree =
|
|
25186
|
+
tree = join8(parse(query));
|
|
25107
25187
|
if (cache2) {
|
|
25108
25188
|
cache2.set(query, tree);
|
|
25109
25189
|
}
|
|
@@ -25259,11 +25339,11 @@ var require_connection = __commonJS({
|
|
|
25259
25339
|
const config = this.config;
|
|
25260
25340
|
tracePromise(
|
|
25261
25341
|
connectChannel,
|
|
25262
|
-
() => new Promise((
|
|
25342
|
+
() => new Promise((resolve4, reject) => {
|
|
25263
25343
|
let onConnect, onError;
|
|
25264
25344
|
onConnect = (param) => {
|
|
25265
25345
|
this.removeListener("error", onError);
|
|
25266
|
-
|
|
25346
|
+
resolve4(param);
|
|
25267
25347
|
};
|
|
25268
25348
|
onError = (err) => {
|
|
25269
25349
|
this.removeListener("connect", onConnect);
|
|
@@ -25688,9 +25768,9 @@ var require_connection = __commonJS({
|
|
|
25688
25768
|
} else if (shouldTrace(queryChannel)) {
|
|
25689
25769
|
tracePromise(
|
|
25690
25770
|
queryChannel,
|
|
25691
|
-
() => new Promise((
|
|
25771
|
+
() => new Promise((resolve4, reject) => {
|
|
25692
25772
|
cmdQuery.once("error", reject);
|
|
25693
|
-
cmdQuery.once("end", () =>
|
|
25773
|
+
cmdQuery.once("end", () => resolve4());
|
|
25694
25774
|
this.addCommand(cmdQuery);
|
|
25695
25775
|
}),
|
|
25696
25776
|
() => {
|
|
@@ -25837,12 +25917,12 @@ var require_connection = __commonJS({
|
|
|
25837
25917
|
} else if (shouldTrace(executeChannel)) {
|
|
25838
25918
|
tracePromise(
|
|
25839
25919
|
executeChannel,
|
|
25840
|
-
() => new Promise((
|
|
25920
|
+
() => new Promise((resolve4, reject) => {
|
|
25841
25921
|
prepareAndExecute((err) => {
|
|
25842
25922
|
executeCommand.emit("error", err);
|
|
25843
25923
|
});
|
|
25844
25924
|
executeCommand.once("error", reject);
|
|
25845
|
-
executeCommand.once("end", () =>
|
|
25925
|
+
executeCommand.once("end", () => resolve4());
|
|
25846
25926
|
}),
|
|
25847
25927
|
() => {
|
|
25848
25928
|
const server = getServerContext(this.config);
|
|
@@ -26107,13 +26187,13 @@ var require_capture_local_err = __commonJS({
|
|
|
26107
26187
|
var require_make_done_cb = __commonJS({
|
|
26108
26188
|
"../../node_modules/.pnpm/mysql2@3.22.3_@types+node@24.12.3/node_modules/mysql2/lib/promise/make_done_cb.js"(exports, module) {
|
|
26109
26189
|
var { applyCapturedStack } = require_capture_local_err();
|
|
26110
|
-
function makeDoneCb(
|
|
26190
|
+
function makeDoneCb(resolve4, reject, stackHolder) {
|
|
26111
26191
|
return function(err, rows, fields) {
|
|
26112
26192
|
if (err) {
|
|
26113
26193
|
applyCapturedStack(err, stackHolder);
|
|
26114
26194
|
reject(err);
|
|
26115
26195
|
} else {
|
|
26116
|
-
|
|
26196
|
+
resolve4([rows, fields]);
|
|
26117
26197
|
}
|
|
26118
26198
|
};
|
|
26119
26199
|
}
|
|
@@ -26136,8 +26216,8 @@ var require_prepared_statement_info = __commonJS({
|
|
|
26136
26216
|
const stackHolder = captureStackHolder(
|
|
26137
26217
|
_PromisePreparedStatementInfo.prototype.execute
|
|
26138
26218
|
);
|
|
26139
|
-
return new this.Promise((
|
|
26140
|
-
const done = makeDoneCb(
|
|
26219
|
+
return new this.Promise((resolve4, reject) => {
|
|
26220
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26141
26221
|
if (parameters) {
|
|
26142
26222
|
s.execute(parameters, done);
|
|
26143
26223
|
} else {
|
|
@@ -26146,9 +26226,9 @@ var require_prepared_statement_info = __commonJS({
|
|
|
26146
26226
|
});
|
|
26147
26227
|
}
|
|
26148
26228
|
close() {
|
|
26149
|
-
return new this.Promise((
|
|
26229
|
+
return new this.Promise((resolve4) => {
|
|
26150
26230
|
this.statement.close();
|
|
26151
|
-
|
|
26231
|
+
resolve4();
|
|
26152
26232
|
});
|
|
26153
26233
|
}
|
|
26154
26234
|
};
|
|
@@ -26219,8 +26299,8 @@ var require_connection2 = __commonJS({
|
|
|
26219
26299
|
"Callback function is not available with promise clients."
|
|
26220
26300
|
);
|
|
26221
26301
|
}
|
|
26222
|
-
return new this.Promise((
|
|
26223
|
-
const done = makeDoneCb(
|
|
26302
|
+
return new this.Promise((resolve4, reject) => {
|
|
26303
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26224
26304
|
if (params !== void 0) {
|
|
26225
26305
|
c2.query(query, params, done);
|
|
26226
26306
|
} else {
|
|
@@ -26236,8 +26316,8 @@ var require_connection2 = __commonJS({
|
|
|
26236
26316
|
"Callback function is not available with promise clients."
|
|
26237
26317
|
);
|
|
26238
26318
|
}
|
|
26239
|
-
return new this.Promise((
|
|
26240
|
-
const done = makeDoneCb(
|
|
26319
|
+
return new this.Promise((resolve4, reject) => {
|
|
26320
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26241
26321
|
if (params !== void 0) {
|
|
26242
26322
|
c2.execute(query, params, done);
|
|
26243
26323
|
} else {
|
|
@@ -26246,8 +26326,8 @@ var require_connection2 = __commonJS({
|
|
|
26246
26326
|
});
|
|
26247
26327
|
}
|
|
26248
26328
|
end() {
|
|
26249
|
-
return new this.Promise((
|
|
26250
|
-
this.connection.end(
|
|
26329
|
+
return new this.Promise((resolve4) => {
|
|
26330
|
+
this.connection.end(resolve4);
|
|
26251
26331
|
});
|
|
26252
26332
|
}
|
|
26253
26333
|
async [Symbol.asyncDispose]() {
|
|
@@ -26260,16 +26340,16 @@ var require_connection2 = __commonJS({
|
|
|
26260
26340
|
const stackHolder = captureStackHolder(
|
|
26261
26341
|
_PromiseConnection.prototype.beginTransaction
|
|
26262
26342
|
);
|
|
26263
|
-
return new this.Promise((
|
|
26264
|
-
const done = makeDoneCb(
|
|
26343
|
+
return new this.Promise((resolve4, reject) => {
|
|
26344
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26265
26345
|
c2.beginTransaction(done);
|
|
26266
26346
|
});
|
|
26267
26347
|
}
|
|
26268
26348
|
commit() {
|
|
26269
26349
|
const c2 = this.connection;
|
|
26270
26350
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.commit);
|
|
26271
|
-
return new this.Promise((
|
|
26272
|
-
const done = makeDoneCb(
|
|
26351
|
+
return new this.Promise((resolve4, reject) => {
|
|
26352
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26273
26353
|
c2.commit(done);
|
|
26274
26354
|
});
|
|
26275
26355
|
}
|
|
@@ -26278,21 +26358,21 @@ var require_connection2 = __commonJS({
|
|
|
26278
26358
|
const stackHolder = captureStackHolder(
|
|
26279
26359
|
_PromiseConnection.prototype.rollback
|
|
26280
26360
|
);
|
|
26281
|
-
return new this.Promise((
|
|
26282
|
-
const done = makeDoneCb(
|
|
26361
|
+
return new this.Promise((resolve4, reject) => {
|
|
26362
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26283
26363
|
c2.rollback(done);
|
|
26284
26364
|
});
|
|
26285
26365
|
}
|
|
26286
26366
|
ping() {
|
|
26287
26367
|
const c2 = this.connection;
|
|
26288
26368
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.ping);
|
|
26289
|
-
return new this.Promise((
|
|
26369
|
+
return new this.Promise((resolve4, reject) => {
|
|
26290
26370
|
c2.ping((err) => {
|
|
26291
26371
|
if (err) {
|
|
26292
26372
|
applyCapturedStack(err, stackHolder);
|
|
26293
26373
|
reject(err);
|
|
26294
26374
|
} else {
|
|
26295
|
-
|
|
26375
|
+
resolve4(true);
|
|
26296
26376
|
}
|
|
26297
26377
|
});
|
|
26298
26378
|
});
|
|
@@ -26300,13 +26380,13 @@ var require_connection2 = __commonJS({
|
|
|
26300
26380
|
reset() {
|
|
26301
26381
|
const c2 = this.connection;
|
|
26302
26382
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.reset);
|
|
26303
|
-
return new this.Promise((
|
|
26383
|
+
return new this.Promise((resolve4, reject) => {
|
|
26304
26384
|
c2.reset((err) => {
|
|
26305
26385
|
if (err) {
|
|
26306
26386
|
applyCapturedStack(err, stackHolder);
|
|
26307
26387
|
reject(err);
|
|
26308
26388
|
} else {
|
|
26309
|
-
|
|
26389
|
+
resolve4();
|
|
26310
26390
|
}
|
|
26311
26391
|
});
|
|
26312
26392
|
});
|
|
@@ -26314,13 +26394,13 @@ var require_connection2 = __commonJS({
|
|
|
26314
26394
|
connect() {
|
|
26315
26395
|
const c2 = this.connection;
|
|
26316
26396
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.connect);
|
|
26317
|
-
return new this.Promise((
|
|
26397
|
+
return new this.Promise((resolve4, reject) => {
|
|
26318
26398
|
c2.connect((err, param) => {
|
|
26319
26399
|
if (err) {
|
|
26320
26400
|
applyCapturedStack(err, stackHolder);
|
|
26321
26401
|
reject(err);
|
|
26322
26402
|
} else {
|
|
26323
|
-
|
|
26403
|
+
resolve4(param);
|
|
26324
26404
|
}
|
|
26325
26405
|
});
|
|
26326
26406
|
});
|
|
@@ -26329,7 +26409,7 @@ var require_connection2 = __commonJS({
|
|
|
26329
26409
|
const c2 = this.connection;
|
|
26330
26410
|
const promiseImpl = this.Promise;
|
|
26331
26411
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.prepare);
|
|
26332
|
-
return new this.Promise((
|
|
26412
|
+
return new this.Promise((resolve4, reject) => {
|
|
26333
26413
|
c2.prepare(options, (err, statement) => {
|
|
26334
26414
|
if (err) {
|
|
26335
26415
|
applyCapturedStack(err, stackHolder);
|
|
@@ -26339,7 +26419,7 @@ var require_connection2 = __commonJS({
|
|
|
26339
26419
|
statement,
|
|
26340
26420
|
promiseImpl
|
|
26341
26421
|
);
|
|
26342
|
-
|
|
26422
|
+
resolve4(wrappedStatement);
|
|
26343
26423
|
}
|
|
26344
26424
|
});
|
|
26345
26425
|
});
|
|
@@ -26349,13 +26429,13 @@ var require_connection2 = __commonJS({
|
|
|
26349
26429
|
const stackHolder = captureStackHolder(
|
|
26350
26430
|
_PromiseConnection.prototype.changeUser
|
|
26351
26431
|
);
|
|
26352
|
-
return new this.Promise((
|
|
26432
|
+
return new this.Promise((resolve4, reject) => {
|
|
26353
26433
|
c2.changeUser(options, (err) => {
|
|
26354
26434
|
if (err) {
|
|
26355
26435
|
applyCapturedStack(err, stackHolder);
|
|
26356
26436
|
reject(err);
|
|
26357
26437
|
} else {
|
|
26358
|
-
|
|
26438
|
+
resolve4();
|
|
26359
26439
|
}
|
|
26360
26440
|
});
|
|
26361
26441
|
});
|
|
@@ -26817,12 +26897,12 @@ var require_pool2 = __commonJS({
|
|
|
26817
26897
|
}
|
|
26818
26898
|
getConnection() {
|
|
26819
26899
|
const corePool = this.pool;
|
|
26820
|
-
return new this.Promise((
|
|
26900
|
+
return new this.Promise((resolve4, reject) => {
|
|
26821
26901
|
corePool.getConnection((err, coreConnection) => {
|
|
26822
26902
|
if (err) {
|
|
26823
26903
|
reject(err);
|
|
26824
26904
|
} else {
|
|
26825
|
-
|
|
26905
|
+
resolve4(new PromisePoolConnection(coreConnection, this.Promise));
|
|
26826
26906
|
}
|
|
26827
26907
|
});
|
|
26828
26908
|
});
|
|
@@ -26838,8 +26918,8 @@ var require_pool2 = __commonJS({
|
|
|
26838
26918
|
"Callback function is not available with promise clients."
|
|
26839
26919
|
);
|
|
26840
26920
|
}
|
|
26841
|
-
return new this.Promise((
|
|
26842
|
-
const done = makeDoneCb(
|
|
26921
|
+
return new this.Promise((resolve4, reject) => {
|
|
26922
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26843
26923
|
if (args !== void 0) {
|
|
26844
26924
|
corePool.query(sql, args, done);
|
|
26845
26925
|
} else {
|
|
@@ -26855,8 +26935,8 @@ var require_pool2 = __commonJS({
|
|
|
26855
26935
|
"Callback function is not available with promise clients."
|
|
26856
26936
|
);
|
|
26857
26937
|
}
|
|
26858
|
-
return new this.Promise((
|
|
26859
|
-
const done = makeDoneCb(
|
|
26938
|
+
return new this.Promise((resolve4, reject) => {
|
|
26939
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26860
26940
|
if (args) {
|
|
26861
26941
|
corePool.execute(sql, args, done);
|
|
26862
26942
|
} else {
|
|
@@ -26867,13 +26947,13 @@ var require_pool2 = __commonJS({
|
|
|
26867
26947
|
end() {
|
|
26868
26948
|
const corePool = this.pool;
|
|
26869
26949
|
const stackHolder = captureStackHolder(_PromisePool.prototype.end);
|
|
26870
|
-
return new this.Promise((
|
|
26950
|
+
return new this.Promise((resolve4, reject) => {
|
|
26871
26951
|
corePool.end((err) => {
|
|
26872
26952
|
if (err) {
|
|
26873
26953
|
applyCapturedStack(err, stackHolder);
|
|
26874
26954
|
reject(err);
|
|
26875
26955
|
} else {
|
|
26876
|
-
|
|
26956
|
+
resolve4();
|
|
26877
26957
|
}
|
|
26878
26958
|
});
|
|
26879
26959
|
});
|
|
@@ -27298,12 +27378,12 @@ var require_pool_cluster2 = __commonJS({
|
|
|
27298
27378
|
}
|
|
27299
27379
|
getConnection() {
|
|
27300
27380
|
const corePoolNamespace = this.poolNamespace;
|
|
27301
|
-
return new this.Promise((
|
|
27381
|
+
return new this.Promise((resolve4, reject) => {
|
|
27302
27382
|
corePoolNamespace.getConnection((err, coreConnection) => {
|
|
27303
27383
|
if (err) {
|
|
27304
27384
|
reject(err);
|
|
27305
27385
|
} else {
|
|
27306
|
-
|
|
27386
|
+
resolve4(new PromisePoolConnection(coreConnection, this.Promise));
|
|
27307
27387
|
}
|
|
27308
27388
|
});
|
|
27309
27389
|
});
|
|
@@ -27318,8 +27398,8 @@ var require_pool_cluster2 = __commonJS({
|
|
|
27318
27398
|
"Callback function is not available with promise clients."
|
|
27319
27399
|
);
|
|
27320
27400
|
}
|
|
27321
|
-
return new this.Promise((
|
|
27322
|
-
const done = makeDoneCb(
|
|
27401
|
+
return new this.Promise((resolve4, reject) => {
|
|
27402
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27323
27403
|
corePoolNamespace.query(sql, values, done);
|
|
27324
27404
|
});
|
|
27325
27405
|
}
|
|
@@ -27333,8 +27413,8 @@ var require_pool_cluster2 = __commonJS({
|
|
|
27333
27413
|
"Callback function is not available with promise clients."
|
|
27334
27414
|
);
|
|
27335
27415
|
}
|
|
27336
|
-
return new this.Promise((
|
|
27337
|
-
const done = makeDoneCb(
|
|
27416
|
+
return new this.Promise((resolve4, reject) => {
|
|
27417
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27338
27418
|
corePoolNamespace.execute(sql, values, done);
|
|
27339
27419
|
});
|
|
27340
27420
|
}
|
|
@@ -27372,9 +27452,9 @@ var require_promise = __commonJS({
|
|
|
27372
27452
|
"no Promise implementation available.Use promise-enabled node version or pass userland Promise implementation as parameter, for example: { Promise: require('bluebird') }"
|
|
27373
27453
|
);
|
|
27374
27454
|
}
|
|
27375
|
-
return new thePromise((
|
|
27455
|
+
return new thePromise((resolve4, reject) => {
|
|
27376
27456
|
coreConnection.once("connect", () => {
|
|
27377
|
-
|
|
27457
|
+
resolve4(new PromiseConnection(coreConnection, thePromise));
|
|
27378
27458
|
});
|
|
27379
27459
|
coreConnection.once("error", (err) => {
|
|
27380
27460
|
applyCapturedStack(err, stackHolder);
|
|
@@ -27401,7 +27481,7 @@ var require_promise = __commonJS({
|
|
|
27401
27481
|
}
|
|
27402
27482
|
getConnection(pattern, selector) {
|
|
27403
27483
|
const corePoolCluster = this.poolCluster;
|
|
27404
|
-
return new this.Promise((
|
|
27484
|
+
return new this.Promise((resolve4, reject) => {
|
|
27405
27485
|
corePoolCluster.getConnection(
|
|
27406
27486
|
pattern,
|
|
27407
27487
|
selector,
|
|
@@ -27409,7 +27489,7 @@ var require_promise = __commonJS({
|
|
|
27409
27489
|
if (err) {
|
|
27410
27490
|
reject(err);
|
|
27411
27491
|
} else {
|
|
27412
|
-
|
|
27492
|
+
resolve4(new PromisePoolConnection(coreConnection, this.Promise));
|
|
27413
27493
|
}
|
|
27414
27494
|
}
|
|
27415
27495
|
);
|
|
@@ -27423,8 +27503,8 @@ var require_promise = __commonJS({
|
|
|
27423
27503
|
"Callback function is not available with promise clients."
|
|
27424
27504
|
);
|
|
27425
27505
|
}
|
|
27426
|
-
return new this.Promise((
|
|
27427
|
-
const done = makeDoneCb(
|
|
27506
|
+
return new this.Promise((resolve4, reject) => {
|
|
27507
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27428
27508
|
corePoolCluster.query(sql, args, done);
|
|
27429
27509
|
});
|
|
27430
27510
|
}
|
|
@@ -27438,8 +27518,8 @@ var require_promise = __commonJS({
|
|
|
27438
27518
|
"Callback function is not available with promise clients."
|
|
27439
27519
|
);
|
|
27440
27520
|
}
|
|
27441
|
-
return new this.Promise((
|
|
27442
|
-
const done = makeDoneCb(
|
|
27521
|
+
return new this.Promise((resolve4, reject) => {
|
|
27522
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27443
27523
|
corePoolCluster.execute(sql, args, done);
|
|
27444
27524
|
});
|
|
27445
27525
|
}
|
|
@@ -27452,13 +27532,13 @@ var require_promise = __commonJS({
|
|
|
27452
27532
|
end() {
|
|
27453
27533
|
const corePoolCluster = this.poolCluster;
|
|
27454
27534
|
const stackHolder = captureStackHolder(_PromisePoolCluster.prototype.end);
|
|
27455
|
-
return new this.Promise((
|
|
27535
|
+
return new this.Promise((resolve4, reject) => {
|
|
27456
27536
|
corePoolCluster.end((err) => {
|
|
27457
27537
|
if (err) {
|
|
27458
27538
|
applyCapturedStack(err, stackHolder);
|
|
27459
27539
|
reject(err);
|
|
27460
27540
|
} else {
|
|
27461
|
-
|
|
27541
|
+
resolve4();
|
|
27462
27542
|
}
|
|
27463
27543
|
});
|
|
27464
27544
|
});
|
|
@@ -30533,7 +30613,7 @@ var require_dist = __commonJS({
|
|
|
30533
30613
|
function parse(stream, callback) {
|
|
30534
30614
|
const parser = new parser_1.Parser();
|
|
30535
30615
|
stream.on("data", (buffer) => parser.parse(buffer, callback));
|
|
30536
|
-
return new Promise((
|
|
30616
|
+
return new Promise((resolve4) => stream.on("end", () => resolve4()));
|
|
30537
30617
|
}
|
|
30538
30618
|
exports.parse = parse;
|
|
30539
30619
|
}
|
|
@@ -31258,12 +31338,12 @@ var require_client2 = __commonJS({
|
|
|
31258
31338
|
this._connect(callback);
|
|
31259
31339
|
return;
|
|
31260
31340
|
}
|
|
31261
|
-
return new this._Promise((
|
|
31341
|
+
return new this._Promise((resolve4, reject) => {
|
|
31262
31342
|
this._connect((error) => {
|
|
31263
31343
|
if (error) {
|
|
31264
31344
|
reject(error);
|
|
31265
31345
|
} else {
|
|
31266
|
-
|
|
31346
|
+
resolve4(this);
|
|
31267
31347
|
}
|
|
31268
31348
|
});
|
|
31269
31349
|
});
|
|
@@ -31609,8 +31689,8 @@ var require_client2 = __commonJS({
|
|
|
31609
31689
|
readTimeout = config.query_timeout || this.connectionParameters.query_timeout;
|
|
31610
31690
|
query = new Query2(config, values, callback);
|
|
31611
31691
|
if (!query.callback) {
|
|
31612
|
-
result = new this._Promise((
|
|
31613
|
-
query.callback = (err, res) => err ? reject(err) :
|
|
31692
|
+
result = new this._Promise((resolve4, reject) => {
|
|
31693
|
+
query.callback = (err, res) => err ? reject(err) : resolve4(res);
|
|
31614
31694
|
}).catch((err) => {
|
|
31615
31695
|
Error.captureStackTrace(err);
|
|
31616
31696
|
throw err;
|
|
@@ -31687,8 +31767,8 @@ var require_client2 = __commonJS({
|
|
|
31687
31767
|
if (cb) {
|
|
31688
31768
|
this.connection.once("end", cb);
|
|
31689
31769
|
} else {
|
|
31690
|
-
return new this._Promise((
|
|
31691
|
-
this.connection.once("end",
|
|
31770
|
+
return new this._Promise((resolve4) => {
|
|
31771
|
+
this.connection.once("end", resolve4);
|
|
31692
31772
|
});
|
|
31693
31773
|
}
|
|
31694
31774
|
}
|
|
@@ -31736,8 +31816,8 @@ var require_pg_pool = __commonJS({
|
|
|
31736
31816
|
const cb = function(err, client) {
|
|
31737
31817
|
err ? rej(err) : res(client);
|
|
31738
31818
|
};
|
|
31739
|
-
const result = new Promise2(function(
|
|
31740
|
-
res =
|
|
31819
|
+
const result = new Promise2(function(resolve4, reject) {
|
|
31820
|
+
res = resolve4;
|
|
31741
31821
|
rej = reject;
|
|
31742
31822
|
}).catch((err) => {
|
|
31743
31823
|
Error.captureStackTrace(err);
|
|
@@ -31798,7 +31878,7 @@ var require_pg_pool = __commonJS({
|
|
|
31798
31878
|
if (typeof Promise2.try === "function") {
|
|
31799
31879
|
return Promise2.try(f);
|
|
31800
31880
|
}
|
|
31801
|
-
return new Promise2((
|
|
31881
|
+
return new Promise2((resolve4) => resolve4(f()));
|
|
31802
31882
|
}
|
|
31803
31883
|
_isFull() {
|
|
31804
31884
|
return this._clients.length >= this.options.max;
|
|
@@ -32190,8 +32270,8 @@ var require_query4 = __commonJS({
|
|
|
32190
32270
|
NativeQuery.prototype._getPromise = function() {
|
|
32191
32271
|
if (this._promise) return this._promise;
|
|
32192
32272
|
this._promise = new Promise(
|
|
32193
|
-
function(
|
|
32194
|
-
this._once("end",
|
|
32273
|
+
function(resolve4, reject) {
|
|
32274
|
+
this._once("end", resolve4);
|
|
32195
32275
|
this._once("error", reject);
|
|
32196
32276
|
}.bind(this)
|
|
32197
32277
|
);
|
|
@@ -32368,12 +32448,12 @@ var require_client3 = __commonJS({
|
|
|
32368
32448
|
this._connect(callback);
|
|
32369
32449
|
return;
|
|
32370
32450
|
}
|
|
32371
|
-
return new this._Promise((
|
|
32451
|
+
return new this._Promise((resolve4, reject) => {
|
|
32372
32452
|
this._connect((error) => {
|
|
32373
32453
|
if (error) {
|
|
32374
32454
|
reject(error);
|
|
32375
32455
|
} else {
|
|
32376
|
-
|
|
32456
|
+
resolve4(this);
|
|
32377
32457
|
}
|
|
32378
32458
|
});
|
|
32379
32459
|
});
|
|
@@ -32397,8 +32477,8 @@ var require_client3 = __commonJS({
|
|
|
32397
32477
|
query = new NativeQuery(config, values, callback);
|
|
32398
32478
|
if (!query.callback) {
|
|
32399
32479
|
let resolveOut, rejectOut;
|
|
32400
|
-
result = new this._Promise((
|
|
32401
|
-
resolveOut =
|
|
32480
|
+
result = new this._Promise((resolve4, reject) => {
|
|
32481
|
+
resolveOut = resolve4;
|
|
32402
32482
|
rejectOut = reject;
|
|
32403
32483
|
}).catch((err) => {
|
|
32404
32484
|
Error.captureStackTrace(err);
|
|
@@ -32458,8 +32538,8 @@ var require_client3 = __commonJS({
|
|
|
32458
32538
|
}
|
|
32459
32539
|
let result;
|
|
32460
32540
|
if (!cb) {
|
|
32461
|
-
result = new this._Promise(function(
|
|
32462
|
-
cb = (err) => err ? reject(err) :
|
|
32541
|
+
result = new this._Promise(function(resolve4, reject) {
|
|
32542
|
+
cb = (err) => err ? reject(err) : resolve4();
|
|
32463
32543
|
});
|
|
32464
32544
|
}
|
|
32465
32545
|
this.native.end(function() {
|
|
@@ -36382,8 +36462,8 @@ var require_common = __commonJS({
|
|
|
36382
36462
|
}
|
|
36383
36463
|
return debug2;
|
|
36384
36464
|
}
|
|
36385
|
-
function extend(namespace,
|
|
36386
|
-
const newDebug = createDebug(this.namespace + (typeof
|
|
36465
|
+
function extend(namespace, delimiter2) {
|
|
36466
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter2 === "undefined" ? ":" : delimiter2) + namespace);
|
|
36387
36467
|
newDebug.log = this.log;
|
|
36388
36468
|
return newDebug;
|
|
36389
36469
|
}
|
|
@@ -37566,7 +37646,7 @@ var require_Command = __commonJS({
|
|
|
37566
37646
|
}
|
|
37567
37647
|
}
|
|
37568
37648
|
initPromise() {
|
|
37569
|
-
const promise = new Promise((
|
|
37649
|
+
const promise = new Promise((resolve4, reject) => {
|
|
37570
37650
|
if (!this.transformed) {
|
|
37571
37651
|
this.transformed = true;
|
|
37572
37652
|
const transformer = _Command._transformer.argument[this.name];
|
|
@@ -37575,7 +37655,7 @@ var require_Command = __commonJS({
|
|
|
37575
37655
|
}
|
|
37576
37656
|
this.stringifyArguments();
|
|
37577
37657
|
}
|
|
37578
|
-
this.resolve = this._convertValue(
|
|
37658
|
+
this.resolve = this._convertValue(resolve4);
|
|
37579
37659
|
this.reject = (err) => {
|
|
37580
37660
|
this._clearTimers();
|
|
37581
37661
|
if (this.errorStack) {
|
|
@@ -37608,11 +37688,11 @@ var require_Command = __commonJS({
|
|
|
37608
37688
|
/**
|
|
37609
37689
|
* Convert the value from buffer to the target encoding.
|
|
37610
37690
|
*/
|
|
37611
|
-
_convertValue(
|
|
37691
|
+
_convertValue(resolve4) {
|
|
37612
37692
|
return (value) => {
|
|
37613
37693
|
try {
|
|
37614
37694
|
this._clearTimers();
|
|
37615
|
-
|
|
37695
|
+
resolve4(this.transformReply(value));
|
|
37616
37696
|
this.isResolved = true;
|
|
37617
37697
|
} catch (err) {
|
|
37618
37698
|
this.reject(err);
|
|
@@ -37890,13 +37970,13 @@ var require_autoPipelining = __commonJS({
|
|
|
37890
37970
|
if (client.isCluster && !client.slots.length) {
|
|
37891
37971
|
if (client.status === "wait")
|
|
37892
37972
|
client.connect().catch(lodash_1.noop);
|
|
37893
|
-
return (0, standard_as_callback_1.default)(new Promise(function(
|
|
37973
|
+
return (0, standard_as_callback_1.default)(new Promise(function(resolve4, reject) {
|
|
37894
37974
|
client.delayUntilReady((err) => {
|
|
37895
37975
|
if (err) {
|
|
37896
37976
|
reject(err);
|
|
37897
37977
|
return;
|
|
37898
37978
|
}
|
|
37899
|
-
executeWithAutoPipelining(client, functionName, commandName, args, null).then(
|
|
37979
|
+
executeWithAutoPipelining(client, functionName, commandName, args, null).then(resolve4, reject);
|
|
37900
37980
|
});
|
|
37901
37981
|
}), callback);
|
|
37902
37982
|
}
|
|
@@ -37917,13 +37997,13 @@ var require_autoPipelining = __commonJS({
|
|
|
37917
37997
|
pipeline[exports.kExec] = true;
|
|
37918
37998
|
setImmediate(executeAutoPipeline, client, slotKey);
|
|
37919
37999
|
}
|
|
37920
|
-
const autoPipelinePromise = new Promise(function(
|
|
38000
|
+
const autoPipelinePromise = new Promise(function(resolve4, reject) {
|
|
37921
38001
|
pipeline[exports.kCallbacks].push(function(err, value) {
|
|
37922
38002
|
if (err) {
|
|
37923
38003
|
reject(err);
|
|
37924
38004
|
return;
|
|
37925
38005
|
}
|
|
37926
|
-
|
|
38006
|
+
resolve4(value);
|
|
37927
38007
|
});
|
|
37928
38008
|
if (functionName === "call") {
|
|
37929
38009
|
args.unshift(commandName);
|
|
@@ -38158,8 +38238,8 @@ var require_Pipeline = __commonJS({
|
|
|
38158
38238
|
this[name] = redis[name];
|
|
38159
38239
|
this[name + "Buffer"] = redis[name + "Buffer"];
|
|
38160
38240
|
});
|
|
38161
|
-
this.promise = new Promise((
|
|
38162
|
-
this.resolve =
|
|
38241
|
+
this.promise = new Promise((resolve4, reject) => {
|
|
38242
|
+
this.resolve = resolve4;
|
|
38163
38243
|
this.reject = reject;
|
|
38164
38244
|
});
|
|
38165
38245
|
const _this = this;
|
|
@@ -38459,13 +38539,13 @@ var require_transaction = __commonJS({
|
|
|
38459
38539
|
if (this.isCluster && !this.redis.slots.length) {
|
|
38460
38540
|
if (this.redis.status === "wait")
|
|
38461
38541
|
this.redis.connect().catch(utils_1.noop);
|
|
38462
|
-
return (0, standard_as_callback_1.default)(new Promise((
|
|
38542
|
+
return (0, standard_as_callback_1.default)(new Promise((resolve4, reject) => {
|
|
38463
38543
|
this.redis.delayUntilReady((err) => {
|
|
38464
38544
|
if (err) {
|
|
38465
38545
|
reject(err);
|
|
38466
38546
|
return;
|
|
38467
38547
|
}
|
|
38468
|
-
this.exec(pipeline).then(
|
|
38548
|
+
this.exec(pipeline).then(resolve4, reject);
|
|
38469
38549
|
});
|
|
38470
38550
|
}), callback);
|
|
38471
38551
|
}
|
|
@@ -39594,7 +39674,7 @@ var require_cluster = __commonJS({
|
|
|
39594
39674
|
* Connect to a cluster
|
|
39595
39675
|
*/
|
|
39596
39676
|
connect() {
|
|
39597
|
-
return new Promise((
|
|
39677
|
+
return new Promise((resolve4, reject) => {
|
|
39598
39678
|
if (this.status === "connecting" || this.status === "connect" || this.status === "ready") {
|
|
39599
39679
|
reject(new Error("Redis is already connecting/connected"));
|
|
39600
39680
|
return;
|
|
@@ -39623,7 +39703,7 @@ var require_cluster = __commonJS({
|
|
|
39623
39703
|
this.retryAttempts = 0;
|
|
39624
39704
|
this.executeOfflineCommands();
|
|
39625
39705
|
this.resetNodesRefreshInterval();
|
|
39626
|
-
|
|
39706
|
+
resolve4();
|
|
39627
39707
|
};
|
|
39628
39708
|
let closeListener = void 0;
|
|
39629
39709
|
const refreshListener = () => {
|
|
@@ -40233,7 +40313,7 @@ var require_cluster = __commonJS({
|
|
|
40233
40313
|
});
|
|
40234
40314
|
}
|
|
40235
40315
|
resolveSrv(hostname2) {
|
|
40236
|
-
return new Promise((
|
|
40316
|
+
return new Promise((resolve4, reject) => {
|
|
40237
40317
|
this.options.resolveSrv(hostname2, (err, records) => {
|
|
40238
40318
|
if (err) {
|
|
40239
40319
|
return reject(err);
|
|
@@ -40247,7 +40327,7 @@ var require_cluster = __commonJS({
|
|
|
40247
40327
|
if (!group.records.length) {
|
|
40248
40328
|
sortedKeys.shift();
|
|
40249
40329
|
}
|
|
40250
|
-
self2.dnsLookup(record.name).then((host) =>
|
|
40330
|
+
self2.dnsLookup(record.name).then((host) => resolve4({
|
|
40251
40331
|
host,
|
|
40252
40332
|
port: record.port
|
|
40253
40333
|
}), tryFirstOne);
|
|
@@ -40257,14 +40337,14 @@ var require_cluster = __commonJS({
|
|
|
40257
40337
|
});
|
|
40258
40338
|
}
|
|
40259
40339
|
dnsLookup(hostname2) {
|
|
40260
|
-
return new Promise((
|
|
40340
|
+
return new Promise((resolve4, reject) => {
|
|
40261
40341
|
this.options.dnsLookup(hostname2, (err, address) => {
|
|
40262
40342
|
if (err) {
|
|
40263
40343
|
debug2("failed to resolve hostname %s to IP: %s", hostname2, err.message);
|
|
40264
40344
|
reject(err);
|
|
40265
40345
|
} else {
|
|
40266
40346
|
debug2("resolved hostname %s to IP %s", hostname2, address);
|
|
40267
|
-
|
|
40347
|
+
resolve4(address);
|
|
40268
40348
|
}
|
|
40269
40349
|
});
|
|
40270
40350
|
});
|
|
@@ -40419,7 +40499,7 @@ var require_StandaloneConnector = __commonJS({
|
|
|
40419
40499
|
if (options.tls) {
|
|
40420
40500
|
Object.assign(connectionOptions, options.tls);
|
|
40421
40501
|
}
|
|
40422
|
-
return new Promise((
|
|
40502
|
+
return new Promise((resolve4, reject) => {
|
|
40423
40503
|
process.nextTick(() => {
|
|
40424
40504
|
if (!this.connecting) {
|
|
40425
40505
|
reject(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG));
|
|
@@ -40438,7 +40518,7 @@ var require_StandaloneConnector = __commonJS({
|
|
|
40438
40518
|
this.stream.once("error", (err) => {
|
|
40439
40519
|
this.firstError = err;
|
|
40440
40520
|
});
|
|
40441
|
-
|
|
40521
|
+
resolve4(this.stream);
|
|
40442
40522
|
});
|
|
40443
40523
|
});
|
|
40444
40524
|
}
|
|
@@ -40594,7 +40674,7 @@ var require_SentinelConnector = __commonJS({
|
|
|
40594
40674
|
const error = new Error(errorMsg);
|
|
40595
40675
|
if (typeof retryDelay === "number") {
|
|
40596
40676
|
eventEmitter("error", error);
|
|
40597
|
-
await new Promise((
|
|
40677
|
+
await new Promise((resolve4) => setTimeout(resolve4, retryDelay));
|
|
40598
40678
|
return connectToNext();
|
|
40599
40679
|
} else {
|
|
40600
40680
|
throw error;
|
|
@@ -41911,7 +41991,7 @@ var require_Redis = __commonJS({
|
|
|
41911
41991
|
* if the connection fails, times out, or if Redis is already connecting/connected.
|
|
41912
41992
|
*/
|
|
41913
41993
|
connect(callback) {
|
|
41914
|
-
const promise = new Promise((
|
|
41994
|
+
const promise = new Promise((resolve4, reject) => {
|
|
41915
41995
|
if (this.status === "connecting" || this.status === "connect" || this.status === "ready") {
|
|
41916
41996
|
reject(new Error("Redis is already connecting/connected"));
|
|
41917
41997
|
return;
|
|
@@ -41990,7 +42070,7 @@ var require_Redis = __commonJS({
|
|
|
41990
42070
|
}
|
|
41991
42071
|
const connectionReadyHandler = function() {
|
|
41992
42072
|
_this.removeListener("close", connectionCloseHandler);
|
|
41993
|
-
|
|
42073
|
+
resolve4();
|
|
41994
42074
|
};
|
|
41995
42075
|
var connectionCloseHandler = function() {
|
|
41996
42076
|
_this.removeListener("ready", connectionReadyHandler);
|
|
@@ -42084,10 +42164,10 @@ var require_Redis = __commonJS({
|
|
|
42084
42164
|
monitor: true,
|
|
42085
42165
|
lazyConnect: false
|
|
42086
42166
|
});
|
|
42087
|
-
return (0, standard_as_callback_1.default)(new Promise(function(
|
|
42167
|
+
return (0, standard_as_callback_1.default)(new Promise(function(resolve4, reject) {
|
|
42088
42168
|
monitorInstance.once("error", reject);
|
|
42089
42169
|
monitorInstance.once("monitoring", function() {
|
|
42090
|
-
|
|
42170
|
+
resolve4(monitorInstance);
|
|
42091
42171
|
});
|
|
42092
42172
|
}), callback);
|
|
42093
42173
|
}
|
|
@@ -42860,7 +42940,15 @@ async function runMenu() {
|
|
|
42860
42940
|
});
|
|
42861
42941
|
if (!q(setup) && setup) {
|
|
42862
42942
|
const { runInitFlow: runInitFlow2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
42863
|
-
await runInitFlow2(client, {
|
|
42943
|
+
const outcome = await runInitFlow2(client, {
|
|
42944
|
+
cwd: process.cwd(),
|
|
42945
|
+
dryRun: false,
|
|
42946
|
+
noScripts: false
|
|
42947
|
+
});
|
|
42948
|
+
if (outcome.exitCode === 0) {
|
|
42949
|
+
ye("All set. Run keynv again anytime to manage secrets.");
|
|
42950
|
+
return 0;
|
|
42951
|
+
}
|
|
42864
42952
|
}
|
|
42865
42953
|
}
|
|
42866
42954
|
}
|
|
@@ -42930,8 +43018,8 @@ var init_menu = __esm({
|
|
|
42930
43018
|
"src/ui/menu.ts"() {
|
|
42931
43019
|
init_dist5();
|
|
42932
43020
|
init_http();
|
|
42933
|
-
init_detect();
|
|
42934
43021
|
init_store();
|
|
43022
|
+
init_detect();
|
|
42935
43023
|
init_version();
|
|
42936
43024
|
init_audit2();
|
|
42937
43025
|
init_login();
|
|
@@ -44657,44 +44745,48 @@ var AuditListCommand = class extends Command {
|
|
|
44657
44745
|
sinceId = options_exports.String("--since-id");
|
|
44658
44746
|
json = options_exports.Boolean("--json", false);
|
|
44659
44747
|
async execute() {
|
|
44660
|
-
|
|
44661
|
-
|
|
44662
|
-
|
|
44663
|
-
|
|
44664
|
-
|
|
44665
|
-
|
|
44666
|
-
|
|
44667
|
-
|
|
44748
|
+
try {
|
|
44749
|
+
const client = new ApiClient();
|
|
44750
|
+
const data = await client.request(
|
|
44751
|
+
"/v1/audit",
|
|
44752
|
+
{
|
|
44753
|
+
query: {
|
|
44754
|
+
event_type: this.eventType,
|
|
44755
|
+
limit: this.limit,
|
|
44756
|
+
since_id: this.sinceId
|
|
44757
|
+
}
|
|
44668
44758
|
}
|
|
44669
|
-
|
|
44670
|
-
|
|
44671
|
-
|
|
44672
|
-
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
44759
|
+
);
|
|
44760
|
+
if (this.json) {
|
|
44761
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
44673
44762
|
`);
|
|
44674
|
-
|
|
44675
|
-
|
|
44676
|
-
|
|
44677
|
-
|
|
44678
|
-
|
|
44679
|
-
|
|
44680
|
-
|
|
44681
|
-
|
|
44682
|
-
|
|
44683
|
-
|
|
44684
|
-
|
|
44685
|
-
|
|
44686
|
-
|
|
44687
|
-
|
|
44688
|
-
|
|
44689
|
-
|
|
44690
|
-
|
|
44763
|
+
return 0;
|
|
44764
|
+
}
|
|
44765
|
+
if (data.entries.length === 0) {
|
|
44766
|
+
this.context.stdout.write("no audit entries\n");
|
|
44767
|
+
return 0;
|
|
44768
|
+
}
|
|
44769
|
+
this.context.stdout.write(
|
|
44770
|
+
`${table(
|
|
44771
|
+
["id", "ts", "actor", "agent", "event"],
|
|
44772
|
+
data.entries.map((e2) => [
|
|
44773
|
+
String(e2.id),
|
|
44774
|
+
e2.ts,
|
|
44775
|
+
e2.actor_user_id ?? "(none)",
|
|
44776
|
+
e2.actor_agent,
|
|
44777
|
+
e2.event_type
|
|
44778
|
+
])
|
|
44779
|
+
)}
|
|
44691
44780
|
`
|
|
44692
|
-
|
|
44693
|
-
|
|
44694
|
-
|
|
44781
|
+
);
|
|
44782
|
+
if (data.next_cursor) {
|
|
44783
|
+
this.context.stdout.write(`(next: --since-id ${data.next_cursor})
|
|
44695
44784
|
`);
|
|
44785
|
+
}
|
|
44786
|
+
return 0;
|
|
44787
|
+
} catch (err) {
|
|
44788
|
+
return handleExecError(this.context.stderr, err);
|
|
44696
44789
|
}
|
|
44697
|
-
return 0;
|
|
44698
44790
|
}
|
|
44699
44791
|
};
|
|
44700
44792
|
var AuditVerifyCommand = class extends Command {
|
|
@@ -44704,27 +44796,29 @@ var AuditVerifyCommand = class extends Command {
|
|
|
44704
44796
|
});
|
|
44705
44797
|
json = options_exports.Boolean("--json", false);
|
|
44706
44798
|
async execute() {
|
|
44707
|
-
|
|
44708
|
-
|
|
44709
|
-
|
|
44710
|
-
this.
|
|
44799
|
+
try {
|
|
44800
|
+
const client = new ApiClient();
|
|
44801
|
+
const data = await client.request("/v1/audit/verify", { method: "POST" });
|
|
44802
|
+
if (this.json) {
|
|
44803
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
44711
44804
|
`);
|
|
44712
|
-
|
|
44713
|
-
|
|
44714
|
-
|
|
44715
|
-
|
|
44805
|
+
return data.ok ? 0 : 1;
|
|
44806
|
+
}
|
|
44807
|
+
if (data.ok) {
|
|
44808
|
+
this.context.stdout.write(`OK: ${data.checked} entries verified
|
|
44716
44809
|
`);
|
|
44717
|
-
|
|
44718
|
-
|
|
44719
|
-
|
|
44720
|
-
|
|
44810
|
+
return 0;
|
|
44811
|
+
}
|
|
44812
|
+
this.context.stdout.write(
|
|
44813
|
+
`FAIL: chain broken at id ${data.broken_at_id} (${data.reason}); ${data.checked} entries verified before break
|
|
44721
44814
|
`
|
|
44722
|
-
|
|
44723
|
-
|
|
44815
|
+
);
|
|
44816
|
+
return 1;
|
|
44817
|
+
} catch (err) {
|
|
44818
|
+
return handleExecError(this.context.stderr, err);
|
|
44819
|
+
}
|
|
44724
44820
|
}
|
|
44725
44821
|
};
|
|
44726
|
-
|
|
44727
|
-
// src/commands/exec.ts
|
|
44728
44822
|
init_http();
|
|
44729
44823
|
init_envFile();
|
|
44730
44824
|
|
|
@@ -45073,7 +45167,9 @@ var ENV_ALLOWLIST = [
|
|
|
45073
45167
|
"WINDIR",
|
|
45074
45168
|
"COMSPEC",
|
|
45075
45169
|
"APPDATA",
|
|
45076
|
-
"LOCALAPPDATA"
|
|
45170
|
+
"LOCALAPPDATA",
|
|
45171
|
+
"PATHEXT"
|
|
45172
|
+
// needed so child processes can resolve executables by name
|
|
45077
45173
|
];
|
|
45078
45174
|
function spawnPrivileged(opts) {
|
|
45079
45175
|
const startedAt = Date.now();
|
|
@@ -45082,15 +45178,63 @@ function spawnPrivileged(opts) {
|
|
|
45082
45178
|
const v2 = process.env[name];
|
|
45083
45179
|
if (v2 !== void 0) env2[name] = v2;
|
|
45084
45180
|
}
|
|
45181
|
+
const nmBin = findNodeModulesBin(process.cwd());
|
|
45182
|
+
if (nmBin) {
|
|
45183
|
+
const existingPath = env2.PATH ?? "";
|
|
45184
|
+
env2.PATH = existingPath.startsWith(nmBin + nodePath.delimiter) ? existingPath : nmBin + nodePath.delimiter + existingPath;
|
|
45185
|
+
}
|
|
45085
45186
|
if (opts.injectedEnv) {
|
|
45086
45187
|
for (const [k2, v2] of Object.entries(opts.injectedEnv)) env2[k2] = v2;
|
|
45087
45188
|
}
|
|
45088
45189
|
const stdio = ["inherit", "pipe", "pipe"];
|
|
45089
|
-
const
|
|
45190
|
+
const WIN_BUILTINS = /* @__PURE__ */ new Set([
|
|
45191
|
+
"echo",
|
|
45192
|
+
"dir",
|
|
45193
|
+
"type",
|
|
45194
|
+
"copy",
|
|
45195
|
+
"del",
|
|
45196
|
+
"move",
|
|
45197
|
+
"ren",
|
|
45198
|
+
"md",
|
|
45199
|
+
"mkdir",
|
|
45200
|
+
"rd",
|
|
45201
|
+
"rmdir",
|
|
45202
|
+
"cd",
|
|
45203
|
+
"cls",
|
|
45204
|
+
"set",
|
|
45205
|
+
"pause",
|
|
45206
|
+
"find",
|
|
45207
|
+
"where"
|
|
45208
|
+
]);
|
|
45209
|
+
let spawnCmd = opts.command;
|
|
45210
|
+
let spawnArgs = opts.args;
|
|
45211
|
+
let windowsVerbatimArguments = false;
|
|
45212
|
+
if (process.platform === "win32") {
|
|
45213
|
+
const comspec = env2.COMSPEC ?? process.env.COMSPEC ?? "cmd.exe";
|
|
45214
|
+
if (WIN_BUILTINS.has(opts.command.toLowerCase())) {
|
|
45215
|
+
spawnCmd = comspec;
|
|
45216
|
+
spawnArgs = ["/d", "/s", "/c", opts.command, ...opts.args];
|
|
45217
|
+
} else {
|
|
45218
|
+
const resolved = resolveWindowsCmd(opts.command, env2);
|
|
45219
|
+
if (resolved !== null) {
|
|
45220
|
+
const ext = nodePath.extname(resolved).toLowerCase();
|
|
45221
|
+
if (ext === ".cmd" || ext === ".bat") {
|
|
45222
|
+
const q2 = (s) => s.includes(" ") ? `"${s}"` : s;
|
|
45223
|
+
const inner = [q2(resolved), ...opts.args.map(q2)].join(" ");
|
|
45224
|
+
spawnCmd = comspec;
|
|
45225
|
+
spawnArgs = ["/d", "/s", "/c", `"${inner}"`];
|
|
45226
|
+
windowsVerbatimArguments = true;
|
|
45227
|
+
} else {
|
|
45228
|
+
spawnCmd = resolved;
|
|
45229
|
+
}
|
|
45230
|
+
}
|
|
45231
|
+
}
|
|
45232
|
+
}
|
|
45233
|
+
const child = spawn(spawnCmd, spawnArgs, {
|
|
45090
45234
|
env: env2,
|
|
45091
45235
|
stdio,
|
|
45092
45236
|
detached: false,
|
|
45093
|
-
|
|
45237
|
+
windowsVerbatimArguments
|
|
45094
45238
|
});
|
|
45095
45239
|
const literals = opts.resolved.map((r) => r.value).filter((v2) => v2.length > 0);
|
|
45096
45240
|
if (!opts.noRedact && child.stdout) {
|
|
@@ -45111,14 +45255,14 @@ function spawnPrivileged(opts) {
|
|
|
45111
45255
|
}, opts.timeoutS * 1e3);
|
|
45112
45256
|
timer.unref();
|
|
45113
45257
|
}
|
|
45114
|
-
return new Promise((
|
|
45258
|
+
return new Promise((resolve4, reject) => {
|
|
45115
45259
|
child.on("error", (err) => {
|
|
45116
45260
|
if (timer) clearTimeout(timer);
|
|
45117
45261
|
reject(err);
|
|
45118
45262
|
});
|
|
45119
45263
|
child.on("close", (code, signal) => {
|
|
45120
45264
|
if (timer) clearTimeout(timer);
|
|
45121
|
-
|
|
45265
|
+
resolve4({
|
|
45122
45266
|
exitCode: code ?? 0,
|
|
45123
45267
|
signal,
|
|
45124
45268
|
durationMs: Date.now() - startedAt
|
|
@@ -45126,6 +45270,34 @@ function spawnPrivileged(opts) {
|
|
|
45126
45270
|
});
|
|
45127
45271
|
});
|
|
45128
45272
|
}
|
|
45273
|
+
function resolveWindowsCmd(command, subprocessEnv) {
|
|
45274
|
+
if (nodePath.extname(command)) return null;
|
|
45275
|
+
if (command.includes("/") || command.includes("\\")) return null;
|
|
45276
|
+
const pathExt = (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").map((e2) => e2.toLowerCase()).filter(Boolean);
|
|
45277
|
+
const pathStr = subprocessEnv.PATH ?? process.env.PATH ?? "";
|
|
45278
|
+
const pathDirs = pathStr.split(nodePath.delimiter).filter(Boolean);
|
|
45279
|
+
for (const dir of pathDirs) {
|
|
45280
|
+
for (const ext of pathExt) {
|
|
45281
|
+
try {
|
|
45282
|
+
const full = nodePath.join(dir, command + ext);
|
|
45283
|
+
if (existsSync(full)) return full;
|
|
45284
|
+
} catch {
|
|
45285
|
+
}
|
|
45286
|
+
}
|
|
45287
|
+
}
|
|
45288
|
+
return null;
|
|
45289
|
+
}
|
|
45290
|
+
function findNodeModulesBin(cwd) {
|
|
45291
|
+
let dir = nodePath.resolve(cwd);
|
|
45292
|
+
for (let i = 0; i < 20; i++) {
|
|
45293
|
+
const candidate = nodePath.join(dir, "node_modules", ".bin");
|
|
45294
|
+
if (existsSync(candidate)) return candidate;
|
|
45295
|
+
const parent = nodePath.dirname(dir);
|
|
45296
|
+
if (parent === dir) break;
|
|
45297
|
+
dir = parent;
|
|
45298
|
+
}
|
|
45299
|
+
return null;
|
|
45300
|
+
}
|
|
45129
45301
|
|
|
45130
45302
|
// src/commands/exec.ts
|
|
45131
45303
|
var ExecCommand = class extends Command {
|
|
@@ -45182,6 +45354,10 @@ spelled \`--from\` to avoid the collision.)
|
|
|
45182
45354
|
quiet = options_exports.Boolean("--quiet", false, {
|
|
45183
45355
|
description: `Suppress the "loaded N vars from ${ENV_FILE_BASENAME}" status line.`
|
|
45184
45356
|
});
|
|
45357
|
+
// Option.Rest: keynv options (e.g. --no-env-file) are parsed before `--`.
|
|
45358
|
+
// Everything after `--` is captured in rest verbatim, including subprocess
|
|
45359
|
+
// flags like `--port 3005` and `-v`. Always use `--` to separate keynv
|
|
45360
|
+
// options from the subprocess command.
|
|
45185
45361
|
rest = options_exports.Rest();
|
|
45186
45362
|
async execute() {
|
|
45187
45363
|
if (!this.rest || this.rest.length === 0) {
|
|
@@ -45224,6 +45400,13 @@ spelled \`--from\` to avoid the collision.)
|
|
|
45224
45400
|
);
|
|
45225
45401
|
return 2;
|
|
45226
45402
|
}
|
|
45403
|
+
if (!envFileLoaded && !this.noEnvFile && !this.envFile && !process.env.KEYNV_ENV_FILE) {
|
|
45404
|
+
this.context.stderr.write(
|
|
45405
|
+
`keynv: no ${ENV_FILE_BASENAME} found in this directory or any parent.
|
|
45406
|
+
Run \`keynv init\` in your project root to migrate secrets and create one.
|
|
45407
|
+
`
|
|
45408
|
+
);
|
|
45409
|
+
}
|
|
45227
45410
|
const viaEnvSpecs = [];
|
|
45228
45411
|
for (const spec of this.viaEnv ?? []) {
|
|
45229
45412
|
const eq = spec.indexOf("=");
|
|
@@ -45348,7 +45531,9 @@ function signalNumber(sig) {
|
|
|
45348
45531
|
init_dist();
|
|
45349
45532
|
init_http();
|
|
45350
45533
|
init_envFile();
|
|
45534
|
+
init_detect();
|
|
45351
45535
|
init_heuristics();
|
|
45536
|
+
init_aiContext();
|
|
45352
45537
|
init_init();
|
|
45353
45538
|
init_cancel();
|
|
45354
45539
|
init_tty();
|
|
@@ -45364,7 +45549,8 @@ async function resolveProjectId(client, input) {
|
|
|
45364
45549
|
return input;
|
|
45365
45550
|
}
|
|
45366
45551
|
const data = await client.request("/v1/projects");
|
|
45367
|
-
const
|
|
45552
|
+
const lowerInput = input.toLowerCase();
|
|
45553
|
+
const match = data.projects.find((p2) => p2.name.toLowerCase() === lowerInput);
|
|
45368
45554
|
if (!match) throw new Error(`project not found: ${input}`);
|
|
45369
45555
|
return match.id;
|
|
45370
45556
|
}
|
|
@@ -45375,25 +45561,29 @@ var ProjectListCommand = class extends Command {
|
|
|
45375
45561
|
});
|
|
45376
45562
|
json = options_exports.Boolean("--json", false);
|
|
45377
45563
|
async execute() {
|
|
45378
|
-
|
|
45379
|
-
|
|
45380
|
-
|
|
45381
|
-
this.
|
|
45564
|
+
try {
|
|
45565
|
+
const client = new ApiClient();
|
|
45566
|
+
const data = await client.request("/v1/projects");
|
|
45567
|
+
if (this.json) {
|
|
45568
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45382
45569
|
`);
|
|
45570
|
+
return 0;
|
|
45571
|
+
}
|
|
45572
|
+
if (data.projects.length === 0) {
|
|
45573
|
+
this.context.stdout.write("no projects\n");
|
|
45574
|
+
return 0;
|
|
45575
|
+
}
|
|
45576
|
+
this.context.stdout.write(
|
|
45577
|
+
`${table(
|
|
45578
|
+
["name", "id", "created_at"],
|
|
45579
|
+
data.projects.map((p2) => [p2.name, p2.id, p2.created_at])
|
|
45580
|
+
)}
|
|
45581
|
+
`
|
|
45582
|
+
);
|
|
45383
45583
|
return 0;
|
|
45584
|
+
} catch (err) {
|
|
45585
|
+
return handleExecError(this.context.stderr, err);
|
|
45384
45586
|
}
|
|
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
45587
|
}
|
|
45398
45588
|
};
|
|
45399
45589
|
var ProjectCreateCommand = class extends Command {
|
|
@@ -45407,28 +45597,32 @@ var ProjectCreateCommand = class extends Command {
|
|
|
45407
45597
|
description: 'Environment spec: name[:tier[:approval]]. Tier \u2208 {production,non-production}; "approval" sets require_approval=true.'
|
|
45408
45598
|
});
|
|
45409
45599
|
async execute() {
|
|
45410
|
-
|
|
45411
|
-
const
|
|
45412
|
-
|
|
45413
|
-
|
|
45414
|
-
|
|
45415
|
-
|
|
45416
|
-
|
|
45417
|
-
|
|
45418
|
-
|
|
45419
|
-
|
|
45420
|
-
|
|
45421
|
-
|
|
45422
|
-
|
|
45423
|
-
|
|
45600
|
+
try {
|
|
45601
|
+
const envs = (this.envs ?? ["dev"]).map((spec) => {
|
|
45602
|
+
const [name, tier, approval] = spec.split(":");
|
|
45603
|
+
return {
|
|
45604
|
+
name: name ?? "",
|
|
45605
|
+
tier: tier ?? "non-production",
|
|
45606
|
+
require_approval: approval === "approval"
|
|
45607
|
+
};
|
|
45608
|
+
});
|
|
45609
|
+
const client = new ApiClient();
|
|
45610
|
+
const result = await client.request("/v1/projects", {
|
|
45611
|
+
method: "POST",
|
|
45612
|
+
body: { name: this.name, environments: envs }
|
|
45613
|
+
});
|
|
45614
|
+
this.context.stdout.write(`created project ${result.name} (${result.id})
|
|
45424
45615
|
`);
|
|
45425
|
-
|
|
45426
|
-
|
|
45427
|
-
|
|
45616
|
+
for (const e2 of envs) {
|
|
45617
|
+
this.context.stdout.write(
|
|
45618
|
+
` env: ${e2.name} (tier=${e2.tier}, approval=${e2.require_approval})
|
|
45428
45619
|
`
|
|
45429
|
-
|
|
45620
|
+
);
|
|
45621
|
+
}
|
|
45622
|
+
return 0;
|
|
45623
|
+
} catch (err) {
|
|
45624
|
+
return handleExecError(this.context.stderr, err);
|
|
45430
45625
|
}
|
|
45431
|
-
return 0;
|
|
45432
45626
|
}
|
|
45433
45627
|
};
|
|
45434
45628
|
var ProjectDescribeCommand = class extends Command {
|
|
@@ -45443,23 +45637,27 @@ var ProjectDescribeCommand = class extends Command {
|
|
|
45443
45637
|
id = options_exports.String();
|
|
45444
45638
|
json = options_exports.Boolean("--json", false);
|
|
45445
45639
|
async execute() {
|
|
45446
|
-
|
|
45447
|
-
|
|
45448
|
-
|
|
45449
|
-
|
|
45450
|
-
this.
|
|
45640
|
+
try {
|
|
45641
|
+
const client = new ApiClient();
|
|
45642
|
+
const projectId2 = await resolveProjectId(client, this.id);
|
|
45643
|
+
const data = await client.request(`/v1/projects/${projectId2}`);
|
|
45644
|
+
if (this.json) {
|
|
45645
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45451
45646
|
`);
|
|
45452
|
-
|
|
45453
|
-
|
|
45454
|
-
|
|
45647
|
+
return 0;
|
|
45648
|
+
}
|
|
45649
|
+
this.context.stdout.write(`project: ${data.name} (${data.id})
|
|
45455
45650
|
`);
|
|
45456
|
-
|
|
45457
|
-
|
|
45458
|
-
|
|
45651
|
+
for (const e2 of data.environments) {
|
|
45652
|
+
this.context.stdout.write(
|
|
45653
|
+
` env: ${e2.name} (tier=${e2.tier}, approval=${e2.require_approval})
|
|
45459
45654
|
`
|
|
45460
|
-
|
|
45655
|
+
);
|
|
45656
|
+
}
|
|
45657
|
+
return 0;
|
|
45658
|
+
} catch (err) {
|
|
45659
|
+
return handleExecError(this.context.stderr, err);
|
|
45461
45660
|
}
|
|
45462
|
-
return 0;
|
|
45463
45661
|
}
|
|
45464
45662
|
};
|
|
45465
45663
|
var ProjectDeleteCommand = class extends Command {
|
|
@@ -45472,15 +45670,27 @@ var ProjectDeleteCommand = class extends Command {
|
|
|
45472
45670
|
this.context.stderr.write("keynv: refusing to delete without --force\n");
|
|
45473
45671
|
return 2;
|
|
45474
45672
|
}
|
|
45475
|
-
|
|
45476
|
-
|
|
45477
|
-
|
|
45673
|
+
try {
|
|
45674
|
+
const client = new ApiClient();
|
|
45675
|
+
await client.request(`/v1/projects/${this.id}`, { method: "DELETE" });
|
|
45676
|
+
this.context.stdout.write(`deleted project ${this.id}
|
|
45478
45677
|
`);
|
|
45479
|
-
|
|
45678
|
+
return 0;
|
|
45679
|
+
} catch (err) {
|
|
45680
|
+
return handleExecError(this.context.stderr, err);
|
|
45681
|
+
}
|
|
45480
45682
|
}
|
|
45481
45683
|
};
|
|
45482
45684
|
|
|
45483
45685
|
// src/commands/init.ts
|
|
45686
|
+
function toAliasKey2(name) {
|
|
45687
|
+
if (!name) return name;
|
|
45688
|
+
const KEY_RE3 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
|
|
45689
|
+
if (KEY_RE3.test(name)) return name;
|
|
45690
|
+
const normalised = name.toLowerCase().replace(/_/g, "-");
|
|
45691
|
+
if (KEY_RE3.test(normalised)) return normalised;
|
|
45692
|
+
return normalised.replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 64) || "key";
|
|
45693
|
+
}
|
|
45484
45694
|
var InitCommand = class extends Command {
|
|
45485
45695
|
static paths = [["init"]];
|
|
45486
45696
|
static usage = Command.Usage({
|
|
@@ -45499,15 +45709,19 @@ mappings that would be written to .keynv.env, then exits without
|
|
|
45499
45709
|
touching any files or making any network calls. Use it to preview
|
|
45500
45710
|
what init will do before committing.
|
|
45501
45711
|
|
|
45502
|
-
|
|
45503
|
-
|
|
45504
|
-
|
|
45712
|
+
For scripted migration, use \`--env-file\` or \`--secret\` flags, or
|
|
45713
|
+
\`--yes\` to auto-scan the project directory and set up without
|
|
45714
|
+
any prompts.
|
|
45505
45715
|
`,
|
|
45506
45716
|
examples: [
|
|
45507
45717
|
["Walk the current project", "$0 init"],
|
|
45508
45718
|
["Preview without writing or uploading", "$0 init --dry-run"],
|
|
45509
45719
|
["Skip the package.json script-wrapping step", "$0 init --no-scripts"],
|
|
45510
|
-
["Non-interactive (CI/CD)", "$0 init --env-file .env --project myproject --env dev"]
|
|
45720
|
+
["Non-interactive (CI/CD)", "$0 init --env-file .env --project myproject --env dev"],
|
|
45721
|
+
[
|
|
45722
|
+
"Auto-scan & set up without prompts (CI/CD)",
|
|
45723
|
+
"$0 init --yes"
|
|
45724
|
+
]
|
|
45511
45725
|
]
|
|
45512
45726
|
});
|
|
45513
45727
|
dryRun = options_exports.Boolean("--dry-run", false, {
|
|
@@ -45528,6 +45742,9 @@ commands directly.
|
|
|
45528
45742
|
secret = options_exports.Array("--secret", {
|
|
45529
45743
|
description: "KEY=value secret to upload (non-interactive). Can be specified multiple times."
|
|
45530
45744
|
});
|
|
45745
|
+
yes = options_exports.Boolean("--yes", false, {
|
|
45746
|
+
description: "Auto-scan .env files, classify, and set up without prompts. Implies non-interactive mode."
|
|
45747
|
+
});
|
|
45531
45748
|
async execute() {
|
|
45532
45749
|
const client = new ApiClient();
|
|
45533
45750
|
await client.ensureHydrated();
|
|
@@ -45537,13 +45754,13 @@ commands directly.
|
|
|
45537
45754
|
}
|
|
45538
45755
|
const hasEnvFile = this.envFile != null;
|
|
45539
45756
|
const hasSecrets = this.secret != null && this.secret.length > 0;
|
|
45540
|
-
const isNonInteractive = hasEnvFile || hasSecrets;
|
|
45757
|
+
const isNonInteractive = hasEnvFile || hasSecrets || this.dryRun || this.yes;
|
|
45541
45758
|
if (isNonInteractive) {
|
|
45542
45759
|
return this.runNonInteractive(client);
|
|
45543
45760
|
}
|
|
45544
45761
|
if (!isInteractive()) {
|
|
45545
45762
|
this.context.stderr.write(
|
|
45546
|
-
"keynv init requires an interactive terminal. Use --env-file or --secret for scripted setup.\n"
|
|
45763
|
+
"keynv init requires an interactive terminal. Use --dry-run, --env-file, or --secret for scripted setup.\n"
|
|
45547
45764
|
);
|
|
45548
45765
|
return 1;
|
|
45549
45766
|
}
|
|
@@ -45563,6 +45780,9 @@ commands directly.
|
|
|
45563
45780
|
}
|
|
45564
45781
|
}
|
|
45565
45782
|
async runNonInteractive(client) {
|
|
45783
|
+
if (this.yes && !this.envFile && !this.secret) {
|
|
45784
|
+
return this.runAutoScan(client);
|
|
45785
|
+
}
|
|
45566
45786
|
const projectName = this.project;
|
|
45567
45787
|
if (!projectName) {
|
|
45568
45788
|
this.context.stderr.write("keynv: --project is required in non-interactive mode.\n");
|
|
@@ -45582,7 +45802,7 @@ commands directly.
|
|
|
45582
45802
|
const content = readFileSync(this.envFile, "utf8");
|
|
45583
45803
|
const entries = parseEnvFile(content, this.envFile);
|
|
45584
45804
|
for (const e2 of entries) {
|
|
45585
|
-
if (classifyEntry(e2.name, e2.value).verdict
|
|
45805
|
+
if (classifyEntry(e2.name, e2.value).verdict === "secret") {
|
|
45586
45806
|
secrets.push({ name: e2.name, value: e2.value });
|
|
45587
45807
|
}
|
|
45588
45808
|
}
|
|
@@ -45612,34 +45832,134 @@ commands directly.
|
|
|
45612
45832
|
return 0;
|
|
45613
45833
|
}
|
|
45614
45834
|
if (this.dryRun) {
|
|
45615
|
-
this.
|
|
45616
|
-
|
|
45835
|
+
if (this.envFile || this.secret && this.secret.length > 0) {
|
|
45836
|
+
this.context.stdout.write(
|
|
45837
|
+
`keynv: dry-run \u2014 would upload ${secrets.length} secret(s) to project ${projectName} (${projectId2}) in env ${envName}
|
|
45617
45838
|
`
|
|
45839
|
+
);
|
|
45840
|
+
for (const { name } of secrets) {
|
|
45841
|
+
const aliasKey = toAliasKey2(name);
|
|
45842
|
+
this.context.stdout.write(` ${name}=@${projectName}.${envName}.${aliasKey}
|
|
45843
|
+
`);
|
|
45844
|
+
}
|
|
45845
|
+
return 0;
|
|
45846
|
+
}
|
|
45847
|
+
this.context.stdout.write(
|
|
45848
|
+
"keynv: dry-run mode \u2014 no --env-file or --secret provided. Nothing to scan.\n"
|
|
45618
45849
|
);
|
|
45850
|
+
return 0;
|
|
45851
|
+
}
|
|
45852
|
+
const secretsWithKeys = secrets.map((s) => ({ ...s, aliasKey: toAliasKey2(s.name) }));
|
|
45853
|
+
return this.uploadSecrets(client, projectId2, projectName, envName, secretsWithKeys);
|
|
45854
|
+
}
|
|
45855
|
+
/**
|
|
45856
|
+
* Auto-scan mode (--yes without explicit --env-file). Finds .env files
|
|
45857
|
+
* in the project root, classifies entries, creates a project, uploads
|
|
45858
|
+
* secrets, and writes .keynv.env — all without prompts.
|
|
45859
|
+
*/
|
|
45860
|
+
async runAutoScan(client) {
|
|
45861
|
+
const root = findProjectRoot(process.cwd());
|
|
45862
|
+
if (!root) {
|
|
45863
|
+
this.context.stderr.write(
|
|
45864
|
+
"keynv: no project root found (no package.json, .git, etc.).\n"
|
|
45865
|
+
);
|
|
45866
|
+
return 1;
|
|
45867
|
+
}
|
|
45868
|
+
const envFiles = findEnvFiles(root.path);
|
|
45869
|
+
if (envFiles.length === 0) {
|
|
45870
|
+
this.context.stdout.write("keynv: no .env files found. Nothing to migrate.\n");
|
|
45871
|
+
return 0;
|
|
45872
|
+
}
|
|
45873
|
+
const projectName = this.project ?? root.suggestedName;
|
|
45874
|
+
const envName = this.env ?? suggestedEnvForSuffix(envFiles[0]?.suffix ?? null);
|
|
45875
|
+
const secrets = [];
|
|
45876
|
+
for (const f of envFiles) {
|
|
45877
|
+
try {
|
|
45878
|
+
const entries = parseEnvFile(readFileSync(f.path, "utf8"), f.path);
|
|
45879
|
+
for (const e2 of entries) {
|
|
45880
|
+
if (classifyEntry(e2.name, e2.value).verdict === "secret") {
|
|
45881
|
+
secrets.push({ name: e2.name, value: e2.value });
|
|
45882
|
+
}
|
|
45883
|
+
}
|
|
45884
|
+
} catch {
|
|
45885
|
+
this.context.stderr.write(`keynv: warning \u2014 could not parse ${f.name}, skipping.
|
|
45886
|
+
`);
|
|
45887
|
+
}
|
|
45888
|
+
}
|
|
45889
|
+
if (secrets.length === 0) {
|
|
45890
|
+
this.context.stdout.write("keynv: no secrets detected in .env files. Nothing to upload.\n");
|
|
45891
|
+
return 0;
|
|
45892
|
+
}
|
|
45893
|
+
this.context.stdout.write(
|
|
45894
|
+
`keynv: auto-scan found ${secrets.length} secret(s) across ${envFiles.length} file(s).
|
|
45895
|
+
`
|
|
45896
|
+
);
|
|
45897
|
+
if (this.dryRun) {
|
|
45619
45898
|
for (const { name } of secrets) {
|
|
45620
|
-
const aliasKey = name
|
|
45899
|
+
const aliasKey = toAliasKey2(name);
|
|
45621
45900
|
this.context.stdout.write(` ${name}=@${projectName}.${envName}.${aliasKey}
|
|
45622
45901
|
`);
|
|
45623
45902
|
}
|
|
45624
45903
|
return 0;
|
|
45625
45904
|
}
|
|
45905
|
+
let projectId2;
|
|
45906
|
+
try {
|
|
45907
|
+
projectId2 = await resolveProjectId(client, projectName);
|
|
45908
|
+
} catch {
|
|
45909
|
+
const created = await client.request("/v1/projects", {
|
|
45910
|
+
method: "POST",
|
|
45911
|
+
body: { name: projectName, environments: [{ name: envName, tier: "non-production", require_approval: false }] }
|
|
45912
|
+
});
|
|
45913
|
+
projectId2 = created.id;
|
|
45914
|
+
this.context.stdout.write(`keynv: created project "${projectName}" (${projectId2}).
|
|
45915
|
+
`);
|
|
45916
|
+
}
|
|
45917
|
+
const secretsWithKeys = secrets.map((s) => ({ ...s, aliasKey: toAliasKey2(s.name) }));
|
|
45918
|
+
const result = await this.uploadSecrets(client, projectId2, projectName, envName, secretsWithKeys);
|
|
45919
|
+
if (result !== 0) return result;
|
|
45920
|
+
const aliasLines = secretsWithKeys.map((s) => `# ${s.name}
|
|
45921
|
+
${s.name}=@${projectName}.${envName}.${s.aliasKey}`).join("\n");
|
|
45922
|
+
const keynvEnvPath = join(root.path, ".keynv.env");
|
|
45923
|
+
writeFileSync(keynvEnvPath, `# Auto-generated by keynv init --yes
|
|
45924
|
+
${aliasLines}
|
|
45925
|
+
`);
|
|
45926
|
+
this.context.stdout.write(`keynv: wrote ${keynvEnvPath}
|
|
45927
|
+
`);
|
|
45928
|
+
try {
|
|
45929
|
+
const outcome = writeAiContext(root.path);
|
|
45930
|
+
if (outcome === "created") this.context.stdout.write("keynv: wrote AGENTS.md\n");
|
|
45931
|
+
} catch {
|
|
45932
|
+
this.context.stdout.write("keynv: warning \u2014 could not write AGENTS.md.\n");
|
|
45933
|
+
}
|
|
45934
|
+
for (const f of envFiles) {
|
|
45935
|
+
unlinkSync(f.path);
|
|
45936
|
+
this.context.stdout.write(`keynv: removed ${f.name} (secrets migrated to vault).
|
|
45937
|
+
`);
|
|
45938
|
+
}
|
|
45939
|
+
this.context.stdout.write("keynv: done. Use `keynv exec` to run commands with resolved secrets.\n");
|
|
45940
|
+
return 0;
|
|
45941
|
+
}
|
|
45942
|
+
/**
|
|
45943
|
+
* Upload secrets to the vault and print the result. Shared between
|
|
45944
|
+
* runNonInteractive and runAutoScan.
|
|
45945
|
+
*/
|
|
45946
|
+
async uploadSecrets(client, projectId2, projectName, envName, secrets) {
|
|
45626
45947
|
let uploaded = 0;
|
|
45627
45948
|
const failed = [];
|
|
45628
|
-
for (const
|
|
45629
|
-
const
|
|
45630
|
-
const alias2 = buildAlias({ project: projectName, environment: envName, key: aliasKey });
|
|
45949
|
+
for (const s of secrets) {
|
|
45950
|
+
const alias2 = buildAlias({ project: projectName, environment: envName, key: s.aliasKey });
|
|
45631
45951
|
if (!alias2) {
|
|
45632
|
-
failed.push(
|
|
45952
|
+
failed.push({ name: s.name, reason: `invalid alias key: ${s.aliasKey}` });
|
|
45633
45953
|
continue;
|
|
45634
45954
|
}
|
|
45635
45955
|
try {
|
|
45636
45956
|
await client.request(`/v1/projects/${projectId2}/secrets`, {
|
|
45637
45957
|
method: "POST",
|
|
45638
|
-
body: { env: envName, key: aliasKey, value }
|
|
45958
|
+
body: { env: envName, key: s.aliasKey, value: s.value }
|
|
45639
45959
|
});
|
|
45640
45960
|
uploaded++;
|
|
45641
45961
|
} catch (err) {
|
|
45642
|
-
failed.push(
|
|
45962
|
+
failed.push({ name: s.name, reason: err instanceof Error ? err.message : String(err) });
|
|
45643
45963
|
}
|
|
45644
45964
|
}
|
|
45645
45965
|
this.context.stdout.write(
|
|
@@ -45647,7 +45967,7 @@ commands directly.
|
|
|
45647
45967
|
`
|
|
45648
45968
|
);
|
|
45649
45969
|
if (failed.length > 0) {
|
|
45650
|
-
for (const f of failed) this.context.stderr.write(` failed: ${f}
|
|
45970
|
+
for (const f of failed) this.context.stderr.write(` failed: ${f.name} \u2014 ${f.reason}
|
|
45651
45971
|
`);
|
|
45652
45972
|
return 1;
|
|
45653
45973
|
}
|
|
@@ -45669,7 +45989,7 @@ async function promptHidden(prompt) {
|
|
|
45669
45989
|
process.stdin.setRawMode(true);
|
|
45670
45990
|
process.stdin.resume();
|
|
45671
45991
|
process.stdin.setEncoding("utf8");
|
|
45672
|
-
return new Promise((
|
|
45992
|
+
return new Promise((resolve4) => {
|
|
45673
45993
|
let buf = "";
|
|
45674
45994
|
const onData = (chunk) => {
|
|
45675
45995
|
for (const ch of chunk) {
|
|
@@ -45678,7 +45998,7 @@ async function promptHidden(prompt) {
|
|
|
45678
45998
|
process.stdin.pause();
|
|
45679
45999
|
process.stdin.removeListener("data", onData);
|
|
45680
46000
|
process.stdout.write("\n");
|
|
45681
|
-
|
|
46001
|
+
resolve4(buf);
|
|
45682
46002
|
return;
|
|
45683
46003
|
}
|
|
45684
46004
|
if (ch === "") {
|
|
@@ -45696,10 +46016,10 @@ async function promptHidden(prompt) {
|
|
|
45696
46016
|
}
|
|
45697
46017
|
async function promptLine(prompt) {
|
|
45698
46018
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
45699
|
-
return new Promise((
|
|
46019
|
+
return new Promise((resolve4) => {
|
|
45700
46020
|
rl.question(prompt, (answer) => {
|
|
45701
46021
|
rl.close();
|
|
45702
|
-
|
|
46022
|
+
resolve4(answer.trim());
|
|
45703
46023
|
});
|
|
45704
46024
|
});
|
|
45705
46025
|
}
|
|
@@ -45732,6 +46052,13 @@ var LoginCommand = class extends Command {
|
|
|
45732
46052
|
});
|
|
45733
46053
|
async execute() {
|
|
45734
46054
|
const finalServerUrl = this.server ?? DEFAULT_SERVER_URL;
|
|
46055
|
+
try {
|
|
46056
|
+
new URL(finalServerUrl);
|
|
46057
|
+
} catch {
|
|
46058
|
+
this.context.stderr.write(`keynv: invalid server URL '${finalServerUrl}'
|
|
46059
|
+
`);
|
|
46060
|
+
return 1;
|
|
46061
|
+
}
|
|
45735
46062
|
if (this.token) {
|
|
45736
46063
|
return this.loginWithToken(finalServerUrl, this.token);
|
|
45737
46064
|
}
|
|
@@ -45754,11 +46081,20 @@ var LoginCommand = class extends Command {
|
|
|
45754
46081
|
}
|
|
45755
46082
|
const email2 = this.email ?? await promptLine("email: ");
|
|
45756
46083
|
const password = this.password ?? await promptHidden("password: ");
|
|
45757
|
-
|
|
45758
|
-
|
|
45759
|
-
|
|
45760
|
-
|
|
45761
|
-
|
|
46084
|
+
let res;
|
|
46085
|
+
try {
|
|
46086
|
+
res = await fetch(new URL("/v1/auth/login", finalServerUrl).toString(), {
|
|
46087
|
+
method: "POST",
|
|
46088
|
+
headers: { "content-type": "application/json", "x-keynv-agent": AGENT },
|
|
46089
|
+
body: JSON.stringify({ email: email2, password })
|
|
46090
|
+
});
|
|
46091
|
+
} catch (err) {
|
|
46092
|
+
this.context.stderr.write(
|
|
46093
|
+
`keynv: cannot reach server '${finalServerUrl}' \u2014 ${err instanceof Error ? err.message : String(err)}
|
|
46094
|
+
`
|
|
46095
|
+
);
|
|
46096
|
+
return 1;
|
|
46097
|
+
}
|
|
45762
46098
|
if (!res.ok) {
|
|
45763
46099
|
const text = await res.text();
|
|
45764
46100
|
let msg = `login failed (${res.status})`;
|
|
@@ -45804,9 +46140,18 @@ var LoginCommand = class extends Command {
|
|
|
45804
46140
|
return 0;
|
|
45805
46141
|
}
|
|
45806
46142
|
async loginWithToken(serverUrl, token) {
|
|
45807
|
-
|
|
45808
|
-
|
|
45809
|
-
|
|
46143
|
+
let res;
|
|
46144
|
+
try {
|
|
46145
|
+
res = await fetch(new URL("/v1/whoami", serverUrl).toString(), {
|
|
46146
|
+
headers: { authorization: `Bearer ${token}`, "x-keynv-agent": AGENT }
|
|
46147
|
+
});
|
|
46148
|
+
} catch (err) {
|
|
46149
|
+
this.context.stderr.write(
|
|
46150
|
+
`keynv: cannot reach server '${serverUrl}' \u2014 ${err instanceof Error ? err.message : String(err)}
|
|
46151
|
+
`
|
|
46152
|
+
);
|
|
46153
|
+
return 1;
|
|
46154
|
+
}
|
|
45810
46155
|
if (!res.ok) {
|
|
45811
46156
|
const text = await res.text();
|
|
45812
46157
|
let msg = `token login failed (${res.status})`;
|
|
@@ -45884,36 +46229,40 @@ var WhoamiCommand = class extends Command {
|
|
|
45884
46229
|
});
|
|
45885
46230
|
json = options_exports.Boolean("--json", false);
|
|
45886
46231
|
async execute() {
|
|
45887
|
-
|
|
45888
|
-
|
|
45889
|
-
|
|
45890
|
-
|
|
45891
|
-
|
|
45892
|
-
|
|
45893
|
-
|
|
45894
|
-
|
|
45895
|
-
this.
|
|
46232
|
+
try {
|
|
46233
|
+
const client = new ApiClient();
|
|
46234
|
+
await client.ensureHydrated();
|
|
46235
|
+
if (!client.isLoggedIn) {
|
|
46236
|
+
this.context.stderr.write("keynv: not logged in. Run `keynv login`.\n");
|
|
46237
|
+
return 1;
|
|
46238
|
+
}
|
|
46239
|
+
const data = await client.request("/v1/whoami");
|
|
46240
|
+
if (this.json) {
|
|
46241
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45896
46242
|
`);
|
|
45897
|
-
|
|
45898
|
-
|
|
45899
|
-
|
|
46243
|
+
return 0;
|
|
46244
|
+
}
|
|
46245
|
+
this.context.stdout.write(`user: ${data.email} (${data.id})
|
|
45900
46246
|
`);
|
|
45901
|
-
|
|
45902
|
-
|
|
46247
|
+
const orgDisplay = data.org_name ? `${data.org_name} (${data.org_id})` : data.org_id;
|
|
46248
|
+
this.context.stdout.write(`org: ${orgDisplay}
|
|
45903
46249
|
`);
|
|
45904
|
-
|
|
46250
|
+
this.context.stdout.write(`role: ${data.org_role}
|
|
45905
46251
|
`);
|
|
45906
|
-
|
|
45907
|
-
|
|
45908
|
-
|
|
45909
|
-
|
|
45910
|
-
|
|
45911
|
-
|
|
45912
|
-
|
|
46252
|
+
if (data.memberships.length === 0) {
|
|
46253
|
+
this.context.stdout.write("memberships: (none)\n");
|
|
46254
|
+
} else {
|
|
46255
|
+
this.context.stdout.write("memberships:\n");
|
|
46256
|
+
for (const m of data.memberships) {
|
|
46257
|
+
const proj = m.project_name ? `${m.project_name} (${m.project_id})` : m.project_id;
|
|
46258
|
+
this.context.stdout.write(` ${proj}: ${m.role}
|
|
45913
46259
|
`);
|
|
46260
|
+
}
|
|
45914
46261
|
}
|
|
46262
|
+
return 0;
|
|
46263
|
+
} catch (err) {
|
|
46264
|
+
return handleExecError(this.context.stderr, err);
|
|
45915
46265
|
}
|
|
45916
|
-
return 0;
|
|
45917
46266
|
}
|
|
45918
46267
|
};
|
|
45919
46268
|
|
|
@@ -45935,15 +46284,19 @@ var MemberAddCommand = class extends Command {
|
|
|
45935
46284
|
this.context.stderr.write("keynv: --role must be one of lead, developer, reader\n");
|
|
45936
46285
|
return 1;
|
|
45937
46286
|
}
|
|
45938
|
-
|
|
45939
|
-
|
|
45940
|
-
|
|
45941
|
-
|
|
45942
|
-
|
|
45943
|
-
|
|
45944
|
-
|
|
46287
|
+
try {
|
|
46288
|
+
const client = new ApiClient();
|
|
46289
|
+
const projectId2 = await resolveProjectId(client, this.project);
|
|
46290
|
+
await client.request(`/v1/projects/${projectId2}/members`, {
|
|
46291
|
+
method: "POST",
|
|
46292
|
+
body: { email: this.email, role: role2 }
|
|
46293
|
+
});
|
|
46294
|
+
this.context.stdout.write(`added ${this.email} to ${this.project} as ${role2}
|
|
45945
46295
|
`);
|
|
45946
|
-
|
|
46296
|
+
return 0;
|
|
46297
|
+
} catch (err) {
|
|
46298
|
+
return handleExecError(this.context.stderr, err);
|
|
46299
|
+
}
|
|
45947
46300
|
}
|
|
45948
46301
|
};
|
|
45949
46302
|
var MemberRemoveCommand = class extends Command {
|
|
@@ -45952,21 +46305,25 @@ var MemberRemoveCommand = class extends Command {
|
|
|
45952
46305
|
project = options_exports.String();
|
|
45953
46306
|
email = options_exports.String();
|
|
45954
46307
|
async execute() {
|
|
45955
|
-
|
|
45956
|
-
|
|
45957
|
-
|
|
45958
|
-
|
|
45959
|
-
|
|
45960
|
-
|
|
46308
|
+
try {
|
|
46309
|
+
const client = new ApiClient();
|
|
46310
|
+
const projectId2 = await resolveProjectId(client, this.project);
|
|
46311
|
+
const members = await client.request(`/v1/projects/${projectId2}/members`);
|
|
46312
|
+
const target = members.members.find((m) => m.email === this.email);
|
|
46313
|
+
if (!target) {
|
|
46314
|
+
this.context.stderr.write(`keynv: ${this.email} is not a member of ${this.project}
|
|
45961
46315
|
`);
|
|
45962
|
-
|
|
45963
|
-
|
|
45964
|
-
|
|
45965
|
-
|
|
45966
|
-
|
|
45967
|
-
|
|
46316
|
+
return 1;
|
|
46317
|
+
}
|
|
46318
|
+
await client.request(`/v1/projects/${projectId2}/members/${target.user_id}`, {
|
|
46319
|
+
method: "DELETE"
|
|
46320
|
+
});
|
|
46321
|
+
this.context.stdout.write(`removed ${this.email} from ${this.project}
|
|
45968
46322
|
`);
|
|
45969
|
-
|
|
46323
|
+
return 0;
|
|
46324
|
+
} catch (err) {
|
|
46325
|
+
return handleExecError(this.context.stderr, err);
|
|
46326
|
+
}
|
|
45970
46327
|
}
|
|
45971
46328
|
};
|
|
45972
46329
|
var MemberListCommand = class extends Command {
|
|
@@ -45975,26 +46332,30 @@ var MemberListCommand = class extends Command {
|
|
|
45975
46332
|
project = options_exports.String();
|
|
45976
46333
|
json = options_exports.Boolean("--json", false);
|
|
45977
46334
|
async execute() {
|
|
45978
|
-
|
|
45979
|
-
|
|
45980
|
-
|
|
45981
|
-
|
|
45982
|
-
this.
|
|
46335
|
+
try {
|
|
46336
|
+
const client = new ApiClient();
|
|
46337
|
+
const projectId2 = await resolveProjectId(client, this.project);
|
|
46338
|
+
const data = await client.request(`/v1/projects/${projectId2}/members`);
|
|
46339
|
+
if (this.json) {
|
|
46340
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
45983
46341
|
`);
|
|
46342
|
+
return 0;
|
|
46343
|
+
}
|
|
46344
|
+
if (data.members.length === 0) {
|
|
46345
|
+
this.context.stdout.write("no members\n");
|
|
46346
|
+
return 0;
|
|
46347
|
+
}
|
|
46348
|
+
this.context.stdout.write(
|
|
46349
|
+
`${table(
|
|
46350
|
+
["email", "role", "granted_at"],
|
|
46351
|
+
data.members.map((m) => [m.email, m.role, m.granted_at])
|
|
46352
|
+
)}
|
|
46353
|
+
`
|
|
46354
|
+
);
|
|
45984
46355
|
return 0;
|
|
46356
|
+
} catch (err) {
|
|
46357
|
+
return handleExecError(this.context.stderr, err);
|
|
45985
46358
|
}
|
|
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
46359
|
}
|
|
45999
46360
|
};
|
|
46000
46361
|
var RedactCommand = class extends Command {
|
|
@@ -46045,9 +46406,9 @@ here (see the streaming-mode limitation in the redactor package).
|
|
|
46045
46406
|
`
|
|
46046
46407
|
});
|
|
46047
46408
|
async execute() {
|
|
46048
|
-
return new Promise((
|
|
46409
|
+
return new Promise((resolve4, reject) => {
|
|
46049
46410
|
const transform = createRedactStream();
|
|
46050
|
-
this.context.stdin.pipe(transform).pipe(this.context.stdout).on("error", reject).on("finish", () =>
|
|
46411
|
+
this.context.stdin.pipe(transform).pipe(this.context.stdout).on("error", reject).on("finish", () => resolve4(0));
|
|
46051
46412
|
this.context.stdin.on("error", reject);
|
|
46052
46413
|
});
|
|
46053
46414
|
}
|
|
@@ -46093,46 +46454,53 @@ var SecretCreateCommand = class extends Command {
|
|
|
46093
46454
|
});
|
|
46094
46455
|
stdin = options_exports.Boolean("--stdin", false);
|
|
46095
46456
|
async execute() {
|
|
46096
|
-
|
|
46097
|
-
|
|
46098
|
-
|
|
46099
|
-
|
|
46100
|
-
|
|
46101
|
-
if (!
|
|
46102
|
-
|
|
46103
|
-
|
|
46104
|
-
|
|
46105
|
-
|
|
46106
|
-
|
|
46107
|
-
|
|
46108
|
-
|
|
46109
|
-
|
|
46457
|
+
try {
|
|
46458
|
+
const client = new ApiClient();
|
|
46459
|
+
await client.ensureHydrated();
|
|
46460
|
+
let alias2 = this.alias;
|
|
46461
|
+
let value = this.value;
|
|
46462
|
+
if (!alias2) {
|
|
46463
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46464
|
+
try {
|
|
46465
|
+
const built = await promptNewSecret(client);
|
|
46466
|
+
if (!built) return 1;
|
|
46467
|
+
alias2 = built.alias;
|
|
46468
|
+
value = built.value;
|
|
46469
|
+
} catch (err) {
|
|
46470
|
+
if (err instanceof UserCancelled) return 130;
|
|
46471
|
+
throw err;
|
|
46472
|
+
}
|
|
46110
46473
|
}
|
|
46111
|
-
|
|
46112
|
-
|
|
46113
|
-
|
|
46114
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46474
|
+
const parsed = parseAlias(alias2);
|
|
46475
|
+
if (!parsed) {
|
|
46476
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46115
46477
|
${ALIAS_FORMAT_HINT}
|
|
46116
46478
|
`);
|
|
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);
|
|
46479
|
+
return 1;
|
|
46123
46480
|
}
|
|
46124
|
-
|
|
46125
|
-
|
|
46126
|
-
|
|
46127
|
-
|
|
46128
|
-
|
|
46129
|
-
|
|
46130
|
-
|
|
46131
|
-
|
|
46132
|
-
|
|
46133
|
-
|
|
46481
|
+
if (this.stdin) {
|
|
46482
|
+
const chunks = [];
|
|
46483
|
+
for await (const chunk of this.context.stdin) {
|
|
46484
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
46485
|
+
}
|
|
46486
|
+
value = Buffer.concat(chunks).toString("utf8").replace(/\n$/, "");
|
|
46487
|
+
} else if (value === void 0) {
|
|
46488
|
+
value = await promptHidden("value: ");
|
|
46489
|
+
}
|
|
46490
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46491
|
+
await client.request(
|
|
46492
|
+
`/v1/projects/${projectId2}/secrets`,
|
|
46493
|
+
{
|
|
46494
|
+
method: "POST",
|
|
46495
|
+
body: { env: parsed.environment, key: parsed.key, value }
|
|
46496
|
+
}
|
|
46497
|
+
);
|
|
46498
|
+
this.context.stdout.write(`created ${parsed.literal}
|
|
46134
46499
|
`);
|
|
46135
|
-
|
|
46500
|
+
return 0;
|
|
46501
|
+
} catch (err) {
|
|
46502
|
+
return handleExecError(this.context.stderr, err);
|
|
46503
|
+
}
|
|
46136
46504
|
}
|
|
46137
46505
|
};
|
|
46138
46506
|
var SecretGetCommand = class extends Command {
|
|
@@ -46143,40 +46511,44 @@ var SecretGetCommand = class extends Command {
|
|
|
46143
46511
|
alias = options_exports.String({ required: false });
|
|
46144
46512
|
json = options_exports.Boolean("--json", false);
|
|
46145
46513
|
async execute() {
|
|
46146
|
-
|
|
46147
|
-
|
|
46148
|
-
|
|
46149
|
-
|
|
46150
|
-
if (!
|
|
46151
|
-
|
|
46152
|
-
|
|
46153
|
-
|
|
46154
|
-
|
|
46155
|
-
|
|
46514
|
+
try {
|
|
46515
|
+
const client = new ApiClient();
|
|
46516
|
+
await client.ensureHydrated();
|
|
46517
|
+
let alias2 = this.alias;
|
|
46518
|
+
if (!alias2) {
|
|
46519
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46520
|
+
try {
|
|
46521
|
+
alias2 = await pickAliasInteractive(client) ?? void 0;
|
|
46522
|
+
} catch (err) {
|
|
46523
|
+
if (err instanceof UserCancelled) return 130;
|
|
46524
|
+
throw err;
|
|
46525
|
+
}
|
|
46526
|
+
if (!alias2) return 1;
|
|
46156
46527
|
}
|
|
46157
|
-
|
|
46158
|
-
|
|
46159
|
-
|
|
46160
|
-
if (!parsed) {
|
|
46161
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46528
|
+
const parsed = parseAlias(alias2);
|
|
46529
|
+
if (!parsed) {
|
|
46530
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46162
46531
|
${ALIAS_FORMAT_HINT}
|
|
46163
46532
|
`);
|
|
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
|
-
`
|
|
46533
|
+
return 1;
|
|
46534
|
+
}
|
|
46535
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46536
|
+
const data = await client.request(
|
|
46537
|
+
`/v1/projects/${projectId2}/secrets/${parsed.environment}/${parsed.key}`
|
|
46174
46538
|
);
|
|
46175
|
-
|
|
46176
|
-
|
|
46539
|
+
if (this.json) {
|
|
46540
|
+
this.context.stdout.write(
|
|
46541
|
+
`${JSON.stringify({ alias: data.alias, version: data.version, value: data.value })}
|
|
46542
|
+
`
|
|
46543
|
+
);
|
|
46544
|
+
} else {
|
|
46545
|
+
this.context.stdout.write(`${data.value}
|
|
46177
46546
|
`);
|
|
46547
|
+
}
|
|
46548
|
+
return 0;
|
|
46549
|
+
} catch (err) {
|
|
46550
|
+
return handleExecError(this.context.stderr, err);
|
|
46178
46551
|
}
|
|
46179
|
-
return 0;
|
|
46180
46552
|
}
|
|
46181
46553
|
};
|
|
46182
46554
|
var SecretListCommand = class extends Command {
|
|
@@ -46187,42 +46559,55 @@ var SecretListCommand = class extends Command {
|
|
|
46187
46559
|
project = options_exports.String({ required: false });
|
|
46188
46560
|
json = options_exports.Boolean("--json", false);
|
|
46189
46561
|
async execute() {
|
|
46190
|
-
|
|
46191
|
-
|
|
46192
|
-
|
|
46193
|
-
|
|
46194
|
-
if (!
|
|
46195
|
-
|
|
46196
|
-
|
|
46562
|
+
try {
|
|
46563
|
+
const client = new ApiClient();
|
|
46564
|
+
await client.ensureHydrated();
|
|
46565
|
+
let projectName = this.project;
|
|
46566
|
+
if (!projectName) {
|
|
46567
|
+
if (!isInteractive()) {
|
|
46568
|
+
this.context.stderr.write("keynv: missing <project>.\n");
|
|
46569
|
+
return 1;
|
|
46570
|
+
}
|
|
46571
|
+
try {
|
|
46572
|
+
const picked = await pickProject(client, "Project");
|
|
46573
|
+
if (!picked) return 1;
|
|
46574
|
+
projectName = picked.name;
|
|
46575
|
+
} catch (err) {
|
|
46576
|
+
if (err instanceof UserCancelled) return 130;
|
|
46577
|
+
throw err;
|
|
46578
|
+
}
|
|
46197
46579
|
}
|
|
46198
|
-
|
|
46199
|
-
|
|
46200
|
-
|
|
46201
|
-
|
|
46202
|
-
|
|
46203
|
-
|
|
46204
|
-
|
|
46580
|
+
let resolvedProjectName = projectName;
|
|
46581
|
+
if (projectName.startsWith("@")) {
|
|
46582
|
+
const parsed = parseAlias(projectName);
|
|
46583
|
+
if (parsed) {
|
|
46584
|
+
resolvedProjectName = parsed.project;
|
|
46585
|
+
} else {
|
|
46586
|
+
resolvedProjectName = projectName.slice(1).split(".")[0] ?? projectName;
|
|
46587
|
+
}
|
|
46205
46588
|
}
|
|
46206
|
-
|
|
46207
|
-
|
|
46208
|
-
|
|
46209
|
-
|
|
46210
|
-
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
46589
|
+
const projectId2 = await resolveProjectId(client, resolvedProjectName);
|
|
46590
|
+
const data = await client.request(`/v1/projects/${projectId2}/secrets`);
|
|
46591
|
+
if (this.json) {
|
|
46592
|
+
this.context.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
46211
46593
|
`);
|
|
46594
|
+
return 0;
|
|
46595
|
+
}
|
|
46596
|
+
if (data.secrets.length === 0) {
|
|
46597
|
+
this.context.stdout.write("no secrets\n");
|
|
46598
|
+
return 0;
|
|
46599
|
+
}
|
|
46600
|
+
this.context.stdout.write(
|
|
46601
|
+
`${table(
|
|
46602
|
+
["alias", "version", "created_at"],
|
|
46603
|
+
data.secrets.map((s) => [s.alias, String(s.version), s.created_at])
|
|
46604
|
+
)}
|
|
46605
|
+
`
|
|
46606
|
+
);
|
|
46212
46607
|
return 0;
|
|
46608
|
+
} catch (err) {
|
|
46609
|
+
return handleExecError(this.context.stderr, err);
|
|
46213
46610
|
}
|
|
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
46611
|
}
|
|
46227
46612
|
};
|
|
46228
46613
|
var SecretRotateCommand = class extends Command {
|
|
@@ -46232,46 +46617,50 @@ var SecretRotateCommand = class extends Command {
|
|
|
46232
46617
|
value = options_exports.String("--value");
|
|
46233
46618
|
stdin = options_exports.Boolean("--stdin", false);
|
|
46234
46619
|
async execute() {
|
|
46235
|
-
|
|
46236
|
-
|
|
46237
|
-
|
|
46238
|
-
|
|
46239
|
-
if (!
|
|
46240
|
-
|
|
46241
|
-
|
|
46242
|
-
|
|
46243
|
-
|
|
46244
|
-
|
|
46620
|
+
try {
|
|
46621
|
+
const client = new ApiClient();
|
|
46622
|
+
await client.ensureHydrated();
|
|
46623
|
+
let alias2 = this.alias;
|
|
46624
|
+
if (!alias2) {
|
|
46625
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46626
|
+
try {
|
|
46627
|
+
alias2 = await pickAliasInteractive(client) ?? void 0;
|
|
46628
|
+
} catch (err) {
|
|
46629
|
+
if (err instanceof UserCancelled) return 130;
|
|
46630
|
+
throw err;
|
|
46631
|
+
}
|
|
46632
|
+
if (!alias2) return 1;
|
|
46245
46633
|
}
|
|
46246
|
-
|
|
46247
|
-
|
|
46248
|
-
|
|
46249
|
-
if (!parsed) {
|
|
46250
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46634
|
+
const parsed = parseAlias(alias2);
|
|
46635
|
+
if (!parsed) {
|
|
46636
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46251
46637
|
${ALIAS_FORMAT_HINT}
|
|
46252
46638
|
`);
|
|
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);
|
|
46639
|
+
return 1;
|
|
46260
46640
|
}
|
|
46261
|
-
value
|
|
46262
|
-
|
|
46263
|
-
|
|
46264
|
-
|
|
46265
|
-
|
|
46266
|
-
|
|
46267
|
-
|
|
46268
|
-
|
|
46269
|
-
|
|
46270
|
-
|
|
46271
|
-
|
|
46272
|
-
|
|
46641
|
+
let value;
|
|
46642
|
+
if (this.stdin) {
|
|
46643
|
+
const chunks = [];
|
|
46644
|
+
for await (const chunk of this.context.stdin) {
|
|
46645
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
46646
|
+
}
|
|
46647
|
+
value = Buffer.concat(chunks).toString("utf8").replace(/\n$/, "");
|
|
46648
|
+
} else if (this.value !== void 0) {
|
|
46649
|
+
value = this.value;
|
|
46650
|
+
} else {
|
|
46651
|
+
value = await promptHidden("new value: ");
|
|
46652
|
+
}
|
|
46653
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46654
|
+
const data = await client.request(
|
|
46655
|
+
`/v1/projects/${projectId2}/secrets/${parsed.environment}/${parsed.key}/rotate`,
|
|
46656
|
+
{ method: "POST", body: { new_value: value } }
|
|
46657
|
+
);
|
|
46658
|
+
this.context.stdout.write(`rotated ${data.alias} \u2192 v${data.version}
|
|
46273
46659
|
`);
|
|
46274
|
-
|
|
46660
|
+
return 0;
|
|
46661
|
+
} catch (err) {
|
|
46662
|
+
return handleExecError(this.context.stderr, err);
|
|
46663
|
+
}
|
|
46275
46664
|
}
|
|
46276
46665
|
};
|
|
46277
46666
|
var SecretDeleteCommand = class extends Command {
|
|
@@ -46279,33 +46668,40 @@ var SecretDeleteCommand = class extends Command {
|
|
|
46279
46668
|
static usage = Command.Usage({ description: "Soft-delete a secret." });
|
|
46280
46669
|
alias = options_exports.String({ required: false });
|
|
46281
46670
|
async execute() {
|
|
46282
|
-
|
|
46283
|
-
|
|
46284
|
-
|
|
46285
|
-
|
|
46286
|
-
if (!
|
|
46287
|
-
|
|
46288
|
-
|
|
46289
|
-
|
|
46290
|
-
|
|
46291
|
-
|
|
46671
|
+
try {
|
|
46672
|
+
const client = new ApiClient();
|
|
46673
|
+
await client.ensureHydrated();
|
|
46674
|
+
let alias2 = this.alias;
|
|
46675
|
+
if (!alias2) {
|
|
46676
|
+
if (!isInteractive()) return missingAlias(this.context.stderr);
|
|
46677
|
+
try {
|
|
46678
|
+
alias2 = await pickAliasInteractive(client) ?? void 0;
|
|
46679
|
+
} catch (err) {
|
|
46680
|
+
if (err instanceof UserCancelled) return 130;
|
|
46681
|
+
throw err;
|
|
46682
|
+
}
|
|
46683
|
+
if (!alias2) return 1;
|
|
46292
46684
|
}
|
|
46293
|
-
|
|
46294
|
-
|
|
46295
|
-
|
|
46296
|
-
if (!parsed) {
|
|
46297
|
-
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46685
|
+
const parsed = parseAlias(alias2);
|
|
46686
|
+
if (!parsed) {
|
|
46687
|
+
this.context.stderr.write(`keynv: invalid alias '${alias2}'.
|
|
46298
46688
|
${ALIAS_FORMAT_HINT}
|
|
46299
46689
|
`);
|
|
46300
|
-
|
|
46301
|
-
|
|
46302
|
-
|
|
46303
|
-
|
|
46304
|
-
|
|
46305
|
-
|
|
46306
|
-
|
|
46690
|
+
return 1;
|
|
46691
|
+
}
|
|
46692
|
+
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46693
|
+
await client.request(
|
|
46694
|
+
`/v1/projects/${projectId2}/secrets/${parsed.environment}/${parsed.key}`,
|
|
46695
|
+
{
|
|
46696
|
+
method: "DELETE"
|
|
46697
|
+
}
|
|
46698
|
+
);
|
|
46699
|
+
this.context.stdout.write(`deleted ${parsed.literal}
|
|
46307
46700
|
`);
|
|
46308
|
-
|
|
46701
|
+
return 0;
|
|
46702
|
+
} catch (err) {
|
|
46703
|
+
return handleExecError(this.context.stderr, err);
|
|
46704
|
+
}
|
|
46309
46705
|
}
|
|
46310
46706
|
};
|
|
46311
46707
|
function generateSecret(bytes = 32) {
|
|
@@ -46367,8 +46763,8 @@ Non-interactive with --yes to skip prompts.
|
|
|
46367
46763
|
"# KEYNV_ARGON2_MEMORY_KIB=46080",
|
|
46368
46764
|
"# KEYNV_ARGON2_TIME_COST=3"
|
|
46369
46765
|
].join("\n");
|
|
46370
|
-
const { writeFileSync:
|
|
46371
|
-
|
|
46766
|
+
const { writeFileSync: writeFileSync5 } = await import('fs');
|
|
46767
|
+
writeFileSync5(outPath, `${contents}
|
|
46372
46768
|
`);
|
|
46373
46769
|
this.context.stdout.write(`Wrote ${outPath}
|
|
46374
46770
|
|
|
@@ -46434,7 +46830,7 @@ services:
|
|
|
46434
46830
|
volumes:
|
|
46435
46831
|
keynv-data:
|
|
46436
46832
|
`;
|
|
46437
|
-
|
|
46833
|
+
writeFileSync5("docker-compose.yml", composeContent);
|
|
46438
46834
|
this.context.stdout.write(
|
|
46439
46835
|
"\nWrote docker-compose.yml (update Litestream S3 config before deploying).\n"
|
|
46440
46836
|
);
|
|
@@ -46670,7 +47066,7 @@ var sshTester = {
|
|
|
46670
47066
|
async test(secret, target) {
|
|
46671
47067
|
const start = Date.now();
|
|
46672
47068
|
const { Client: Client2 } = await import('ssh2');
|
|
46673
|
-
return new Promise((
|
|
47069
|
+
return new Promise((resolve4) => {
|
|
46674
47070
|
const client = new Client2();
|
|
46675
47071
|
let settled = false;
|
|
46676
47072
|
const settle = (result) => {
|
|
@@ -46681,7 +47077,7 @@ var sshTester = {
|
|
|
46681
47077
|
client.end();
|
|
46682
47078
|
} catch {
|
|
46683
47079
|
}
|
|
46684
|
-
|
|
47080
|
+
resolve4(result);
|
|
46685
47081
|
};
|
|
46686
47082
|
client.once("ready", () => {
|
|
46687
47083
|
client.exec("true", (err, stream) => {
|
|
@@ -46747,12 +47143,12 @@ function sanitizeResult(result, secret) {
|
|
|
46747
47143
|
|
|
46748
47144
|
// ../../packages/testers/dist/run.js
|
|
46749
47145
|
function withTimeout(promise, ms) {
|
|
46750
|
-
return new Promise((
|
|
47146
|
+
return new Promise((resolve4, reject) => {
|
|
46751
47147
|
const t = setTimeout(() => reject(new Error(`tester timed out after ${ms}ms`)), ms);
|
|
46752
47148
|
t.unref();
|
|
46753
47149
|
promise.then((v2) => {
|
|
46754
47150
|
clearTimeout(t);
|
|
46755
|
-
|
|
47151
|
+
resolve4(v2);
|
|
46756
47152
|
}, (err) => {
|
|
46757
47153
|
clearTimeout(t);
|
|
46758
47154
|
reject(err);
|