@keynv/cli 0.1.0-rc.13 → 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 +655 -387
- 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
|
});
|
|
@@ -5656,7 +5657,16 @@ var init_http = __esm({
|
|
|
5656
5657
|
return this.creds;
|
|
5657
5658
|
}
|
|
5658
5659
|
async ensureHydrated() {
|
|
5659
|
-
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
|
+
}
|
|
5660
5670
|
}
|
|
5661
5671
|
async setCredentials(creds) {
|
|
5662
5672
|
this.creds = creds;
|
|
@@ -5678,21 +5688,40 @@ var init_http = __esm({
|
|
|
5678
5688
|
headers.authorization = `Bearer ${this.creds.access_token}`;
|
|
5679
5689
|
}
|
|
5680
5690
|
const url = this.creds ? buildUrl(this.creds.server_url, path, opts.query) : path;
|
|
5681
|
-
let res
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
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
|
+
}
|
|
5686
5706
|
if (res.status === 401 && this.creds && opts.authed !== false) {
|
|
5687
5707
|
const refreshed = await tryRefresh(this.creds);
|
|
5688
5708
|
if (refreshed) {
|
|
5689
5709
|
this.creds = refreshed;
|
|
5690
5710
|
headers.authorization = `Bearer ${refreshed.access_token}`;
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
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
|
+
}
|
|
5696
5725
|
}
|
|
5697
5726
|
}
|
|
5698
5727
|
if (res.status === 204) return void 0;
|
|
@@ -5891,6 +5920,121 @@ var init_envFile = __esm({
|
|
|
5891
5920
|
};
|
|
5892
5921
|
}
|
|
5893
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
|
+
});
|
|
5894
6038
|
|
|
5895
6039
|
// src/init/heuristics.ts
|
|
5896
6040
|
function shannonEntropyBits(s) {
|
|
@@ -6017,6 +6161,95 @@ var init_heuristics = __esm({
|
|
|
6017
6161
|
];
|
|
6018
6162
|
}
|
|
6019
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
|
+
});
|
|
6020
6253
|
|
|
6021
6254
|
// ../../node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
|
|
6022
6255
|
var getCodePointsLength, isFullWidth, isWideNotCJKTNotEmoji;
|
|
@@ -7172,210 +7405,6 @@ ${c2}
|
|
|
7172
7405
|
} }).prompt();
|
|
7173
7406
|
}
|
|
7174
7407
|
});
|
|
7175
|
-
function aiContextBody() {
|
|
7176
|
-
return `## keynv (secrets)
|
|
7177
|
-
|
|
7178
|
-
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.
|
|
7179
|
-
|
|
7180
|
-
### Mental model
|
|
7181
|
-
|
|
7182
|
-
- **\`.keynv.env\`** \u2014 checked into git, contains aliases. Safe to read, edit, commit.
|
|
7183
|
-
- **Vault** \u2014 holds the real values. The \`keynv\` CLI reads it on demand.
|
|
7184
|
-
- **\`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.
|
|
7185
|
-
- **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.
|
|
7186
|
-
|
|
7187
|
-
### What you should do
|
|
7188
|
-
|
|
7189
|
-
When the user asks about secrets or env vars, follow this decision tree:
|
|
7190
|
-
|
|
7191
|
-
| User intent | Run / suggest |
|
|
7192
|
-
|---|---|
|
|
7193
|
-
| "Add a new API key" / "set up a secret" | \`keynv secret create\` (interactive prompt picks project + env + key) |
|
|
7194
|
-
| "I have a \`.env\`, migrate it" | \`keynv init\` (you're seeing this file because that already happened) |
|
|
7195
|
-
| "Run the app / dev server / tests" | \`keynv exec -- <their existing command>\` (auto-loads \`.keynv.env\`) |
|
|
7196
|
-
| "Show me the value of X" | \`keynv secret get @alias\` \u2014 but copy to clipboard, do NOT print the value into chat / terminal |
|
|
7197
|
-
| "Rotate this key" | \`keynv secret rotate @alias\` |
|
|
7198
|
-
| "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\`) |
|
|
7199
|
-
| "Who has access?" | \`keynv member list <project>\` |
|
|
7200
|
-
|
|
7201
|
-
### Hard rules \u2014 do not violate
|
|
7202
|
-
|
|
7203
|
-
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.
|
|
7204
|
-
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.
|
|
7205
|
-
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.
|
|
7206
|
-
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.
|
|
7207
|
-
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.
|
|
7208
|
-
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.
|
|
7209
|
-
|
|
7210
|
-
### Quick reference
|
|
7211
|
-
|
|
7212
|
-
\`\`\`bash
|
|
7213
|
-
keynv # interactive TUI menu (pick projects, secrets, members)
|
|
7214
|
-
keynv exec -- <cmd> # run cmd with .keynv.env loaded
|
|
7215
|
-
keynv secret create # walk through creating a new secret
|
|
7216
|
-
keynv secret list <project> # list aliases (no values)
|
|
7217
|
-
keynv whoami # who am I logged in as
|
|
7218
|
-
keynv --help # full command list
|
|
7219
|
-
\`\`\`
|
|
7220
|
-
|
|
7221
|
-
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\`.`;
|
|
7222
|
-
}
|
|
7223
|
-
function renderKeynvBlock() {
|
|
7224
|
-
return `${KEYNV_BLOCK_START}
|
|
7225
|
-
${aiContextBody()}
|
|
7226
|
-
${KEYNV_BLOCK_END}`;
|
|
7227
|
-
}
|
|
7228
|
-
function writeAiContext(rootPath) {
|
|
7229
|
-
const path = join(rootPath, AGENTS_FILE_BASENAME);
|
|
7230
|
-
const block = renderKeynvBlock();
|
|
7231
|
-
if (!existsSync(path)) {
|
|
7232
|
-
const initial = `# Agent guidance for this project
|
|
7233
|
-
|
|
7234
|
-
${block}
|
|
7235
|
-
`;
|
|
7236
|
-
writeFileSync(path, initial);
|
|
7237
|
-
return "created";
|
|
7238
|
-
}
|
|
7239
|
-
const existing = readFileSync(path, "utf8");
|
|
7240
|
-
const startIdx = existing.indexOf(KEYNV_BLOCK_START);
|
|
7241
|
-
const endIdx = existing.indexOf(KEYNV_BLOCK_END);
|
|
7242
|
-
if (startIdx >= 0 && endIdx > startIdx) {
|
|
7243
|
-
const before = existing.slice(0, startIdx);
|
|
7244
|
-
const after = existing.slice(endIdx + KEYNV_BLOCK_END.length);
|
|
7245
|
-
const next = `${before}${block}${after}`;
|
|
7246
|
-
if (next === existing) return "unchanged";
|
|
7247
|
-
writeFileSync(path, next);
|
|
7248
|
-
return "updated";
|
|
7249
|
-
}
|
|
7250
|
-
const sep = existing.length === 0 ? "" : existing.endsWith("\n\n") ? "" : existing.endsWith("\n") ? "\n" : "\n\n";
|
|
7251
|
-
const trailingNewline = existing.endsWith("\n") ? "" : "\n";
|
|
7252
|
-
writeFileSync(path, `${existing}${trailingNewline}${sep}${block}
|
|
7253
|
-
`);
|
|
7254
|
-
return "appended";
|
|
7255
|
-
}
|
|
7256
|
-
var AGENTS_FILE_BASENAME, KEYNV_BLOCK_START, KEYNV_BLOCK_END;
|
|
7257
|
-
var init_aiContext = __esm({
|
|
7258
|
-
"src/init/aiContext.ts"() {
|
|
7259
|
-
AGENTS_FILE_BASENAME = "AGENTS.md";
|
|
7260
|
-
KEYNV_BLOCK_START = "<!-- keynv:start -- generated by `keynv init`; safe to leave intact, will be refreshed on re-run -->";
|
|
7261
|
-
KEYNV_BLOCK_END = "<!-- keynv:end -->";
|
|
7262
|
-
}
|
|
7263
|
-
});
|
|
7264
|
-
function findProjectRoot(startDir) {
|
|
7265
|
-
const result = walkUp(startDir, (dir) => {
|
|
7266
|
-
for (const marker of PROJECT_MARKERS) {
|
|
7267
|
-
if (existsSync(join(dir, marker))) {
|
|
7268
|
-
return { dir, marker };
|
|
7269
|
-
}
|
|
7270
|
-
}
|
|
7271
|
-
if (existsSync(join(dir, GIT_MARKER))) {
|
|
7272
|
-
return { dir, marker: GIT_MARKER };
|
|
7273
|
-
}
|
|
7274
|
-
return null;
|
|
7275
|
-
});
|
|
7276
|
-
if (!result) return null;
|
|
7277
|
-
return buildRoot(result.dir, result.marker);
|
|
7278
|
-
}
|
|
7279
|
-
function buildRoot(dir, marker) {
|
|
7280
|
-
let suggestedName = basename(dir);
|
|
7281
|
-
let scripts = null;
|
|
7282
|
-
let invalid = false;
|
|
7283
|
-
if (marker === "package.json" || existsSync(join(dir, "package.json"))) {
|
|
7284
|
-
try {
|
|
7285
|
-
const pkg = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
7286
|
-
if (typeof pkg.name === "string" && pkg.name.length > 0) {
|
|
7287
|
-
suggestedName = pkg.name.replace(/^@[^/]+\//, "");
|
|
7288
|
-
}
|
|
7289
|
-
if (pkg.scripts && typeof pkg.scripts === "object") {
|
|
7290
|
-
scripts = Object.fromEntries(
|
|
7291
|
-
Object.entries(pkg.scripts).filter(([, v2]) => typeof v2 === "string")
|
|
7292
|
-
);
|
|
7293
|
-
}
|
|
7294
|
-
} catch {
|
|
7295
|
-
invalid = true;
|
|
7296
|
-
}
|
|
7297
|
-
}
|
|
7298
|
-
return {
|
|
7299
|
-
path: dir,
|
|
7300
|
-
suggestedName,
|
|
7301
|
-
marker,
|
|
7302
|
-
packageJsonScripts: scripts,
|
|
7303
|
-
packageJsonInvalid: invalid
|
|
7304
|
-
};
|
|
7305
|
-
}
|
|
7306
|
-
function findEnvFiles(rootDir) {
|
|
7307
|
-
let entries;
|
|
7308
|
-
try {
|
|
7309
|
-
entries = readdirSync(rootDir);
|
|
7310
|
-
} catch {
|
|
7311
|
-
return [];
|
|
7312
|
-
}
|
|
7313
|
-
const hits = [];
|
|
7314
|
-
for (const name of entries) {
|
|
7315
|
-
if (!ENV_GLOB.test(name)) continue;
|
|
7316
|
-
if (ENV_EXAMPLE.test(name)) continue;
|
|
7317
|
-
if (name === KEYNV_ENV_BASENAME) continue;
|
|
7318
|
-
const full = join(rootDir, name);
|
|
7319
|
-
try {
|
|
7320
|
-
if (!statSync(full).isFile()) continue;
|
|
7321
|
-
} catch {
|
|
7322
|
-
continue;
|
|
7323
|
-
}
|
|
7324
|
-
const suffixMatch = name.match(/^\.env\.(.+)$/);
|
|
7325
|
-
const suffix = suffixMatch ? suffixMatch[1] : null;
|
|
7326
|
-
hits.push({ path: full, name, suffix, suggestedEnv: suggestedEnvForSuffix(suffix) });
|
|
7327
|
-
}
|
|
7328
|
-
hits.sort((a, b2) => {
|
|
7329
|
-
if (a.suffix === null) return -1;
|
|
7330
|
-
if (b2.suffix === null) return 1;
|
|
7331
|
-
return a.name.localeCompare(b2.name);
|
|
7332
|
-
});
|
|
7333
|
-
return hits;
|
|
7334
|
-
}
|
|
7335
|
-
function suggestedEnvForSuffix(suffix) {
|
|
7336
|
-
if (suffix === null) return "dev";
|
|
7337
|
-
switch (suffix) {
|
|
7338
|
-
case "local":
|
|
7339
|
-
case "development":
|
|
7340
|
-
case "dev":
|
|
7341
|
-
return "dev";
|
|
7342
|
-
case "production":
|
|
7343
|
-
case "prod":
|
|
7344
|
-
return "prod";
|
|
7345
|
-
case "staging":
|
|
7346
|
-
case "stage":
|
|
7347
|
-
return "staging";
|
|
7348
|
-
case "test":
|
|
7349
|
-
return "test";
|
|
7350
|
-
case "preview":
|
|
7351
|
-
return "preview";
|
|
7352
|
-
default:
|
|
7353
|
-
return suffix;
|
|
7354
|
-
}
|
|
7355
|
-
}
|
|
7356
|
-
function hasExistingKeynvEnv(rootDir) {
|
|
7357
|
-
return existsSync(join(rootDir, KEYNV_ENV_BASENAME));
|
|
7358
|
-
}
|
|
7359
|
-
var PROJECT_MARKERS, GIT_MARKER, ENV_GLOB, ENV_EXAMPLE, KEYNV_ENV_BASENAME;
|
|
7360
|
-
var init_detect = __esm({
|
|
7361
|
-
"src/init/detect.ts"() {
|
|
7362
|
-
init_fs();
|
|
7363
|
-
PROJECT_MARKERS = [
|
|
7364
|
-
"package.json",
|
|
7365
|
-
"pyproject.toml",
|
|
7366
|
-
"Cargo.toml",
|
|
7367
|
-
"go.mod",
|
|
7368
|
-
"pnpm-workspace.yaml",
|
|
7369
|
-
"deno.json",
|
|
7370
|
-
"deno.jsonc",
|
|
7371
|
-
"requirements.txt"
|
|
7372
|
-
];
|
|
7373
|
-
GIT_MARKER = ".git";
|
|
7374
|
-
ENV_GLOB = /^\.env(\.[A-Za-z0-9_-]+)?$/;
|
|
7375
|
-
ENV_EXAMPLE = /^\.env\.(example|sample|template|dist|defaults)$/;
|
|
7376
|
-
KEYNV_ENV_BASENAME = ".keynv.env";
|
|
7377
|
-
}
|
|
7378
|
-
});
|
|
7379
7408
|
|
|
7380
7409
|
// src/init/scriptWrap.ts
|
|
7381
7410
|
function analyzeScript(name, command) {
|
|
@@ -7596,6 +7625,14 @@ __export(init_exports, {
|
|
|
7596
7625
|
UserCancelled: () => UserCancelled,
|
|
7597
7626
|
runInitFlow: () => runInitFlow
|
|
7598
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
|
+
}
|
|
7599
7636
|
async function runInitFlow(client, opts) {
|
|
7600
7637
|
ge("keynv init");
|
|
7601
7638
|
const root = findProjectRoot(opts.cwd);
|
|
@@ -7754,7 +7791,7 @@ ${detail}`
|
|
|
7754
7791
|
if (!selected.has(`${env2}|${e2.name}`)) continue;
|
|
7755
7792
|
i++;
|
|
7756
7793
|
s.message(`Uploading (${i}/${totalToUpload}) [${env2}] ${e2.name}`);
|
|
7757
|
-
const aliasKey = e2.name
|
|
7794
|
+
const aliasKey = toAliasKey(e2.name);
|
|
7758
7795
|
try {
|
|
7759
7796
|
await client.request(`/v1/projects/${projectId2}/secrets`, {
|
|
7760
7797
|
method: "POST",
|
|
@@ -7812,6 +7849,30 @@ ${detail}`
|
|
|
7812
7849
|
R2.error(`Failed to write .keynv.env: ${err instanceof Error ? err.message : String(err)}`);
|
|
7813
7850
|
return { exitCode: 1 };
|
|
7814
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
|
+
}
|
|
7815
7876
|
try {
|
|
7816
7877
|
const outcome = writeAiContext(root.path);
|
|
7817
7878
|
if (outcome === "created") R2.success("Wrote AGENTS.md (so AI agents understand keynv)");
|
|
@@ -7848,7 +7909,8 @@ ${detail}`
|
|
|
7848
7909
|
if (otherEnvs.length > 0) {
|
|
7849
7910
|
const lines = otherEnvs.map((env2) => {
|
|
7850
7911
|
const count = uploadedByEnv.get(env2)?.size ?? 0;
|
|
7851
|
-
|
|
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)`;
|
|
7852
7914
|
});
|
|
7853
7915
|
Se(lines.join("\n"), "Secrets in other envs");
|
|
7854
7916
|
}
|
|
@@ -8098,7 +8160,7 @@ var init_tty = __esm({
|
|
|
8098
8160
|
}
|
|
8099
8161
|
});
|
|
8100
8162
|
function sleep(ms) {
|
|
8101
|
-
return new Promise((
|
|
8163
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
8102
8164
|
}
|
|
8103
8165
|
async function errorMessage(res, fallback) {
|
|
8104
8166
|
const text = await res.text();
|
|
@@ -8340,16 +8402,16 @@ async function runSecretMenu(client, project, alias2) {
|
|
|
8340
8402
|
async function copyToClipboard(value) {
|
|
8341
8403
|
const platform2 = process.platform;
|
|
8342
8404
|
const cmd = platform2 === "darwin" ? ["pbcopy", []] : platform2 === "win32" ? ["clip", []] : ["xclip", ["-selection", "clipboard"]];
|
|
8343
|
-
return new Promise((
|
|
8405
|
+
return new Promise((resolve4) => {
|
|
8344
8406
|
try {
|
|
8345
8407
|
const child = spawn(cmd[0], cmd[1], {
|
|
8346
8408
|
stdio: ["pipe", "ignore", "ignore"]
|
|
8347
8409
|
});
|
|
8348
|
-
child.on("error", () =>
|
|
8349
|
-
child.on("exit", (code) =>
|
|
8410
|
+
child.on("error", () => resolve4(false));
|
|
8411
|
+
child.on("exit", (code) => resolve4(code === 0));
|
|
8350
8412
|
child.stdin.end(value);
|
|
8351
8413
|
} catch {
|
|
8352
|
-
|
|
8414
|
+
resolve4(false);
|
|
8353
8415
|
}
|
|
8354
8416
|
});
|
|
8355
8417
|
}
|
|
@@ -25095,7 +25157,7 @@ var require_named_placeholders = __commonJS({
|
|
|
25095
25157
|
}
|
|
25096
25158
|
return s;
|
|
25097
25159
|
}
|
|
25098
|
-
function
|
|
25160
|
+
function join8(tree) {
|
|
25099
25161
|
if (tree.length === 1) {
|
|
25100
25162
|
return tree;
|
|
25101
25163
|
}
|
|
@@ -25121,7 +25183,7 @@ var require_named_placeholders = __commonJS({
|
|
|
25121
25183
|
if (cache2 && (tree = cache2.get(query))) {
|
|
25122
25184
|
return toArrayParams(tree, paramsObj);
|
|
25123
25185
|
}
|
|
25124
|
-
tree =
|
|
25186
|
+
tree = join8(parse(query));
|
|
25125
25187
|
if (cache2) {
|
|
25126
25188
|
cache2.set(query, tree);
|
|
25127
25189
|
}
|
|
@@ -25277,11 +25339,11 @@ var require_connection = __commonJS({
|
|
|
25277
25339
|
const config = this.config;
|
|
25278
25340
|
tracePromise(
|
|
25279
25341
|
connectChannel,
|
|
25280
|
-
() => new Promise((
|
|
25342
|
+
() => new Promise((resolve4, reject) => {
|
|
25281
25343
|
let onConnect, onError;
|
|
25282
25344
|
onConnect = (param) => {
|
|
25283
25345
|
this.removeListener("error", onError);
|
|
25284
|
-
|
|
25346
|
+
resolve4(param);
|
|
25285
25347
|
};
|
|
25286
25348
|
onError = (err) => {
|
|
25287
25349
|
this.removeListener("connect", onConnect);
|
|
@@ -25706,9 +25768,9 @@ var require_connection = __commonJS({
|
|
|
25706
25768
|
} else if (shouldTrace(queryChannel)) {
|
|
25707
25769
|
tracePromise(
|
|
25708
25770
|
queryChannel,
|
|
25709
|
-
() => new Promise((
|
|
25771
|
+
() => new Promise((resolve4, reject) => {
|
|
25710
25772
|
cmdQuery.once("error", reject);
|
|
25711
|
-
cmdQuery.once("end", () =>
|
|
25773
|
+
cmdQuery.once("end", () => resolve4());
|
|
25712
25774
|
this.addCommand(cmdQuery);
|
|
25713
25775
|
}),
|
|
25714
25776
|
() => {
|
|
@@ -25855,12 +25917,12 @@ var require_connection = __commonJS({
|
|
|
25855
25917
|
} else if (shouldTrace(executeChannel)) {
|
|
25856
25918
|
tracePromise(
|
|
25857
25919
|
executeChannel,
|
|
25858
|
-
() => new Promise((
|
|
25920
|
+
() => new Promise((resolve4, reject) => {
|
|
25859
25921
|
prepareAndExecute((err) => {
|
|
25860
25922
|
executeCommand.emit("error", err);
|
|
25861
25923
|
});
|
|
25862
25924
|
executeCommand.once("error", reject);
|
|
25863
|
-
executeCommand.once("end", () =>
|
|
25925
|
+
executeCommand.once("end", () => resolve4());
|
|
25864
25926
|
}),
|
|
25865
25927
|
() => {
|
|
25866
25928
|
const server = getServerContext(this.config);
|
|
@@ -26125,13 +26187,13 @@ var require_capture_local_err = __commonJS({
|
|
|
26125
26187
|
var require_make_done_cb = __commonJS({
|
|
26126
26188
|
"../../node_modules/.pnpm/mysql2@3.22.3_@types+node@24.12.3/node_modules/mysql2/lib/promise/make_done_cb.js"(exports, module) {
|
|
26127
26189
|
var { applyCapturedStack } = require_capture_local_err();
|
|
26128
|
-
function makeDoneCb(
|
|
26190
|
+
function makeDoneCb(resolve4, reject, stackHolder) {
|
|
26129
26191
|
return function(err, rows, fields) {
|
|
26130
26192
|
if (err) {
|
|
26131
26193
|
applyCapturedStack(err, stackHolder);
|
|
26132
26194
|
reject(err);
|
|
26133
26195
|
} else {
|
|
26134
|
-
|
|
26196
|
+
resolve4([rows, fields]);
|
|
26135
26197
|
}
|
|
26136
26198
|
};
|
|
26137
26199
|
}
|
|
@@ -26154,8 +26216,8 @@ var require_prepared_statement_info = __commonJS({
|
|
|
26154
26216
|
const stackHolder = captureStackHolder(
|
|
26155
26217
|
_PromisePreparedStatementInfo.prototype.execute
|
|
26156
26218
|
);
|
|
26157
|
-
return new this.Promise((
|
|
26158
|
-
const done = makeDoneCb(
|
|
26219
|
+
return new this.Promise((resolve4, reject) => {
|
|
26220
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26159
26221
|
if (parameters) {
|
|
26160
26222
|
s.execute(parameters, done);
|
|
26161
26223
|
} else {
|
|
@@ -26164,9 +26226,9 @@ var require_prepared_statement_info = __commonJS({
|
|
|
26164
26226
|
});
|
|
26165
26227
|
}
|
|
26166
26228
|
close() {
|
|
26167
|
-
return new this.Promise((
|
|
26229
|
+
return new this.Promise((resolve4) => {
|
|
26168
26230
|
this.statement.close();
|
|
26169
|
-
|
|
26231
|
+
resolve4();
|
|
26170
26232
|
});
|
|
26171
26233
|
}
|
|
26172
26234
|
};
|
|
@@ -26237,8 +26299,8 @@ var require_connection2 = __commonJS({
|
|
|
26237
26299
|
"Callback function is not available with promise clients."
|
|
26238
26300
|
);
|
|
26239
26301
|
}
|
|
26240
|
-
return new this.Promise((
|
|
26241
|
-
const done = makeDoneCb(
|
|
26302
|
+
return new this.Promise((resolve4, reject) => {
|
|
26303
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26242
26304
|
if (params !== void 0) {
|
|
26243
26305
|
c2.query(query, params, done);
|
|
26244
26306
|
} else {
|
|
@@ -26254,8 +26316,8 @@ var require_connection2 = __commonJS({
|
|
|
26254
26316
|
"Callback function is not available with promise clients."
|
|
26255
26317
|
);
|
|
26256
26318
|
}
|
|
26257
|
-
return new this.Promise((
|
|
26258
|
-
const done = makeDoneCb(
|
|
26319
|
+
return new this.Promise((resolve4, reject) => {
|
|
26320
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26259
26321
|
if (params !== void 0) {
|
|
26260
26322
|
c2.execute(query, params, done);
|
|
26261
26323
|
} else {
|
|
@@ -26264,8 +26326,8 @@ var require_connection2 = __commonJS({
|
|
|
26264
26326
|
});
|
|
26265
26327
|
}
|
|
26266
26328
|
end() {
|
|
26267
|
-
return new this.Promise((
|
|
26268
|
-
this.connection.end(
|
|
26329
|
+
return new this.Promise((resolve4) => {
|
|
26330
|
+
this.connection.end(resolve4);
|
|
26269
26331
|
});
|
|
26270
26332
|
}
|
|
26271
26333
|
async [Symbol.asyncDispose]() {
|
|
@@ -26278,16 +26340,16 @@ var require_connection2 = __commonJS({
|
|
|
26278
26340
|
const stackHolder = captureStackHolder(
|
|
26279
26341
|
_PromiseConnection.prototype.beginTransaction
|
|
26280
26342
|
);
|
|
26281
|
-
return new this.Promise((
|
|
26282
|
-
const done = makeDoneCb(
|
|
26343
|
+
return new this.Promise((resolve4, reject) => {
|
|
26344
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26283
26345
|
c2.beginTransaction(done);
|
|
26284
26346
|
});
|
|
26285
26347
|
}
|
|
26286
26348
|
commit() {
|
|
26287
26349
|
const c2 = this.connection;
|
|
26288
26350
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.commit);
|
|
26289
|
-
return new this.Promise((
|
|
26290
|
-
const done = makeDoneCb(
|
|
26351
|
+
return new this.Promise((resolve4, reject) => {
|
|
26352
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26291
26353
|
c2.commit(done);
|
|
26292
26354
|
});
|
|
26293
26355
|
}
|
|
@@ -26296,21 +26358,21 @@ var require_connection2 = __commonJS({
|
|
|
26296
26358
|
const stackHolder = captureStackHolder(
|
|
26297
26359
|
_PromiseConnection.prototype.rollback
|
|
26298
26360
|
);
|
|
26299
|
-
return new this.Promise((
|
|
26300
|
-
const done = makeDoneCb(
|
|
26361
|
+
return new this.Promise((resolve4, reject) => {
|
|
26362
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26301
26363
|
c2.rollback(done);
|
|
26302
26364
|
});
|
|
26303
26365
|
}
|
|
26304
26366
|
ping() {
|
|
26305
26367
|
const c2 = this.connection;
|
|
26306
26368
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.ping);
|
|
26307
|
-
return new this.Promise((
|
|
26369
|
+
return new this.Promise((resolve4, reject) => {
|
|
26308
26370
|
c2.ping((err) => {
|
|
26309
26371
|
if (err) {
|
|
26310
26372
|
applyCapturedStack(err, stackHolder);
|
|
26311
26373
|
reject(err);
|
|
26312
26374
|
} else {
|
|
26313
|
-
|
|
26375
|
+
resolve4(true);
|
|
26314
26376
|
}
|
|
26315
26377
|
});
|
|
26316
26378
|
});
|
|
@@ -26318,13 +26380,13 @@ var require_connection2 = __commonJS({
|
|
|
26318
26380
|
reset() {
|
|
26319
26381
|
const c2 = this.connection;
|
|
26320
26382
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.reset);
|
|
26321
|
-
return new this.Promise((
|
|
26383
|
+
return new this.Promise((resolve4, reject) => {
|
|
26322
26384
|
c2.reset((err) => {
|
|
26323
26385
|
if (err) {
|
|
26324
26386
|
applyCapturedStack(err, stackHolder);
|
|
26325
26387
|
reject(err);
|
|
26326
26388
|
} else {
|
|
26327
|
-
|
|
26389
|
+
resolve4();
|
|
26328
26390
|
}
|
|
26329
26391
|
});
|
|
26330
26392
|
});
|
|
@@ -26332,13 +26394,13 @@ var require_connection2 = __commonJS({
|
|
|
26332
26394
|
connect() {
|
|
26333
26395
|
const c2 = this.connection;
|
|
26334
26396
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.connect);
|
|
26335
|
-
return new this.Promise((
|
|
26397
|
+
return new this.Promise((resolve4, reject) => {
|
|
26336
26398
|
c2.connect((err, param) => {
|
|
26337
26399
|
if (err) {
|
|
26338
26400
|
applyCapturedStack(err, stackHolder);
|
|
26339
26401
|
reject(err);
|
|
26340
26402
|
} else {
|
|
26341
|
-
|
|
26403
|
+
resolve4(param);
|
|
26342
26404
|
}
|
|
26343
26405
|
});
|
|
26344
26406
|
});
|
|
@@ -26347,7 +26409,7 @@ var require_connection2 = __commonJS({
|
|
|
26347
26409
|
const c2 = this.connection;
|
|
26348
26410
|
const promiseImpl = this.Promise;
|
|
26349
26411
|
const stackHolder = captureStackHolder(_PromiseConnection.prototype.prepare);
|
|
26350
|
-
return new this.Promise((
|
|
26412
|
+
return new this.Promise((resolve4, reject) => {
|
|
26351
26413
|
c2.prepare(options, (err, statement) => {
|
|
26352
26414
|
if (err) {
|
|
26353
26415
|
applyCapturedStack(err, stackHolder);
|
|
@@ -26357,7 +26419,7 @@ var require_connection2 = __commonJS({
|
|
|
26357
26419
|
statement,
|
|
26358
26420
|
promiseImpl
|
|
26359
26421
|
);
|
|
26360
|
-
|
|
26422
|
+
resolve4(wrappedStatement);
|
|
26361
26423
|
}
|
|
26362
26424
|
});
|
|
26363
26425
|
});
|
|
@@ -26367,13 +26429,13 @@ var require_connection2 = __commonJS({
|
|
|
26367
26429
|
const stackHolder = captureStackHolder(
|
|
26368
26430
|
_PromiseConnection.prototype.changeUser
|
|
26369
26431
|
);
|
|
26370
|
-
return new this.Promise((
|
|
26432
|
+
return new this.Promise((resolve4, reject) => {
|
|
26371
26433
|
c2.changeUser(options, (err) => {
|
|
26372
26434
|
if (err) {
|
|
26373
26435
|
applyCapturedStack(err, stackHolder);
|
|
26374
26436
|
reject(err);
|
|
26375
26437
|
} else {
|
|
26376
|
-
|
|
26438
|
+
resolve4();
|
|
26377
26439
|
}
|
|
26378
26440
|
});
|
|
26379
26441
|
});
|
|
@@ -26835,12 +26897,12 @@ var require_pool2 = __commonJS({
|
|
|
26835
26897
|
}
|
|
26836
26898
|
getConnection() {
|
|
26837
26899
|
const corePool = this.pool;
|
|
26838
|
-
return new this.Promise((
|
|
26900
|
+
return new this.Promise((resolve4, reject) => {
|
|
26839
26901
|
corePool.getConnection((err, coreConnection) => {
|
|
26840
26902
|
if (err) {
|
|
26841
26903
|
reject(err);
|
|
26842
26904
|
} else {
|
|
26843
|
-
|
|
26905
|
+
resolve4(new PromisePoolConnection(coreConnection, this.Promise));
|
|
26844
26906
|
}
|
|
26845
26907
|
});
|
|
26846
26908
|
});
|
|
@@ -26856,8 +26918,8 @@ var require_pool2 = __commonJS({
|
|
|
26856
26918
|
"Callback function is not available with promise clients."
|
|
26857
26919
|
);
|
|
26858
26920
|
}
|
|
26859
|
-
return new this.Promise((
|
|
26860
|
-
const done = makeDoneCb(
|
|
26921
|
+
return new this.Promise((resolve4, reject) => {
|
|
26922
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26861
26923
|
if (args !== void 0) {
|
|
26862
26924
|
corePool.query(sql, args, done);
|
|
26863
26925
|
} else {
|
|
@@ -26873,8 +26935,8 @@ var require_pool2 = __commonJS({
|
|
|
26873
26935
|
"Callback function is not available with promise clients."
|
|
26874
26936
|
);
|
|
26875
26937
|
}
|
|
26876
|
-
return new this.Promise((
|
|
26877
|
-
const done = makeDoneCb(
|
|
26938
|
+
return new this.Promise((resolve4, reject) => {
|
|
26939
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
26878
26940
|
if (args) {
|
|
26879
26941
|
corePool.execute(sql, args, done);
|
|
26880
26942
|
} else {
|
|
@@ -26885,13 +26947,13 @@ var require_pool2 = __commonJS({
|
|
|
26885
26947
|
end() {
|
|
26886
26948
|
const corePool = this.pool;
|
|
26887
26949
|
const stackHolder = captureStackHolder(_PromisePool.prototype.end);
|
|
26888
|
-
return new this.Promise((
|
|
26950
|
+
return new this.Promise((resolve4, reject) => {
|
|
26889
26951
|
corePool.end((err) => {
|
|
26890
26952
|
if (err) {
|
|
26891
26953
|
applyCapturedStack(err, stackHolder);
|
|
26892
26954
|
reject(err);
|
|
26893
26955
|
} else {
|
|
26894
|
-
|
|
26956
|
+
resolve4();
|
|
26895
26957
|
}
|
|
26896
26958
|
});
|
|
26897
26959
|
});
|
|
@@ -27316,12 +27378,12 @@ var require_pool_cluster2 = __commonJS({
|
|
|
27316
27378
|
}
|
|
27317
27379
|
getConnection() {
|
|
27318
27380
|
const corePoolNamespace = this.poolNamespace;
|
|
27319
|
-
return new this.Promise((
|
|
27381
|
+
return new this.Promise((resolve4, reject) => {
|
|
27320
27382
|
corePoolNamespace.getConnection((err, coreConnection) => {
|
|
27321
27383
|
if (err) {
|
|
27322
27384
|
reject(err);
|
|
27323
27385
|
} else {
|
|
27324
|
-
|
|
27386
|
+
resolve4(new PromisePoolConnection(coreConnection, this.Promise));
|
|
27325
27387
|
}
|
|
27326
27388
|
});
|
|
27327
27389
|
});
|
|
@@ -27336,8 +27398,8 @@ var require_pool_cluster2 = __commonJS({
|
|
|
27336
27398
|
"Callback function is not available with promise clients."
|
|
27337
27399
|
);
|
|
27338
27400
|
}
|
|
27339
|
-
return new this.Promise((
|
|
27340
|
-
const done = makeDoneCb(
|
|
27401
|
+
return new this.Promise((resolve4, reject) => {
|
|
27402
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27341
27403
|
corePoolNamespace.query(sql, values, done);
|
|
27342
27404
|
});
|
|
27343
27405
|
}
|
|
@@ -27351,8 +27413,8 @@ var require_pool_cluster2 = __commonJS({
|
|
|
27351
27413
|
"Callback function is not available with promise clients."
|
|
27352
27414
|
);
|
|
27353
27415
|
}
|
|
27354
|
-
return new this.Promise((
|
|
27355
|
-
const done = makeDoneCb(
|
|
27416
|
+
return new this.Promise((resolve4, reject) => {
|
|
27417
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27356
27418
|
corePoolNamespace.execute(sql, values, done);
|
|
27357
27419
|
});
|
|
27358
27420
|
}
|
|
@@ -27390,9 +27452,9 @@ var require_promise = __commonJS({
|
|
|
27390
27452
|
"no Promise implementation available.Use promise-enabled node version or pass userland Promise implementation as parameter, for example: { Promise: require('bluebird') }"
|
|
27391
27453
|
);
|
|
27392
27454
|
}
|
|
27393
|
-
return new thePromise((
|
|
27455
|
+
return new thePromise((resolve4, reject) => {
|
|
27394
27456
|
coreConnection.once("connect", () => {
|
|
27395
|
-
|
|
27457
|
+
resolve4(new PromiseConnection(coreConnection, thePromise));
|
|
27396
27458
|
});
|
|
27397
27459
|
coreConnection.once("error", (err) => {
|
|
27398
27460
|
applyCapturedStack(err, stackHolder);
|
|
@@ -27419,7 +27481,7 @@ var require_promise = __commonJS({
|
|
|
27419
27481
|
}
|
|
27420
27482
|
getConnection(pattern, selector) {
|
|
27421
27483
|
const corePoolCluster = this.poolCluster;
|
|
27422
|
-
return new this.Promise((
|
|
27484
|
+
return new this.Promise((resolve4, reject) => {
|
|
27423
27485
|
corePoolCluster.getConnection(
|
|
27424
27486
|
pattern,
|
|
27425
27487
|
selector,
|
|
@@ -27427,7 +27489,7 @@ var require_promise = __commonJS({
|
|
|
27427
27489
|
if (err) {
|
|
27428
27490
|
reject(err);
|
|
27429
27491
|
} else {
|
|
27430
|
-
|
|
27492
|
+
resolve4(new PromisePoolConnection(coreConnection, this.Promise));
|
|
27431
27493
|
}
|
|
27432
27494
|
}
|
|
27433
27495
|
);
|
|
@@ -27441,8 +27503,8 @@ var require_promise = __commonJS({
|
|
|
27441
27503
|
"Callback function is not available with promise clients."
|
|
27442
27504
|
);
|
|
27443
27505
|
}
|
|
27444
|
-
return new this.Promise((
|
|
27445
|
-
const done = makeDoneCb(
|
|
27506
|
+
return new this.Promise((resolve4, reject) => {
|
|
27507
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27446
27508
|
corePoolCluster.query(sql, args, done);
|
|
27447
27509
|
});
|
|
27448
27510
|
}
|
|
@@ -27456,8 +27518,8 @@ var require_promise = __commonJS({
|
|
|
27456
27518
|
"Callback function is not available with promise clients."
|
|
27457
27519
|
);
|
|
27458
27520
|
}
|
|
27459
|
-
return new this.Promise((
|
|
27460
|
-
const done = makeDoneCb(
|
|
27521
|
+
return new this.Promise((resolve4, reject) => {
|
|
27522
|
+
const done = makeDoneCb(resolve4, reject, stackHolder);
|
|
27461
27523
|
corePoolCluster.execute(sql, args, done);
|
|
27462
27524
|
});
|
|
27463
27525
|
}
|
|
@@ -27470,13 +27532,13 @@ var require_promise = __commonJS({
|
|
|
27470
27532
|
end() {
|
|
27471
27533
|
const corePoolCluster = this.poolCluster;
|
|
27472
27534
|
const stackHolder = captureStackHolder(_PromisePoolCluster.prototype.end);
|
|
27473
|
-
return new this.Promise((
|
|
27535
|
+
return new this.Promise((resolve4, reject) => {
|
|
27474
27536
|
corePoolCluster.end((err) => {
|
|
27475
27537
|
if (err) {
|
|
27476
27538
|
applyCapturedStack(err, stackHolder);
|
|
27477
27539
|
reject(err);
|
|
27478
27540
|
} else {
|
|
27479
|
-
|
|
27541
|
+
resolve4();
|
|
27480
27542
|
}
|
|
27481
27543
|
});
|
|
27482
27544
|
});
|
|
@@ -30551,7 +30613,7 @@ var require_dist = __commonJS({
|
|
|
30551
30613
|
function parse(stream, callback) {
|
|
30552
30614
|
const parser = new parser_1.Parser();
|
|
30553
30615
|
stream.on("data", (buffer) => parser.parse(buffer, callback));
|
|
30554
|
-
return new Promise((
|
|
30616
|
+
return new Promise((resolve4) => stream.on("end", () => resolve4()));
|
|
30555
30617
|
}
|
|
30556
30618
|
exports.parse = parse;
|
|
30557
30619
|
}
|
|
@@ -31276,12 +31338,12 @@ var require_client2 = __commonJS({
|
|
|
31276
31338
|
this._connect(callback);
|
|
31277
31339
|
return;
|
|
31278
31340
|
}
|
|
31279
|
-
return new this._Promise((
|
|
31341
|
+
return new this._Promise((resolve4, reject) => {
|
|
31280
31342
|
this._connect((error) => {
|
|
31281
31343
|
if (error) {
|
|
31282
31344
|
reject(error);
|
|
31283
31345
|
} else {
|
|
31284
|
-
|
|
31346
|
+
resolve4(this);
|
|
31285
31347
|
}
|
|
31286
31348
|
});
|
|
31287
31349
|
});
|
|
@@ -31627,8 +31689,8 @@ var require_client2 = __commonJS({
|
|
|
31627
31689
|
readTimeout = config.query_timeout || this.connectionParameters.query_timeout;
|
|
31628
31690
|
query = new Query2(config, values, callback);
|
|
31629
31691
|
if (!query.callback) {
|
|
31630
|
-
result = new this._Promise((
|
|
31631
|
-
query.callback = (err, res) => err ? reject(err) :
|
|
31692
|
+
result = new this._Promise((resolve4, reject) => {
|
|
31693
|
+
query.callback = (err, res) => err ? reject(err) : resolve4(res);
|
|
31632
31694
|
}).catch((err) => {
|
|
31633
31695
|
Error.captureStackTrace(err);
|
|
31634
31696
|
throw err;
|
|
@@ -31705,8 +31767,8 @@ var require_client2 = __commonJS({
|
|
|
31705
31767
|
if (cb) {
|
|
31706
31768
|
this.connection.once("end", cb);
|
|
31707
31769
|
} else {
|
|
31708
|
-
return new this._Promise((
|
|
31709
|
-
this.connection.once("end",
|
|
31770
|
+
return new this._Promise((resolve4) => {
|
|
31771
|
+
this.connection.once("end", resolve4);
|
|
31710
31772
|
});
|
|
31711
31773
|
}
|
|
31712
31774
|
}
|
|
@@ -31754,8 +31816,8 @@ var require_pg_pool = __commonJS({
|
|
|
31754
31816
|
const cb = function(err, client) {
|
|
31755
31817
|
err ? rej(err) : res(client);
|
|
31756
31818
|
};
|
|
31757
|
-
const result = new Promise2(function(
|
|
31758
|
-
res =
|
|
31819
|
+
const result = new Promise2(function(resolve4, reject) {
|
|
31820
|
+
res = resolve4;
|
|
31759
31821
|
rej = reject;
|
|
31760
31822
|
}).catch((err) => {
|
|
31761
31823
|
Error.captureStackTrace(err);
|
|
@@ -31816,7 +31878,7 @@ var require_pg_pool = __commonJS({
|
|
|
31816
31878
|
if (typeof Promise2.try === "function") {
|
|
31817
31879
|
return Promise2.try(f);
|
|
31818
31880
|
}
|
|
31819
|
-
return new Promise2((
|
|
31881
|
+
return new Promise2((resolve4) => resolve4(f()));
|
|
31820
31882
|
}
|
|
31821
31883
|
_isFull() {
|
|
31822
31884
|
return this._clients.length >= this.options.max;
|
|
@@ -32208,8 +32270,8 @@ var require_query4 = __commonJS({
|
|
|
32208
32270
|
NativeQuery.prototype._getPromise = function() {
|
|
32209
32271
|
if (this._promise) return this._promise;
|
|
32210
32272
|
this._promise = new Promise(
|
|
32211
|
-
function(
|
|
32212
|
-
this._once("end",
|
|
32273
|
+
function(resolve4, reject) {
|
|
32274
|
+
this._once("end", resolve4);
|
|
32213
32275
|
this._once("error", reject);
|
|
32214
32276
|
}.bind(this)
|
|
32215
32277
|
);
|
|
@@ -32386,12 +32448,12 @@ var require_client3 = __commonJS({
|
|
|
32386
32448
|
this._connect(callback);
|
|
32387
32449
|
return;
|
|
32388
32450
|
}
|
|
32389
|
-
return new this._Promise((
|
|
32451
|
+
return new this._Promise((resolve4, reject) => {
|
|
32390
32452
|
this._connect((error) => {
|
|
32391
32453
|
if (error) {
|
|
32392
32454
|
reject(error);
|
|
32393
32455
|
} else {
|
|
32394
|
-
|
|
32456
|
+
resolve4(this);
|
|
32395
32457
|
}
|
|
32396
32458
|
});
|
|
32397
32459
|
});
|
|
@@ -32415,8 +32477,8 @@ var require_client3 = __commonJS({
|
|
|
32415
32477
|
query = new NativeQuery(config, values, callback);
|
|
32416
32478
|
if (!query.callback) {
|
|
32417
32479
|
let resolveOut, rejectOut;
|
|
32418
|
-
result = new this._Promise((
|
|
32419
|
-
resolveOut =
|
|
32480
|
+
result = new this._Promise((resolve4, reject) => {
|
|
32481
|
+
resolveOut = resolve4;
|
|
32420
32482
|
rejectOut = reject;
|
|
32421
32483
|
}).catch((err) => {
|
|
32422
32484
|
Error.captureStackTrace(err);
|
|
@@ -32476,8 +32538,8 @@ var require_client3 = __commonJS({
|
|
|
32476
32538
|
}
|
|
32477
32539
|
let result;
|
|
32478
32540
|
if (!cb) {
|
|
32479
|
-
result = new this._Promise(function(
|
|
32480
|
-
cb = (err) => err ? reject(err) :
|
|
32541
|
+
result = new this._Promise(function(resolve4, reject) {
|
|
32542
|
+
cb = (err) => err ? reject(err) : resolve4();
|
|
32481
32543
|
});
|
|
32482
32544
|
}
|
|
32483
32545
|
this.native.end(function() {
|
|
@@ -36400,8 +36462,8 @@ var require_common = __commonJS({
|
|
|
36400
36462
|
}
|
|
36401
36463
|
return debug2;
|
|
36402
36464
|
}
|
|
36403
|
-
function extend(namespace,
|
|
36404
|
-
const newDebug = createDebug(this.namespace + (typeof
|
|
36465
|
+
function extend(namespace, delimiter2) {
|
|
36466
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter2 === "undefined" ? ":" : delimiter2) + namespace);
|
|
36405
36467
|
newDebug.log = this.log;
|
|
36406
36468
|
return newDebug;
|
|
36407
36469
|
}
|
|
@@ -37584,7 +37646,7 @@ var require_Command = __commonJS({
|
|
|
37584
37646
|
}
|
|
37585
37647
|
}
|
|
37586
37648
|
initPromise() {
|
|
37587
|
-
const promise = new Promise((
|
|
37649
|
+
const promise = new Promise((resolve4, reject) => {
|
|
37588
37650
|
if (!this.transformed) {
|
|
37589
37651
|
this.transformed = true;
|
|
37590
37652
|
const transformer = _Command._transformer.argument[this.name];
|
|
@@ -37593,7 +37655,7 @@ var require_Command = __commonJS({
|
|
|
37593
37655
|
}
|
|
37594
37656
|
this.stringifyArguments();
|
|
37595
37657
|
}
|
|
37596
|
-
this.resolve = this._convertValue(
|
|
37658
|
+
this.resolve = this._convertValue(resolve4);
|
|
37597
37659
|
this.reject = (err) => {
|
|
37598
37660
|
this._clearTimers();
|
|
37599
37661
|
if (this.errorStack) {
|
|
@@ -37626,11 +37688,11 @@ var require_Command = __commonJS({
|
|
|
37626
37688
|
/**
|
|
37627
37689
|
* Convert the value from buffer to the target encoding.
|
|
37628
37690
|
*/
|
|
37629
|
-
_convertValue(
|
|
37691
|
+
_convertValue(resolve4) {
|
|
37630
37692
|
return (value) => {
|
|
37631
37693
|
try {
|
|
37632
37694
|
this._clearTimers();
|
|
37633
|
-
|
|
37695
|
+
resolve4(this.transformReply(value));
|
|
37634
37696
|
this.isResolved = true;
|
|
37635
37697
|
} catch (err) {
|
|
37636
37698
|
this.reject(err);
|
|
@@ -37908,13 +37970,13 @@ var require_autoPipelining = __commonJS({
|
|
|
37908
37970
|
if (client.isCluster && !client.slots.length) {
|
|
37909
37971
|
if (client.status === "wait")
|
|
37910
37972
|
client.connect().catch(lodash_1.noop);
|
|
37911
|
-
return (0, standard_as_callback_1.default)(new Promise(function(
|
|
37973
|
+
return (0, standard_as_callback_1.default)(new Promise(function(resolve4, reject) {
|
|
37912
37974
|
client.delayUntilReady((err) => {
|
|
37913
37975
|
if (err) {
|
|
37914
37976
|
reject(err);
|
|
37915
37977
|
return;
|
|
37916
37978
|
}
|
|
37917
|
-
executeWithAutoPipelining(client, functionName, commandName, args, null).then(
|
|
37979
|
+
executeWithAutoPipelining(client, functionName, commandName, args, null).then(resolve4, reject);
|
|
37918
37980
|
});
|
|
37919
37981
|
}), callback);
|
|
37920
37982
|
}
|
|
@@ -37935,13 +37997,13 @@ var require_autoPipelining = __commonJS({
|
|
|
37935
37997
|
pipeline[exports.kExec] = true;
|
|
37936
37998
|
setImmediate(executeAutoPipeline, client, slotKey);
|
|
37937
37999
|
}
|
|
37938
|
-
const autoPipelinePromise = new Promise(function(
|
|
38000
|
+
const autoPipelinePromise = new Promise(function(resolve4, reject) {
|
|
37939
38001
|
pipeline[exports.kCallbacks].push(function(err, value) {
|
|
37940
38002
|
if (err) {
|
|
37941
38003
|
reject(err);
|
|
37942
38004
|
return;
|
|
37943
38005
|
}
|
|
37944
|
-
|
|
38006
|
+
resolve4(value);
|
|
37945
38007
|
});
|
|
37946
38008
|
if (functionName === "call") {
|
|
37947
38009
|
args.unshift(commandName);
|
|
@@ -38176,8 +38238,8 @@ var require_Pipeline = __commonJS({
|
|
|
38176
38238
|
this[name] = redis[name];
|
|
38177
38239
|
this[name + "Buffer"] = redis[name + "Buffer"];
|
|
38178
38240
|
});
|
|
38179
|
-
this.promise = new Promise((
|
|
38180
|
-
this.resolve =
|
|
38241
|
+
this.promise = new Promise((resolve4, reject) => {
|
|
38242
|
+
this.resolve = resolve4;
|
|
38181
38243
|
this.reject = reject;
|
|
38182
38244
|
});
|
|
38183
38245
|
const _this = this;
|
|
@@ -38477,13 +38539,13 @@ var require_transaction = __commonJS({
|
|
|
38477
38539
|
if (this.isCluster && !this.redis.slots.length) {
|
|
38478
38540
|
if (this.redis.status === "wait")
|
|
38479
38541
|
this.redis.connect().catch(utils_1.noop);
|
|
38480
|
-
return (0, standard_as_callback_1.default)(new Promise((
|
|
38542
|
+
return (0, standard_as_callback_1.default)(new Promise((resolve4, reject) => {
|
|
38481
38543
|
this.redis.delayUntilReady((err) => {
|
|
38482
38544
|
if (err) {
|
|
38483
38545
|
reject(err);
|
|
38484
38546
|
return;
|
|
38485
38547
|
}
|
|
38486
|
-
this.exec(pipeline).then(
|
|
38548
|
+
this.exec(pipeline).then(resolve4, reject);
|
|
38487
38549
|
});
|
|
38488
38550
|
}), callback);
|
|
38489
38551
|
}
|
|
@@ -39612,7 +39674,7 @@ var require_cluster = __commonJS({
|
|
|
39612
39674
|
* Connect to a cluster
|
|
39613
39675
|
*/
|
|
39614
39676
|
connect() {
|
|
39615
|
-
return new Promise((
|
|
39677
|
+
return new Promise((resolve4, reject) => {
|
|
39616
39678
|
if (this.status === "connecting" || this.status === "connect" || this.status === "ready") {
|
|
39617
39679
|
reject(new Error("Redis is already connecting/connected"));
|
|
39618
39680
|
return;
|
|
@@ -39641,7 +39703,7 @@ var require_cluster = __commonJS({
|
|
|
39641
39703
|
this.retryAttempts = 0;
|
|
39642
39704
|
this.executeOfflineCommands();
|
|
39643
39705
|
this.resetNodesRefreshInterval();
|
|
39644
|
-
|
|
39706
|
+
resolve4();
|
|
39645
39707
|
};
|
|
39646
39708
|
let closeListener = void 0;
|
|
39647
39709
|
const refreshListener = () => {
|
|
@@ -40251,7 +40313,7 @@ var require_cluster = __commonJS({
|
|
|
40251
40313
|
});
|
|
40252
40314
|
}
|
|
40253
40315
|
resolveSrv(hostname2) {
|
|
40254
|
-
return new Promise((
|
|
40316
|
+
return new Promise((resolve4, reject) => {
|
|
40255
40317
|
this.options.resolveSrv(hostname2, (err, records) => {
|
|
40256
40318
|
if (err) {
|
|
40257
40319
|
return reject(err);
|
|
@@ -40265,7 +40327,7 @@ var require_cluster = __commonJS({
|
|
|
40265
40327
|
if (!group.records.length) {
|
|
40266
40328
|
sortedKeys.shift();
|
|
40267
40329
|
}
|
|
40268
|
-
self2.dnsLookup(record.name).then((host) =>
|
|
40330
|
+
self2.dnsLookup(record.name).then((host) => resolve4({
|
|
40269
40331
|
host,
|
|
40270
40332
|
port: record.port
|
|
40271
40333
|
}), tryFirstOne);
|
|
@@ -40275,14 +40337,14 @@ var require_cluster = __commonJS({
|
|
|
40275
40337
|
});
|
|
40276
40338
|
}
|
|
40277
40339
|
dnsLookup(hostname2) {
|
|
40278
|
-
return new Promise((
|
|
40340
|
+
return new Promise((resolve4, reject) => {
|
|
40279
40341
|
this.options.dnsLookup(hostname2, (err, address) => {
|
|
40280
40342
|
if (err) {
|
|
40281
40343
|
debug2("failed to resolve hostname %s to IP: %s", hostname2, err.message);
|
|
40282
40344
|
reject(err);
|
|
40283
40345
|
} else {
|
|
40284
40346
|
debug2("resolved hostname %s to IP %s", hostname2, address);
|
|
40285
|
-
|
|
40347
|
+
resolve4(address);
|
|
40286
40348
|
}
|
|
40287
40349
|
});
|
|
40288
40350
|
});
|
|
@@ -40437,7 +40499,7 @@ var require_StandaloneConnector = __commonJS({
|
|
|
40437
40499
|
if (options.tls) {
|
|
40438
40500
|
Object.assign(connectionOptions, options.tls);
|
|
40439
40501
|
}
|
|
40440
|
-
return new Promise((
|
|
40502
|
+
return new Promise((resolve4, reject) => {
|
|
40441
40503
|
process.nextTick(() => {
|
|
40442
40504
|
if (!this.connecting) {
|
|
40443
40505
|
reject(new Error(utils_1.CONNECTION_CLOSED_ERROR_MSG));
|
|
@@ -40456,7 +40518,7 @@ var require_StandaloneConnector = __commonJS({
|
|
|
40456
40518
|
this.stream.once("error", (err) => {
|
|
40457
40519
|
this.firstError = err;
|
|
40458
40520
|
});
|
|
40459
|
-
|
|
40521
|
+
resolve4(this.stream);
|
|
40460
40522
|
});
|
|
40461
40523
|
});
|
|
40462
40524
|
}
|
|
@@ -40612,7 +40674,7 @@ var require_SentinelConnector = __commonJS({
|
|
|
40612
40674
|
const error = new Error(errorMsg);
|
|
40613
40675
|
if (typeof retryDelay === "number") {
|
|
40614
40676
|
eventEmitter("error", error);
|
|
40615
|
-
await new Promise((
|
|
40677
|
+
await new Promise((resolve4) => setTimeout(resolve4, retryDelay));
|
|
40616
40678
|
return connectToNext();
|
|
40617
40679
|
} else {
|
|
40618
40680
|
throw error;
|
|
@@ -41929,7 +41991,7 @@ var require_Redis = __commonJS({
|
|
|
41929
41991
|
* if the connection fails, times out, or if Redis is already connecting/connected.
|
|
41930
41992
|
*/
|
|
41931
41993
|
connect(callback) {
|
|
41932
|
-
const promise = new Promise((
|
|
41994
|
+
const promise = new Promise((resolve4, reject) => {
|
|
41933
41995
|
if (this.status === "connecting" || this.status === "connect" || this.status === "ready") {
|
|
41934
41996
|
reject(new Error("Redis is already connecting/connected"));
|
|
41935
41997
|
return;
|
|
@@ -42008,7 +42070,7 @@ var require_Redis = __commonJS({
|
|
|
42008
42070
|
}
|
|
42009
42071
|
const connectionReadyHandler = function() {
|
|
42010
42072
|
_this.removeListener("close", connectionCloseHandler);
|
|
42011
|
-
|
|
42073
|
+
resolve4();
|
|
42012
42074
|
};
|
|
42013
42075
|
var connectionCloseHandler = function() {
|
|
42014
42076
|
_this.removeListener("ready", connectionReadyHandler);
|
|
@@ -42102,10 +42164,10 @@ var require_Redis = __commonJS({
|
|
|
42102
42164
|
monitor: true,
|
|
42103
42165
|
lazyConnect: false
|
|
42104
42166
|
});
|
|
42105
|
-
return (0, standard_as_callback_1.default)(new Promise(function(
|
|
42167
|
+
return (0, standard_as_callback_1.default)(new Promise(function(resolve4, reject) {
|
|
42106
42168
|
monitorInstance.once("error", reject);
|
|
42107
42169
|
monitorInstance.once("monitoring", function() {
|
|
42108
|
-
|
|
42170
|
+
resolve4(monitorInstance);
|
|
42109
42171
|
});
|
|
42110
42172
|
}), callback);
|
|
42111
42173
|
}
|
|
@@ -42878,7 +42940,15 @@ async function runMenu() {
|
|
|
42878
42940
|
});
|
|
42879
42941
|
if (!q(setup) && setup) {
|
|
42880
42942
|
const { runInitFlow: runInitFlow2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
42881
|
-
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
|
+
}
|
|
42882
42952
|
}
|
|
42883
42953
|
}
|
|
42884
42954
|
}
|
|
@@ -42948,8 +43018,8 @@ var init_menu = __esm({
|
|
|
42948
43018
|
"src/ui/menu.ts"() {
|
|
42949
43019
|
init_dist5();
|
|
42950
43020
|
init_http();
|
|
42951
|
-
init_detect();
|
|
42952
43021
|
init_store();
|
|
43022
|
+
init_detect();
|
|
42953
43023
|
init_version();
|
|
42954
43024
|
init_audit2();
|
|
42955
43025
|
init_login();
|
|
@@ -44749,8 +44819,6 @@ var AuditVerifyCommand = class extends Command {
|
|
|
44749
44819
|
}
|
|
44750
44820
|
}
|
|
44751
44821
|
};
|
|
44752
|
-
|
|
44753
|
-
// src/commands/exec.ts
|
|
44754
44822
|
init_http();
|
|
44755
44823
|
init_envFile();
|
|
44756
44824
|
|
|
@@ -45099,7 +45167,9 @@ var ENV_ALLOWLIST = [
|
|
|
45099
45167
|
"WINDIR",
|
|
45100
45168
|
"COMSPEC",
|
|
45101
45169
|
"APPDATA",
|
|
45102
|
-
"LOCALAPPDATA"
|
|
45170
|
+
"LOCALAPPDATA",
|
|
45171
|
+
"PATHEXT"
|
|
45172
|
+
// needed so child processes can resolve executables by name
|
|
45103
45173
|
];
|
|
45104
45174
|
function spawnPrivileged(opts) {
|
|
45105
45175
|
const startedAt = Date.now();
|
|
@@ -45108,6 +45178,11 @@ function spawnPrivileged(opts) {
|
|
|
45108
45178
|
const v2 = process.env[name];
|
|
45109
45179
|
if (v2 !== void 0) env2[name] = v2;
|
|
45110
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
|
+
}
|
|
45111
45186
|
if (opts.injectedEnv) {
|
|
45112
45187
|
for (const [k2, v2] of Object.entries(opts.injectedEnv)) env2[k2] = v2;
|
|
45113
45188
|
}
|
|
@@ -45133,14 +45208,33 @@ function spawnPrivileged(opts) {
|
|
|
45133
45208
|
]);
|
|
45134
45209
|
let spawnCmd = opts.command;
|
|
45135
45210
|
let spawnArgs = opts.args;
|
|
45136
|
-
|
|
45137
|
-
|
|
45138
|
-
|
|
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
|
+
}
|
|
45139
45232
|
}
|
|
45140
45233
|
const child = spawn(spawnCmd, spawnArgs, {
|
|
45141
45234
|
env: env2,
|
|
45142
45235
|
stdio,
|
|
45143
|
-
detached: false
|
|
45236
|
+
detached: false,
|
|
45237
|
+
windowsVerbatimArguments
|
|
45144
45238
|
});
|
|
45145
45239
|
const literals = opts.resolved.map((r) => r.value).filter((v2) => v2.length > 0);
|
|
45146
45240
|
if (!opts.noRedact && child.stdout) {
|
|
@@ -45161,14 +45255,14 @@ function spawnPrivileged(opts) {
|
|
|
45161
45255
|
}, opts.timeoutS * 1e3);
|
|
45162
45256
|
timer.unref();
|
|
45163
45257
|
}
|
|
45164
|
-
return new Promise((
|
|
45258
|
+
return new Promise((resolve4, reject) => {
|
|
45165
45259
|
child.on("error", (err) => {
|
|
45166
45260
|
if (timer) clearTimeout(timer);
|
|
45167
45261
|
reject(err);
|
|
45168
45262
|
});
|
|
45169
45263
|
child.on("close", (code, signal) => {
|
|
45170
45264
|
if (timer) clearTimeout(timer);
|
|
45171
|
-
|
|
45265
|
+
resolve4({
|
|
45172
45266
|
exitCode: code ?? 0,
|
|
45173
45267
|
signal,
|
|
45174
45268
|
durationMs: Date.now() - startedAt
|
|
@@ -45176,6 +45270,34 @@ function spawnPrivileged(opts) {
|
|
|
45176
45270
|
});
|
|
45177
45271
|
});
|
|
45178
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
|
+
}
|
|
45179
45301
|
|
|
45180
45302
|
// src/commands/exec.ts
|
|
45181
45303
|
var ExecCommand = class extends Command {
|
|
@@ -45232,6 +45354,10 @@ spelled \`--from\` to avoid the collision.)
|
|
|
45232
45354
|
quiet = options_exports.Boolean("--quiet", false, {
|
|
45233
45355
|
description: `Suppress the "loaded N vars from ${ENV_FILE_BASENAME}" status line.`
|
|
45234
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.
|
|
45235
45361
|
rest = options_exports.Rest();
|
|
45236
45362
|
async execute() {
|
|
45237
45363
|
if (!this.rest || this.rest.length === 0) {
|
|
@@ -45274,6 +45400,13 @@ spelled \`--from\` to avoid the collision.)
|
|
|
45274
45400
|
);
|
|
45275
45401
|
return 2;
|
|
45276
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
|
+
}
|
|
45277
45410
|
const viaEnvSpecs = [];
|
|
45278
45411
|
for (const spec of this.viaEnv ?? []) {
|
|
45279
45412
|
const eq = spec.indexOf("=");
|
|
@@ -45398,7 +45531,9 @@ function signalNumber(sig) {
|
|
|
45398
45531
|
init_dist();
|
|
45399
45532
|
init_http();
|
|
45400
45533
|
init_envFile();
|
|
45534
|
+
init_detect();
|
|
45401
45535
|
init_heuristics();
|
|
45536
|
+
init_aiContext();
|
|
45402
45537
|
init_init();
|
|
45403
45538
|
init_cancel();
|
|
45404
45539
|
init_tty();
|
|
@@ -45414,7 +45549,8 @@ async function resolveProjectId(client, input) {
|
|
|
45414
45549
|
return input;
|
|
45415
45550
|
}
|
|
45416
45551
|
const data = await client.request("/v1/projects");
|
|
45417
|
-
const
|
|
45552
|
+
const lowerInput = input.toLowerCase();
|
|
45553
|
+
const match = data.projects.find((p2) => p2.name.toLowerCase() === lowerInput);
|
|
45418
45554
|
if (!match) throw new Error(`project not found: ${input}`);
|
|
45419
45555
|
return match.id;
|
|
45420
45556
|
}
|
|
@@ -45547,6 +45683,14 @@ var ProjectDeleteCommand = class extends Command {
|
|
|
45547
45683
|
};
|
|
45548
45684
|
|
|
45549
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
|
+
}
|
|
45550
45694
|
var InitCommand = class extends Command {
|
|
45551
45695
|
static paths = [["init"]];
|
|
45552
45696
|
static usage = Command.Usage({
|
|
@@ -45565,15 +45709,19 @@ mappings that would be written to .keynv.env, then exits without
|
|
|
45565
45709
|
touching any files or making any network calls. Use it to preview
|
|
45566
45710
|
what init will do before committing.
|
|
45567
45711
|
|
|
45568
|
-
|
|
45569
|
-
|
|
45570
|
-
|
|
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.
|
|
45571
45715
|
`,
|
|
45572
45716
|
examples: [
|
|
45573
45717
|
["Walk the current project", "$0 init"],
|
|
45574
45718
|
["Preview without writing or uploading", "$0 init --dry-run"],
|
|
45575
45719
|
["Skip the package.json script-wrapping step", "$0 init --no-scripts"],
|
|
45576
|
-
["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
|
+
]
|
|
45577
45725
|
]
|
|
45578
45726
|
});
|
|
45579
45727
|
dryRun = options_exports.Boolean("--dry-run", false, {
|
|
@@ -45594,6 +45742,9 @@ commands directly.
|
|
|
45594
45742
|
secret = options_exports.Array("--secret", {
|
|
45595
45743
|
description: "KEY=value secret to upload (non-interactive). Can be specified multiple times."
|
|
45596
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
|
+
});
|
|
45597
45748
|
async execute() {
|
|
45598
45749
|
const client = new ApiClient();
|
|
45599
45750
|
await client.ensureHydrated();
|
|
@@ -45603,13 +45754,13 @@ commands directly.
|
|
|
45603
45754
|
}
|
|
45604
45755
|
const hasEnvFile = this.envFile != null;
|
|
45605
45756
|
const hasSecrets = this.secret != null && this.secret.length > 0;
|
|
45606
|
-
const isNonInteractive = hasEnvFile || hasSecrets;
|
|
45757
|
+
const isNonInteractive = hasEnvFile || hasSecrets || this.dryRun || this.yes;
|
|
45607
45758
|
if (isNonInteractive) {
|
|
45608
45759
|
return this.runNonInteractive(client);
|
|
45609
45760
|
}
|
|
45610
45761
|
if (!isInteractive()) {
|
|
45611
45762
|
this.context.stderr.write(
|
|
45612
|
-
"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"
|
|
45613
45764
|
);
|
|
45614
45765
|
return 1;
|
|
45615
45766
|
}
|
|
@@ -45629,6 +45780,9 @@ commands directly.
|
|
|
45629
45780
|
}
|
|
45630
45781
|
}
|
|
45631
45782
|
async runNonInteractive(client) {
|
|
45783
|
+
if (this.yes && !this.envFile && !this.secret) {
|
|
45784
|
+
return this.runAutoScan(client);
|
|
45785
|
+
}
|
|
45632
45786
|
const projectName = this.project;
|
|
45633
45787
|
if (!projectName) {
|
|
45634
45788
|
this.context.stderr.write("keynv: --project is required in non-interactive mode.\n");
|
|
@@ -45678,34 +45832,134 @@ commands directly.
|
|
|
45678
45832
|
return 0;
|
|
45679
45833
|
}
|
|
45680
45834
|
if (this.dryRun) {
|
|
45681
|
-
this.
|
|
45682
|
-
|
|
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}
|
|
45683
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"
|
|
45684
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) {
|
|
45685
45898
|
for (const { name } of secrets) {
|
|
45686
|
-
const aliasKey = name
|
|
45899
|
+
const aliasKey = toAliasKey2(name);
|
|
45687
45900
|
this.context.stdout.write(` ${name}=@${projectName}.${envName}.${aliasKey}
|
|
45688
45901
|
`);
|
|
45689
45902
|
}
|
|
45690
45903
|
return 0;
|
|
45691
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) {
|
|
45692
45947
|
let uploaded = 0;
|
|
45693
45948
|
const failed = [];
|
|
45694
|
-
for (const
|
|
45695
|
-
const
|
|
45696
|
-
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 });
|
|
45697
45951
|
if (!alias2) {
|
|
45698
|
-
failed.push(
|
|
45952
|
+
failed.push({ name: s.name, reason: `invalid alias key: ${s.aliasKey}` });
|
|
45699
45953
|
continue;
|
|
45700
45954
|
}
|
|
45701
45955
|
try {
|
|
45702
45956
|
await client.request(`/v1/projects/${projectId2}/secrets`, {
|
|
45703
45957
|
method: "POST",
|
|
45704
|
-
body: { env: envName, key: aliasKey, value }
|
|
45958
|
+
body: { env: envName, key: s.aliasKey, value: s.value }
|
|
45705
45959
|
});
|
|
45706
45960
|
uploaded++;
|
|
45707
45961
|
} catch (err) {
|
|
45708
|
-
failed.push(
|
|
45962
|
+
failed.push({ name: s.name, reason: err instanceof Error ? err.message : String(err) });
|
|
45709
45963
|
}
|
|
45710
45964
|
}
|
|
45711
45965
|
this.context.stdout.write(
|
|
@@ -45713,7 +45967,7 @@ commands directly.
|
|
|
45713
45967
|
`
|
|
45714
45968
|
);
|
|
45715
45969
|
if (failed.length > 0) {
|
|
45716
|
-
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}
|
|
45717
45971
|
`);
|
|
45718
45972
|
return 1;
|
|
45719
45973
|
}
|
|
@@ -45735,7 +45989,7 @@ async function promptHidden(prompt) {
|
|
|
45735
45989
|
process.stdin.setRawMode(true);
|
|
45736
45990
|
process.stdin.resume();
|
|
45737
45991
|
process.stdin.setEncoding("utf8");
|
|
45738
|
-
return new Promise((
|
|
45992
|
+
return new Promise((resolve4) => {
|
|
45739
45993
|
let buf = "";
|
|
45740
45994
|
const onData = (chunk) => {
|
|
45741
45995
|
for (const ch of chunk) {
|
|
@@ -45744,7 +45998,7 @@ async function promptHidden(prompt) {
|
|
|
45744
45998
|
process.stdin.pause();
|
|
45745
45999
|
process.stdin.removeListener("data", onData);
|
|
45746
46000
|
process.stdout.write("\n");
|
|
45747
|
-
|
|
46001
|
+
resolve4(buf);
|
|
45748
46002
|
return;
|
|
45749
46003
|
}
|
|
45750
46004
|
if (ch === "") {
|
|
@@ -45762,10 +46016,10 @@ async function promptHidden(prompt) {
|
|
|
45762
46016
|
}
|
|
45763
46017
|
async function promptLine(prompt) {
|
|
45764
46018
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
45765
|
-
return new Promise((
|
|
46019
|
+
return new Promise((resolve4) => {
|
|
45766
46020
|
rl.question(prompt, (answer) => {
|
|
45767
46021
|
rl.close();
|
|
45768
|
-
|
|
46022
|
+
resolve4(answer.trim());
|
|
45769
46023
|
});
|
|
45770
46024
|
});
|
|
45771
46025
|
}
|
|
@@ -46152,9 +46406,9 @@ here (see the streaming-mode limitation in the redactor package).
|
|
|
46152
46406
|
`
|
|
46153
46407
|
});
|
|
46154
46408
|
async execute() {
|
|
46155
|
-
return new Promise((
|
|
46409
|
+
return new Promise((resolve4, reject) => {
|
|
46156
46410
|
const transform = createRedactStream();
|
|
46157
|
-
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));
|
|
46158
46412
|
this.context.stdin.on("error", reject);
|
|
46159
46413
|
});
|
|
46160
46414
|
}
|
|
@@ -46234,10 +46488,13 @@ var SecretCreateCommand = class extends Command {
|
|
|
46234
46488
|
value = await promptHidden("value: ");
|
|
46235
46489
|
}
|
|
46236
46490
|
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46237
|
-
await client.request(
|
|
46238
|
-
|
|
46239
|
-
|
|
46240
|
-
|
|
46491
|
+
await client.request(
|
|
46492
|
+
`/v1/projects/${projectId2}/secrets`,
|
|
46493
|
+
{
|
|
46494
|
+
method: "POST",
|
|
46495
|
+
body: { env: parsed.environment, key: parsed.key, value }
|
|
46496
|
+
}
|
|
46497
|
+
);
|
|
46241
46498
|
this.context.stdout.write(`created ${parsed.literal}
|
|
46242
46499
|
`);
|
|
46243
46500
|
return 0;
|
|
@@ -46320,7 +46577,15 @@ var SecretListCommand = class extends Command {
|
|
|
46320
46577
|
throw err;
|
|
46321
46578
|
}
|
|
46322
46579
|
}
|
|
46323
|
-
|
|
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
|
+
}
|
|
46588
|
+
}
|
|
46324
46589
|
const projectId2 = await resolveProjectId(client, resolvedProjectName);
|
|
46325
46590
|
const data = await client.request(`/v1/projects/${projectId2}/secrets`);
|
|
46326
46591
|
if (this.json) {
|
|
@@ -46425,9 +46690,12 @@ var SecretDeleteCommand = class extends Command {
|
|
|
46425
46690
|
return 1;
|
|
46426
46691
|
}
|
|
46427
46692
|
const projectId2 = await resolveProjectId(client, parsed.project);
|
|
46428
|
-
await client.request(
|
|
46429
|
-
|
|
46430
|
-
|
|
46693
|
+
await client.request(
|
|
46694
|
+
`/v1/projects/${projectId2}/secrets/${parsed.environment}/${parsed.key}`,
|
|
46695
|
+
{
|
|
46696
|
+
method: "DELETE"
|
|
46697
|
+
}
|
|
46698
|
+
);
|
|
46431
46699
|
this.context.stdout.write(`deleted ${parsed.literal}
|
|
46432
46700
|
`);
|
|
46433
46701
|
return 0;
|
|
@@ -46495,8 +46763,8 @@ Non-interactive with --yes to skip prompts.
|
|
|
46495
46763
|
"# KEYNV_ARGON2_MEMORY_KIB=46080",
|
|
46496
46764
|
"# KEYNV_ARGON2_TIME_COST=3"
|
|
46497
46765
|
].join("\n");
|
|
46498
|
-
const { writeFileSync:
|
|
46499
|
-
|
|
46766
|
+
const { writeFileSync: writeFileSync5 } = await import('fs');
|
|
46767
|
+
writeFileSync5(outPath, `${contents}
|
|
46500
46768
|
`);
|
|
46501
46769
|
this.context.stdout.write(`Wrote ${outPath}
|
|
46502
46770
|
|
|
@@ -46562,7 +46830,7 @@ services:
|
|
|
46562
46830
|
volumes:
|
|
46563
46831
|
keynv-data:
|
|
46564
46832
|
`;
|
|
46565
|
-
|
|
46833
|
+
writeFileSync5("docker-compose.yml", composeContent);
|
|
46566
46834
|
this.context.stdout.write(
|
|
46567
46835
|
"\nWrote docker-compose.yml (update Litestream S3 config before deploying).\n"
|
|
46568
46836
|
);
|
|
@@ -46798,7 +47066,7 @@ var sshTester = {
|
|
|
46798
47066
|
async test(secret, target) {
|
|
46799
47067
|
const start = Date.now();
|
|
46800
47068
|
const { Client: Client2 } = await import('ssh2');
|
|
46801
|
-
return new Promise((
|
|
47069
|
+
return new Promise((resolve4) => {
|
|
46802
47070
|
const client = new Client2();
|
|
46803
47071
|
let settled = false;
|
|
46804
47072
|
const settle = (result) => {
|
|
@@ -46809,7 +47077,7 @@ var sshTester = {
|
|
|
46809
47077
|
client.end();
|
|
46810
47078
|
} catch {
|
|
46811
47079
|
}
|
|
46812
|
-
|
|
47080
|
+
resolve4(result);
|
|
46813
47081
|
};
|
|
46814
47082
|
client.once("ready", () => {
|
|
46815
47083
|
client.exec("true", (err, stream) => {
|
|
@@ -46875,12 +47143,12 @@ function sanitizeResult(result, secret) {
|
|
|
46875
47143
|
|
|
46876
47144
|
// ../../packages/testers/dist/run.js
|
|
46877
47145
|
function withTimeout(promise, ms) {
|
|
46878
|
-
return new Promise((
|
|
47146
|
+
return new Promise((resolve4, reject) => {
|
|
46879
47147
|
const t = setTimeout(() => reject(new Error(`tester timed out after ${ms}ms`)), ms);
|
|
46880
47148
|
t.unref();
|
|
46881
47149
|
promise.then((v2) => {
|
|
46882
47150
|
clearTimeout(t);
|
|
46883
|
-
|
|
47151
|
+
resolve4(v2);
|
|
46884
47152
|
}, (err) => {
|
|
46885
47153
|
clearTimeout(t);
|
|
46886
47154
|
reject(err);
|