@penvhq/cli 0.16.0 → 0.16.2
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/bin.cjs +77 -21
- package/dist/bin.cjs.map +1 -1
- package/dist/{chunk-4RR6UFVZ.js → chunk-5UQEMWMW.js} +7 -4
- package/dist/chunk-5UQEMWMW.js.map +1 -0
- package/dist/index.cjs +77 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -5
- package/dist/index.d.ts +14 -5
- package/dist/index.js +73 -20
- package/dist/index.js.map +1 -1
- package/dist/install.cjs +6 -3
- package/dist/install.cjs.map +1 -1
- package/dist/install.js +1 -1
- package/package.json +7 -7
- package/dist/chunk-4RR6UFVZ.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -123,10 +123,22 @@ interface ScopeOptions {
|
|
|
123
123
|
readonly environment?: string;
|
|
124
124
|
readonly local?: boolean;
|
|
125
125
|
}
|
|
126
|
+
/** What `set` knows when it has to ask for the value: which file, and whether to hide the typing. */
|
|
127
|
+
interface SetPrompt {
|
|
128
|
+
readonly parameter: string;
|
|
129
|
+
/** Whether meta says this is a secret, so the wrapper mutes the echo. */
|
|
130
|
+
readonly secret: boolean;
|
|
131
|
+
}
|
|
126
132
|
interface SetOptions extends ScopeOptions {
|
|
127
133
|
readonly cwd: string;
|
|
128
134
|
readonly key: string;
|
|
129
|
-
|
|
135
|
+
/** The value, when the command line carried one. */
|
|
136
|
+
readonly value?: string;
|
|
137
|
+
/**
|
|
138
|
+
* How the value is obtained when the command line carried none. `undefined`
|
|
139
|
+
* or an empty answer is a refusal: an empty secret is never what was meant.
|
|
140
|
+
*/
|
|
141
|
+
readonly ask?: (prompt: SetPrompt) => Promise<string | undefined>;
|
|
130
142
|
}
|
|
131
143
|
interface SetResult {
|
|
132
144
|
readonly parameter: string;
|
|
@@ -183,10 +195,7 @@ interface FillPrompt {
|
|
|
183
195
|
/** The value file's key, kebab and slash-separated — the name the user need never derive. */
|
|
184
196
|
readonly parameter: string;
|
|
185
197
|
readonly environment: string;
|
|
186
|
-
/**
|
|
187
|
-
* Whether meta says this is a secret. Carried so a wrapper can mute the echo;
|
|
188
|
-
* v1 does not, and the drift carries no meta, so this is `false` today.
|
|
189
|
-
*/
|
|
198
|
+
/** Whether meta says this is a secret, so the wrapper mutes the echo. */
|
|
190
199
|
readonly secret: boolean;
|
|
191
200
|
/**
|
|
192
201
|
* Whether the schema excuses absence — `.optional()`, `.default()`. An answer
|
package/dist/index.d.ts
CHANGED
|
@@ -123,10 +123,22 @@ interface ScopeOptions {
|
|
|
123
123
|
readonly environment?: string;
|
|
124
124
|
readonly local?: boolean;
|
|
125
125
|
}
|
|
126
|
+
/** What `set` knows when it has to ask for the value: which file, and whether to hide the typing. */
|
|
127
|
+
interface SetPrompt {
|
|
128
|
+
readonly parameter: string;
|
|
129
|
+
/** Whether meta says this is a secret, so the wrapper mutes the echo. */
|
|
130
|
+
readonly secret: boolean;
|
|
131
|
+
}
|
|
126
132
|
interface SetOptions extends ScopeOptions {
|
|
127
133
|
readonly cwd: string;
|
|
128
134
|
readonly key: string;
|
|
129
|
-
|
|
135
|
+
/** The value, when the command line carried one. */
|
|
136
|
+
readonly value?: string;
|
|
137
|
+
/**
|
|
138
|
+
* How the value is obtained when the command line carried none. `undefined`
|
|
139
|
+
* or an empty answer is a refusal: an empty secret is never what was meant.
|
|
140
|
+
*/
|
|
141
|
+
readonly ask?: (prompt: SetPrompt) => Promise<string | undefined>;
|
|
130
142
|
}
|
|
131
143
|
interface SetResult {
|
|
132
144
|
readonly parameter: string;
|
|
@@ -183,10 +195,7 @@ interface FillPrompt {
|
|
|
183
195
|
/** The value file's key, kebab and slash-separated — the name the user need never derive. */
|
|
184
196
|
readonly parameter: string;
|
|
185
197
|
readonly environment: string;
|
|
186
|
-
/**
|
|
187
|
-
* Whether meta says this is a secret. Carried so a wrapper can mute the echo;
|
|
188
|
-
* v1 does not, and the drift carries no meta, so this is `false` today.
|
|
189
|
-
*/
|
|
198
|
+
/** Whether meta says this is a secret, so the wrapper mutes the echo. */
|
|
190
199
|
readonly secret: boolean;
|
|
191
200
|
/**
|
|
192
201
|
* Whether the schema excuses absence — `.optional()`, `.default()`. An answer
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
planInstall,
|
|
8
8
|
renderInstallPlan,
|
|
9
9
|
startChild
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5UQEMWMW.js";
|
|
11
11
|
|
|
12
12
|
// src/index.ts
|
|
13
13
|
import { setKeychain } from "@penvhq/core";
|
|
@@ -2187,8 +2187,21 @@ import { defineCommand as defineCommand6 } from "citty";
|
|
|
2187
2187
|
|
|
2188
2188
|
// src/input.ts
|
|
2189
2189
|
import { createInterface } from "readline";
|
|
2190
|
+
import { Writable } from "stream";
|
|
2191
|
+
function isTerminal(output) {
|
|
2192
|
+
return output.isTTY === true;
|
|
2193
|
+
}
|
|
2190
2194
|
function lineReader(input = process.stdin, output = process.stdout) {
|
|
2191
|
-
|
|
2195
|
+
let muted = false;
|
|
2196
|
+
const sink = new Writable({
|
|
2197
|
+
write(chunk, _encoding, callback) {
|
|
2198
|
+
if (!muted) {
|
|
2199
|
+
output.write(chunk);
|
|
2200
|
+
}
|
|
2201
|
+
callback();
|
|
2202
|
+
}
|
|
2203
|
+
});
|
|
2204
|
+
const rl = createInterface({ input, output: sink, terminal: isTerminal(output) });
|
|
2192
2205
|
const buffered = [];
|
|
2193
2206
|
const waiting = [];
|
|
2194
2207
|
let closed = false;
|
|
@@ -2207,7 +2220,7 @@ function lineReader(input = process.stdin, output = process.stdout) {
|
|
|
2207
2220
|
}
|
|
2208
2221
|
});
|
|
2209
2222
|
return {
|
|
2210
|
-
ask(question) {
|
|
2223
|
+
ask(question, options) {
|
|
2211
2224
|
const early = buffered.shift();
|
|
2212
2225
|
if (early !== void 0) {
|
|
2213
2226
|
return Promise.resolve(early);
|
|
@@ -2215,6 +2228,19 @@ function lineReader(input = process.stdin, output = process.stdout) {
|
|
|
2215
2228
|
if (closed) {
|
|
2216
2229
|
return Promise.resolve(void 0);
|
|
2217
2230
|
}
|
|
2231
|
+
if (options?.secret === true) {
|
|
2232
|
+
output.write(question);
|
|
2233
|
+
muted = true;
|
|
2234
|
+
rl.setPrompt("");
|
|
2235
|
+
rl.prompt();
|
|
2236
|
+
return new Promise((resolve9) => {
|
|
2237
|
+
waiting.push((line) => {
|
|
2238
|
+
muted = false;
|
|
2239
|
+
output.write("\n");
|
|
2240
|
+
resolve9(line);
|
|
2241
|
+
});
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2218
2244
|
rl.setPrompt(question);
|
|
2219
2245
|
rl.prompt();
|
|
2220
2246
|
return new Promise((resolve9) => {
|
|
@@ -3551,16 +3577,30 @@ async function runSet(options) {
|
|
|
3551
3577
|
const ref = refFromKey(options.key, project.config);
|
|
3552
3578
|
const scope = targetScope(project, options, options.key);
|
|
3553
3579
|
const environment = policyEnvironment(project, options);
|
|
3580
|
+
const value = options.value ?? await askForValue(project, ref, environment, options);
|
|
3554
3581
|
const { encrypted, location } = await sealAwareWrite({
|
|
3555
3582
|
project,
|
|
3556
3583
|
provider: project.provider,
|
|
3557
3584
|
ref,
|
|
3558
3585
|
scope,
|
|
3559
|
-
value
|
|
3586
|
+
value,
|
|
3560
3587
|
environment
|
|
3561
3588
|
});
|
|
3562
3589
|
return { parameter: options.key, location, encrypted };
|
|
3563
3590
|
}
|
|
3591
|
+
async function askForValue(project, ref, environment, options) {
|
|
3592
|
+
const parameter = parameterId4(ref);
|
|
3593
|
+
const remedy = `Pass it on the command line \u2014 \`penv set ${options.key} <value>\` \u2014 pipe it in, or answer the prompt.`;
|
|
3594
|
+
if (options.ask === void 0) {
|
|
3595
|
+
throw new PenvError9("VALUE_MISSING", `No value was given for parameter ${parameter}`, remedy);
|
|
3596
|
+
}
|
|
3597
|
+
const secret = isSecret4(await project.provider.readMeta(ref), environment);
|
|
3598
|
+
const answer = await options.ask({ parameter, secret });
|
|
3599
|
+
if (answer === void 0 || answer.length === 0) {
|
|
3600
|
+
throw new PenvError9("VALUE_MISSING", `No value was entered for parameter ${parameter}`, remedy);
|
|
3601
|
+
}
|
|
3602
|
+
return answer;
|
|
3603
|
+
}
|
|
3564
3604
|
function renderSet(result2) {
|
|
3565
3605
|
return formatRows([
|
|
3566
3606
|
{
|
|
@@ -3598,18 +3638,29 @@ var setCommand = defineCommand8({
|
|
|
3598
3638
|
},
|
|
3599
3639
|
run({ args }) {
|
|
3600
3640
|
return guard(async () => {
|
|
3601
|
-
const
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3641
|
+
const base = {
|
|
3642
|
+
cwd: process.cwd(),
|
|
3643
|
+
key: args.key,
|
|
3644
|
+
...args.env === void 0 ? {} : { environment: args.env },
|
|
3645
|
+
...args.local === void 0 ? {} : { local: args.local }
|
|
3646
|
+
};
|
|
3647
|
+
if (args.value !== void 0) {
|
|
3648
|
+
write(renderSet(await runSet({ ...base, value: args.value })));
|
|
3649
|
+
return;
|
|
3650
|
+
}
|
|
3651
|
+
if (process.stdin.isTTY !== true) {
|
|
3652
|
+
write(renderSet(await runSet({ ...base, value: await readStdin() })));
|
|
3653
|
+
return;
|
|
3654
|
+
}
|
|
3655
|
+
const reader = lineReader();
|
|
3656
|
+
try {
|
|
3657
|
+
const ask = ({ parameter, secret }) => reader.ask(prompt(parameter, secret ? "secret, typing is hidden" : void 0), {
|
|
3658
|
+
secret
|
|
3659
|
+
});
|
|
3660
|
+
write(renderSet(await runSet({ ...base, ask })));
|
|
3661
|
+
} finally {
|
|
3662
|
+
reader.close();
|
|
3663
|
+
}
|
|
3613
3664
|
});
|
|
3614
3665
|
}
|
|
3615
3666
|
});
|
|
@@ -3751,7 +3802,7 @@ var decryptCommand = defineCommand9({
|
|
|
3751
3802
|
});
|
|
3752
3803
|
|
|
3753
3804
|
// src/commands/fill.ts
|
|
3754
|
-
import { PenvError as PenvError11, recordPath as recordPath4, SCHEMA_SHAPE_FILE as SCHEMA_SHAPE_FILE2 } from "@penvhq/core";
|
|
3805
|
+
import { isSecret as isSecret6, PenvError as PenvError11, recordPath as recordPath4, SCHEMA_SHAPE_FILE as SCHEMA_SHAPE_FILE2 } from "@penvhq/core";
|
|
3755
3806
|
import { defineCommand as defineCommand10 } from "citty";
|
|
3756
3807
|
var BLOCKING = /* @__PURE__ */ new Set(["config", "collision", "reserved"]);
|
|
3757
3808
|
async function runFill(options) {
|
|
@@ -3773,6 +3824,8 @@ ${detail}`,
|
|
|
3773
3824
|
`Fix these \u2014 \`penv validate\` reports them \u2014 then run \`penv fill\`. If you have not written a schema yet, declare the required parameters in ${SCHEMA_SHAPE_FILE2}.`
|
|
3774
3825
|
);
|
|
3775
3826
|
}
|
|
3827
|
+
const project = openProject(options.cwd);
|
|
3828
|
+
const secretFor = async (ref) => isSecret6(await project.provider.readMeta(ref), environment);
|
|
3776
3829
|
const written = [];
|
|
3777
3830
|
const skipped2 = [];
|
|
3778
3831
|
const kept = [];
|
|
@@ -3787,7 +3840,7 @@ ${detail}`,
|
|
|
3787
3840
|
const value = await options.ask({
|
|
3788
3841
|
parameter: key,
|
|
3789
3842
|
environment,
|
|
3790
|
-
secret:
|
|
3843
|
+
secret: await secretFor(ref),
|
|
3791
3844
|
optional: false
|
|
3792
3845
|
});
|
|
3793
3846
|
if (value === void 0 || value === "") {
|
|
@@ -3811,7 +3864,7 @@ ${detail}`,
|
|
|
3811
3864
|
const value = await options.ask({
|
|
3812
3865
|
parameter: key,
|
|
3813
3866
|
environment,
|
|
3814
|
-
secret:
|
|
3867
|
+
secret: await secretFor(ref),
|
|
3815
3868
|
optional: true,
|
|
3816
3869
|
...item.defaultValue === void 0 ? {} : { defaultValue: item.defaultValue }
|
|
3817
3870
|
});
|
|
@@ -3881,7 +3934,7 @@ var fillCommand = defineCommand10({
|
|
|
3881
3934
|
run({ args }) {
|
|
3882
3935
|
return guard(async () => {
|
|
3883
3936
|
const reader = lineReader();
|
|
3884
|
-
const ask = (prompt2) => reader.ask(prompt(prompt2.parameter, contextFor(prompt2)));
|
|
3937
|
+
const ask = (prompt2) => reader.ask(prompt(prompt2.parameter, contextFor(prompt2)), { secret: prompt2.secret });
|
|
3885
3938
|
try {
|
|
3886
3939
|
write(
|
|
3887
3940
|
renderFill(
|