@procedures/cli-kit 0.0.0-stage → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/args.d.ts ADDED
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Command Line Splitting
3
+ *
4
+ * This module splits the argv of a program into the global flags, the command path, and the
5
+ * input of the procedure. The rules (deep dive CLI-7, CLI-9, CLI-10, CLI-11):
6
+ *
7
+ * - A flag before the command path is a global flag.
8
+ * - After the path, a flag is the procedure's when the procedure declares it (its field name, the
9
+ * kebab-case name, or its short letter). Otherwise it is a global flag. Otherwise it is an error.
10
+ * So `mark docker compose down -v` gives `-v` to the procedure, not to `--version`.
11
+ * - Each value is converted by the type of its field: a string field keeps its text.
12
+ * - A repeated array flag collects its values. A repeated record flag (`--env A=1 --env B=2`) merges.
13
+ * - A boolean flag takes `true`/`false` after it, or `--flag=false`, or `--no-flag`.
14
+ * - A repeated global flag with a value keeps the last value. A repeatable one (`--events`)
15
+ * collects its values, separated by commas.
16
+ * - A negative number is a value, not a flag. `--` ends the flags.
17
+ * - The positional fields take the arguments in order. A last array field takes the rest.
18
+ * An argument that no field takes is an error.
19
+ * - With `readFile`, a value `@<file>` is the text of the file. A value `@@<text>` is the text `@<text>`.
20
+ */
21
+ import { type CLIMeta, type CommandLike, type FieldType } from "./fields.js";
22
+ /** A global flag of a program: a flag that applies to each command. */
23
+ export interface GlobalFlag {
24
+ /** The long name, without "--" */
25
+ readonly long: string;
26
+ /** The short letter, without "-" */
27
+ readonly short?: string | undefined;
28
+ /** True when the flag takes a value */
29
+ readonly takesValue: boolean;
30
+ /** True when the flag can be given more than one time: its values add up, separated by commas */
31
+ readonly repeatable?: boolean | undefined;
32
+ /** True when the help of a command does not list the flag */
33
+ readonly hidden?: boolean | undefined;
34
+ /** The help text */
35
+ readonly description: string;
36
+ }
37
+ /** This function finds the global flag with this long name, or with this short letter. */
38
+ export declare function findGlobalFlag(globals: readonly GlobalFlag[], name: string, short: boolean): GlobalFlag | undefined;
39
+ /** The global flags that the command line gives: true for a flag, text for a flag with a value */
40
+ export type Globals = Record<string, string | boolean | undefined>;
41
+ /** The options of the parse of a command line. */
42
+ export interface ParseOptions {
43
+ /** The name of the program, for the messages. */
44
+ name: string;
45
+ /** The global flags of the program. */
46
+ globals: readonly GlobalFlag[];
47
+ /**
48
+ * The function that reads a file for a value `@<file>`. Without it, a value that starts with
49
+ * `@` stays text.
50
+ */
51
+ readFile?: ((path: string) => string) | undefined;
52
+ }
53
+ /** The result of the parse of a command line. */
54
+ export interface ParsedCommandLine<T extends CommandLike = CommandLike> {
55
+ /** The command path */
56
+ path: string[];
57
+ /** The procedure at the path, if there is one */
58
+ procedure: T | undefined;
59
+ /** The procedure input, converted by the field types (not validated yet) */
60
+ input: Record<string, unknown>;
61
+ /** The global flags */
62
+ globals: Globals;
63
+ /** The arguments that no positional field took */
64
+ extraArguments: string[];
65
+ /** The problems, one message each */
66
+ errors: string[];
67
+ }
68
+ /**
69
+ * Find a procedure matching the given path
70
+ */
71
+ export declare function findProcedure<T extends CommandLike>(procedures: readonly T[], path: readonly string[]): T | undefined;
72
+ /**
73
+ * Find procedures that are children of the given path
74
+ */
75
+ export declare function findChildren<T extends CommandLike>(procedures: readonly T[], path: readonly string[]): T[];
76
+ interface FlagSpec {
77
+ field: string;
78
+ type: FieldType;
79
+ }
80
+ interface ProcedureFlags {
81
+ long: Map<string, FlagSpec>;
82
+ short: Map<string, FlagSpec>;
83
+ /** The field types by field name */
84
+ fields: Map<string, FieldType>;
85
+ /** True when the schema has readable fields: then an unknown flag is an error */
86
+ typed: boolean;
87
+ meta: CLIMeta;
88
+ }
89
+ /**
90
+ * The flags a procedure declares: each field of its input schema (camelCase and kebab-case
91
+ * names) and the short letters of its metadata.
92
+ */
93
+ export declare function procedureFlags(procedure: CommandLike | undefined): ProcedureFlags;
94
+ /**
95
+ * This function reads the global flags before the command path. It needs no procedures: `mark`
96
+ * reads them before it loads the procedures (`--version`, `--server`, `-i`).
97
+ */
98
+ export declare function parseLeadingGlobals(argv: readonly string[], options: Pick<ParseOptions, "globals">): {
99
+ globals: Globals;
100
+ rest: string[];
101
+ errors: string[];
102
+ };
103
+ /**
104
+ * This function splits a whole command line: the global flags, the command path, and the
105
+ * procedure input.
106
+ */
107
+ export declare function parseCommandLine<T extends CommandLike>(argv: readonly string[], procedures: readonly T[], options: ParseOptions): ParsedCommandLine<T>;
108
+ export {};
109
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
package/dist/args.js ADDED
@@ -0,0 +1,399 @@
1
+ /**
2
+ * Command Line Splitting
3
+ *
4
+ * This module splits the argv of a program into the global flags, the command path, and the
5
+ * input of the procedure. The rules (deep dive CLI-7, CLI-9, CLI-10, CLI-11):
6
+ *
7
+ * - A flag before the command path is a global flag.
8
+ * - After the path, a flag is the procedure's when the procedure declares it (its field name, the
9
+ * kebab-case name, or its short letter). Otherwise it is a global flag. Otherwise it is an error.
10
+ * So `mark docker compose down -v` gives `-v` to the procedure, not to `--version`.
11
+ * - Each value is converted by the type of its field: a string field keeps its text.
12
+ * - A repeated array flag collects its values. A repeated record flag (`--env A=1 --env B=2`) merges.
13
+ * - A boolean flag takes `true`/`false` after it, or `--flag=false`, or `--no-flag`.
14
+ * - A repeated global flag with a value keeps the last value. A repeatable one (`--events`)
15
+ * collects its values, separated by commas.
16
+ * - A negative number is a value, not a flag. `--` ends the flags.
17
+ * - The positional fields take the arguments in order. A last array field takes the rest.
18
+ * An argument that no field takes is an error.
19
+ * - With `readFile`, a value `@<file>` is the text of the file. A value `@@<text>` is the text `@<text>`.
20
+ */
21
+ import { convertValue, fieldsOf, mergeValue, toCamel, toKebab, } from "./fields.js";
22
+ /** This function finds the global flag with this long name, or with this short letter. */
23
+ export function findGlobalFlag(globals, name, short) {
24
+ return globals.find((flag) => (short ? flag.short === name : flag.long === name));
25
+ }
26
+ // The digits before the point and the digits after it are two groups, so each token has one match
27
+ const NEGATIVE_NUMBER = /^-(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?$/;
28
+ const ANY = { kind: "any" };
29
+ /** A token that is a flag (not a value, not a negative number, not "-" alone) */
30
+ function isFlag(token) {
31
+ return token.startsWith("-") && token !== "-" && !NEGATIVE_NUMBER.test(token);
32
+ }
33
+ /**
34
+ * Find a procedure matching the given path
35
+ */
36
+ export function findProcedure(procedures, path) {
37
+ return procedures.find((p) => p.path.length === path.length && p.path.every((seg, i) => seg === path[i]));
38
+ }
39
+ /**
40
+ * Find procedures that are children of the given path
41
+ */
42
+ export function findChildren(procedures, path) {
43
+ return procedures.filter((p) => p.path.length > path.length && path.every((seg, i) => seg === p.path[i]));
44
+ }
45
+ /**
46
+ * The flags a procedure declares: each field of its input schema (camelCase and kebab-case
47
+ * names) and the short letters of its metadata.
48
+ */
49
+ export function procedureFlags(procedure) {
50
+ const meta = (procedure?.metadata ?? {});
51
+ const schemaFields = procedure ? fieldsOf(procedure) : [];
52
+ const fields = new Map(schemaFields.map((field) => [field.name, field.fieldType]));
53
+ const long = new Map();
54
+ const short = new Map();
55
+ const addLong = (field) => {
56
+ const spec = { field, type: fields.get(field) ?? ANY };
57
+ long.set(field, spec);
58
+ long.set(toKebab(field), spec);
59
+ };
60
+ for (const field of fields.keys()) {
61
+ addLong(field);
62
+ }
63
+ for (const [field, letter] of Object.entries(meta.shorts ?? {})) {
64
+ if (!long.has(field)) {
65
+ addLong(field);
66
+ }
67
+ short.set(letter, { field, type: fields.get(field) ?? ANY });
68
+ }
69
+ return { long, short, fields, typed: schemaFields.length > 0, meta };
70
+ }
71
+ /** The state of one pass over the tokens */
72
+ class TokenReader {
73
+ tokens;
74
+ index = 0;
75
+ constructor(tokens) {
76
+ this.tokens = tokens;
77
+ }
78
+ get current() {
79
+ return this.tokens[this.index];
80
+ }
81
+ /** The value of a flag: the inline value, or the next token when it is not a flag */
82
+ takeValue(inline) {
83
+ if (inline !== undefined) {
84
+ return inline;
85
+ }
86
+ const next = this.tokens[this.index + 1];
87
+ if (next !== undefined && !isFlag(next)) {
88
+ this.index++;
89
+ return next;
90
+ }
91
+ return undefined;
92
+ }
93
+ /** The value of a boolean flag: the inline value, or a next token that is "true" or "false" */
94
+ takeBoolean(inline) {
95
+ if (inline !== undefined) {
96
+ return inline;
97
+ }
98
+ const next = this.tokens[this.index + 1];
99
+ if (next === "true" || next === "false") {
100
+ this.index++;
101
+ return next;
102
+ }
103
+ return undefined;
104
+ }
105
+ }
106
+ /** Split "--name=value" (or "-n=value") into the name and the inline value */
107
+ function splitInline(body) {
108
+ const eq = body.indexOf("=");
109
+ return eq === -1 ? { name: body, inline: undefined } : { name: body.slice(0, eq), inline: body.slice(eq + 1) };
110
+ }
111
+ /** Read one global flag. Returns an error message, or undefined. */
112
+ function readGlobal(flag, label, inline, reader, globals) {
113
+ const name = flag.long;
114
+ if (flag.takesValue) {
115
+ const value = reader.takeValue(inline);
116
+ if (value === undefined) {
117
+ return `${label} needs a value`;
118
+ }
119
+ // A repeatable flag (--events) collects its values, separated by commas
120
+ const previous = globals[name];
121
+ globals[name] = flag.repeatable && typeof previous === "string" ? `${previous},${value}` : value;
122
+ return undefined;
123
+ }
124
+ if (inline !== undefined && inline !== "true" && inline !== "false") {
125
+ return `${label} needs true or false, not "${inline}"`;
126
+ }
127
+ globals[name] = inline !== "false";
128
+ return undefined;
129
+ }
130
+ /**
131
+ * This function reads the global flags before the command path. It needs no procedures: `mark`
132
+ * reads them before it loads the procedures (`--version`, `--server`, `-i`).
133
+ */
134
+ export function parseLeadingGlobals(argv, options) {
135
+ const globals = {};
136
+ const errors = [];
137
+ const reader = new TokenReader(argv);
138
+ for (; reader.index < argv.length; reader.index++) {
139
+ const token = reader.current;
140
+ if (!isFlag(token) || token === "--") {
141
+ break;
142
+ }
143
+ const isLong = token.startsWith("--");
144
+ const { name, inline } = splitInline(token.slice(isLong ? 2 : 1));
145
+ const flag = isLong || name.length === 1 ? findGlobalFlag(options.globals, name, !isLong) : undefined;
146
+ if (!flag) {
147
+ errors.push(`Unknown option before the command: ${token}`);
148
+ continue;
149
+ }
150
+ const error = readGlobal(flag, isLong ? `--${name}` : `-${name}`, inline, reader, globals);
151
+ if (error) {
152
+ errors.push(error);
153
+ }
154
+ }
155
+ const rest = argv.slice(reader.index);
156
+ if (rest[0] === "--") {
157
+ rest.shift();
158
+ }
159
+ return { globals, rest, errors };
160
+ }
161
+ /**
162
+ * The command path at the start of the tokens: the longest run of words that names a procedure
163
+ * or a group of procedures. The first word is part of the path even when it names nothing (the
164
+ * command is then unknown).
165
+ *
166
+ * A procedure can also be a group: `fs read` and `fs read json` are both procedures (roadmap
167
+ * CLI-75). The words go on while a longer path can match, and the path is the longest one that
168
+ * names a procedure. Thus `fs read json` names `fs.read.json`, and `fs read notes.txt` names
169
+ * `fs.read` with the argument `notes.txt`.
170
+ */
171
+ function readPath(tokens, procedures) {
172
+ const path = [];
173
+ // The length of the longest path that names a procedure
174
+ let named = 0;
175
+ for (const token of tokens) {
176
+ if (isFlag(token) || token === "--") {
177
+ break;
178
+ }
179
+ const testPath = [...path, token];
180
+ const procedure = findProcedure(procedures, testPath) !== undefined;
181
+ const group = findChildren(procedures, testPath).length > 0;
182
+ if (!procedure && !group && path.length > 0) {
183
+ break;
184
+ }
185
+ path.push(token);
186
+ if (procedure)
187
+ named = path.length;
188
+ if (!group) {
189
+ break;
190
+ }
191
+ }
192
+ return named > 0 ? path.slice(0, named) : path;
193
+ }
194
+ /**
195
+ * This function splits a whole command line: the global flags, the command path, and the
196
+ * procedure input.
197
+ */
198
+ export function parseCommandLine(argv, procedures, options) {
199
+ const { name: program, globals: globalFlags, readFile } = options;
200
+ const leading = parseLeadingGlobals(argv, options);
201
+ const globals = leading.globals;
202
+ const errors = [...leading.errors];
203
+ const path = readPath(leading.rest, procedures);
204
+ const procedure = findProcedure(procedures, path);
205
+ const flags = procedureFlags(procedure);
206
+ const input = {};
207
+ const fromFlag = new Set();
208
+ const positionals = [];
209
+ /** The text of a value: the text of a file for `@<file>`, when the options can read files. */
210
+ const textOf = (text, label) => {
211
+ if (!readFile || !text.startsWith("@") || text.length < 2) {
212
+ return text;
213
+ }
214
+ if (text.startsWith("@@")) {
215
+ return text.slice(1);
216
+ }
217
+ try {
218
+ return readFile(text.slice(1));
219
+ }
220
+ catch (error) {
221
+ errors.push(`${label}: cannot read ${text.slice(1)}: ${error instanceof Error ? error.message : String(error)}`);
222
+ return undefined;
223
+ }
224
+ };
225
+ /** The conversion of a value, after `textOf()`. An error goes to `errors`. */
226
+ const convert = (raw, type, label) => {
227
+ const text = type.kind === "boolean" ? raw : textOf(raw, label);
228
+ if (text === undefined) {
229
+ return { ok: false };
230
+ }
231
+ const converted = convertValue(text, type, label);
232
+ if (!converted.ok) {
233
+ errors.push(converted.error);
234
+ return { ok: false };
235
+ }
236
+ return converted;
237
+ };
238
+ const setField = (spec, raw, label) => {
239
+ const converted = convert(raw, spec.type, label);
240
+ if (!converted.ok) {
241
+ return;
242
+ }
243
+ input[spec.field] = mergeValue(input[spec.field], converted.value, spec.type);
244
+ fromFlag.add(spec.field);
245
+ };
246
+ /** Read one procedure flag. Returns false when the procedure does not declare it. */
247
+ const readProcedureFlag = (spec, label, inline, reader) => {
248
+ if (!spec) {
249
+ return false;
250
+ }
251
+ if (spec.type.kind === "boolean") {
252
+ setField(spec, reader.takeBoolean(inline) ?? "true", label);
253
+ return true;
254
+ }
255
+ const value = reader.takeValue(inline);
256
+ if (value === undefined) {
257
+ errors.push(`${label} needs a value`);
258
+ return true;
259
+ }
260
+ setField(spec, value, label);
261
+ return true;
262
+ };
263
+ /** A flag that neither the procedure nor the globals have */
264
+ const readOther = (name, label, inline, reader) => {
265
+ if (procedure && !flags.typed) {
266
+ // The schema has no readable fields: pass the flag through, as JSON or text
267
+ const value = reader.takeValue(inline);
268
+ setField({ field: toCamel(name), type: ANY }, value ?? "true", label);
269
+ return;
270
+ }
271
+ const where = path.length > 0 ? ` for ${program} ${path.join(" ")}` : "";
272
+ errors.push(`Unknown option${where}: ${label}`);
273
+ };
274
+ const reader = new TokenReader(leading.rest);
275
+ reader.index = path.length;
276
+ let onlyPositionals = false;
277
+ for (; reader.index < leading.rest.length; reader.index++) {
278
+ const token = reader.current;
279
+ if (onlyPositionals || !isFlag(token)) {
280
+ positionals.push(token);
281
+ continue;
282
+ }
283
+ if (token === "--") {
284
+ onlyPositionals = true;
285
+ continue;
286
+ }
287
+ if (token.startsWith("--")) {
288
+ const { name, inline } = splitInline(token.slice(2));
289
+ const label = `--${name}`;
290
+ if (readProcedureFlag(flags.long.get(name), label, inline, reader)) {
291
+ continue;
292
+ }
293
+ // --no-<flag> sets a boolean field to false
294
+ const negated = name.startsWith("no-") ? flags.long.get(name.slice(3)) : undefined;
295
+ if (negated?.type.kind === "boolean") {
296
+ if (inline !== undefined) {
297
+ errors.push(`${label} takes no value`);
298
+ }
299
+ else {
300
+ setField(negated, "false", label);
301
+ }
302
+ continue;
303
+ }
304
+ const global = findGlobalFlag(globalFlags, name, false);
305
+ if (global) {
306
+ const error = readGlobal(global, label, inline, reader, globals);
307
+ if (error)
308
+ errors.push(error);
309
+ continue;
310
+ }
311
+ readOther(name, label, inline, reader);
312
+ continue;
313
+ }
314
+ // Short flags: "-x", "-x=value", "-xvalue" (a flag with a value), or "-abc" (boolean flags)
315
+ const { name: body, inline } = splitInline(token.slice(1));
316
+ for (let k = 0; k < body.length; k++) {
317
+ const letter = body[k];
318
+ const label = `-${letter}`;
319
+ const last = k === body.length - 1;
320
+ const attached = last ? inline : body.slice(k + 1);
321
+ const spec = flags.short.get(letter);
322
+ const global = spec ? undefined : findGlobalFlag(globalFlags, letter, true);
323
+ const takesValue = spec ? spec.type.kind !== "boolean" : global?.takesValue === true;
324
+ if (!spec && !global) {
325
+ if (body.length === 1) {
326
+ readOther(letter, label, inline, reader);
327
+ }
328
+ else {
329
+ errors.push(`Unknown option ${label} in ${token}`);
330
+ }
331
+ break;
332
+ }
333
+ if (takesValue || last) {
334
+ // The rest of the token (or the next token) is the value of this flag
335
+ if (spec) {
336
+ readProcedureFlag(spec, label, attached === "" ? undefined : attached, reader);
337
+ }
338
+ else {
339
+ const error = readGlobal(global, label, attached === "" ? undefined : attached, reader, globals);
340
+ if (error)
341
+ errors.push(error);
342
+ }
343
+ break;
344
+ }
345
+ if (spec) {
346
+ setField(spec, "true", label);
347
+ }
348
+ else {
349
+ globals[global.long] = true;
350
+ }
351
+ }
352
+ }
353
+ // Positional fields take the arguments in order; a last array field takes the rest
354
+ const positionalFields = flags.meta.args ?? [];
355
+ let next = 0;
356
+ if (procedure) {
357
+ positionalFields.forEach((field, k) => {
358
+ if (next >= positionals.length) {
359
+ return;
360
+ }
361
+ const type = flags.fields.get(field) ?? ANY;
362
+ const many = type.kind === "array" && k === positionalFields.length - 1;
363
+ const texts = many ? positionals.slice(next) : [positionals[next]];
364
+ next += texts.length;
365
+ if (fromFlag.has(field)) {
366
+ errors.push(`${field} is given twice: as an argument and as --${toKebab(field)}`);
367
+ return;
368
+ }
369
+ let value;
370
+ // Each argument of a last array field is one item, also when there is only one. Before, one
371
+ // argument was converted as the whole array, so `[]` gave no item and `["a","b"]` two.
372
+ if (many) {
373
+ const items = [];
374
+ for (const text of texts) {
375
+ const converted = convert(text, type.item ?? ANY, field);
376
+ if (!converted.ok) {
377
+ return;
378
+ }
379
+ items.push(converted.value);
380
+ }
381
+ value = items;
382
+ }
383
+ else {
384
+ const converted = convert(texts[0], type, field);
385
+ if (!converted.ok) {
386
+ return;
387
+ }
388
+ value = converted.value;
389
+ }
390
+ input[field] = value;
391
+ });
392
+ }
393
+ const extraArguments = positionals.slice(next);
394
+ if (procedure && extraArguments.length > 0) {
395
+ errors.push(`Unexpected argument${extraArguments.length > 1 ? "s" : ""} for ${program} ${path.join(" ")}: ${extraArguments.join(" ")}`);
396
+ }
397
+ return { path, procedure, input, globals, extraArguments, errors };
398
+ }
399
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
package/dist/ask.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Questions for missing arguments.
3
+ *
4
+ * When a person runs a program in a terminal and a required argument is missing, the program
5
+ * asks for it. The question shows the name, the type and the description of the field. The
6
+ * program does not ask when stdin or stdout is not a terminal, when the environment variable CI
7
+ * is set, with `--no-input`, or when the procedure sets `interactive: false` in its CLI metadata.
8
+ * Then a missing argument is an error of the input.
9
+ */
10
+ import { type CLIMeta, type SchemaFieldInfo } from "./fields.js";
11
+ /** The answer to one question: the text of the person, or `cancelled` */
12
+ export type Answer = {
13
+ value: unknown;
14
+ } | {
15
+ cancelled: true;
16
+ };
17
+ /** A function that asks one question. Tests give a fake. */
18
+ export type Asker = (field: SchemaFieldInfo, message: string) => Promise<Answer>;
19
+ /** The terminal state that decides if the program can ask */
20
+ export interface Terminal {
21
+ stdinIsTTY: boolean;
22
+ stdoutIsTTY: boolean;
23
+ env: Record<string, string | undefined>;
24
+ }
25
+ /** This function gives the terminal state of this process. */
26
+ export declare function processTerminal(): Terminal;
27
+ /** This function gives true when the program can ask for a missing argument. */
28
+ export declare function canAsk(noInput: boolean, meta: CLIMeta, terminal: Terminal): boolean;
29
+ /** The required fields that the input does not give (a field with a default is not missing) */
30
+ export declare function missingFields(fields: readonly SchemaFieldInfo[], input: Record<string, unknown>): SchemaFieldInfo[];
31
+ /** The question of a field: its name, its type and its description */
32
+ export declare function questionOf(field: SchemaFieldInfo): string;
33
+ /** The result of the questions: the input with the answers, or the reason to stop */
34
+ export type Asked = {
35
+ ok: true;
36
+ input: Record<string, unknown>;
37
+ } | {
38
+ ok: false;
39
+ cancelled: boolean;
40
+ error: string;
41
+ };
42
+ /**
43
+ * Ask for each missing field, in order, and convert each answer by the type of its field. An
44
+ * array field takes the words of the answer.
45
+ */
46
+ export declare function askMissing(missing: readonly SchemaFieldInfo[], input: Record<string, unknown>, ask: Asker): Promise<Asked>;
47
+ /** The asker of the terminal: a yes/no question for a boolean, a choice for an enum, text otherwise */
48
+ export declare const terminalAsker: Asker;
49
+ //# sourceMappingURL=ask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../src/ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE/E,yEAAyE;AACzE,MAAM,MAAM,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC;AAE9D,4DAA4D;AAC5D,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEjF,6DAA6D;AAC7D,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACzC;AAED,8DAA8D;AAC9D,wBAAgB,eAAe,IAAI,QAAQ,CAM1C;AAED,gFAAgF;AAChF,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CASnF;AAED,+FAA+F;AAC/F,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,EAAE,CAEnH;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAIzD;AAED,qFAAqF;AACrF,MAAM,MAAM,KAAK,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,GAAG,EAAE,KAAK,GACT,OAAO,CAAC,KAAK,CAAC,CA+BhB;AAED,uGAAuG;AACvG,eAAO,MAAM,aAAa,EAAE,KAa3B,CAAC"}