@hivecommons/promptargs 0.7.0 → 0.9.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/README.md +106 -20
- package/dist/autodetect.js +39 -12
- package/dist/autodetect.js.map +1 -1
- package/dist/cli.js +78 -147
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +148 -0
- package/dist/commands.js.map +1 -0
- package/dist/flags.d.ts +20 -0
- package/dist/flags.js +101 -0
- package/dist/flags.js.map +1 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.js +84 -11
- package/dist/loader.js.map +1 -1
- package/dist/log.d.ts +19 -0
- package/dist/log.js +41 -0
- package/dist/log.js.map +1 -0
- package/dist/parser.js +39 -9
- package/dist/parser.js.map +1 -1
- package/dist/resolver.d.ts +3 -1
- package/dist/resolver.js +105 -34
- package/dist/resolver.js.map +1 -1
- package/dist/status.d.ts +1 -1
- package/dist/status.js +5 -4
- package/dist/status.js.map +1 -1
- package/dist/ui.d.ts +3 -0
- package/dist/ui.html +21 -6
- package/dist/ui.js +89 -12
- package/dist/ui.js.map +1 -1
- package/package.json +13 -4
- package/dist/autodetect.test.d.ts +0 -1
- package/dist/autodetect.test.js +0 -207
- package/dist/autodetect.test.js.map +0 -1
- package/dist/cli.test.d.ts +0 -1
- package/dist/cli.test.js +0 -310
- package/dist/cli.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -59
- package/dist/index.test.js.map +0 -1
- package/dist/iterate.test.d.ts +0 -1
- package/dist/iterate.test.js +0 -20
- package/dist/iterate.test.js.map +0 -1
- package/dist/loader.test.d.ts +0 -1
- package/dist/loader.test.js +0 -65
- package/dist/loader.test.js.map +0 -1
- package/dist/parser.test.d.ts +0 -1
- package/dist/parser.test.js +0 -93
- package/dist/parser.test.js.map +0 -1
- package/dist/resolver.test.d.ts +0 -1
- package/dist/resolver.test.js +0 -184
- package/dist/resolver.test.js.map +0 -1
- package/dist/sanitize.test.d.ts +0 -1
- package/dist/sanitize.test.js +0 -38
- package/dist/sanitize.test.js.map +0 -1
- package/dist/status.test.d.ts +0 -1
- package/dist/status.test.js +0 -33
- package/dist/status.test.js.map +0 -1
- package/dist/ui-bootstrap.test.d.ts +0 -1
- package/dist/ui-bootstrap.test.js +0 -479
- package/dist/ui-bootstrap.test.js.map +0 -1
- package/dist/ui-builder.test.d.ts +0 -1
- package/dist/ui-builder.test.js +0 -272
- package/dist/ui-builder.test.js.map +0 -1
- package/dist/ui-command-quoting.test.d.ts +0 -1
- package/dist/ui-command-quoting.test.js +0 -95
- package/dist/ui-command-quoting.test.js.map +0 -1
- package/dist/ui-harness.d.ts +0 -20
- package/dist/ui-harness.js +0 -40
- package/dist/ui-harness.js.map +0 -1
- package/dist/ui-harness.test.d.ts +0 -1
- package/dist/ui-harness.test.js +0 -30
- package/dist/ui-harness.test.js.map +0 -1
- package/dist/ui-inline.test.d.ts +0 -1
- package/dist/ui-inline.test.js +0 -90
- package/dist/ui-inline.test.js.map +0 -1
- package/dist/ui-interactions.test.d.ts +0 -1
- package/dist/ui-interactions.test.js +0 -489
- package/dist/ui-interactions.test.js.map +0 -1
- package/dist/ui.test.d.ts +0 -1
- package/dist/ui.test.js +0 -283
- package/dist/ui.test.js.map +0 -1
package/dist/loader.js
CHANGED
|
@@ -1,22 +1,91 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Find and load prompt templates from .prompts/ directories.
|
|
3
3
|
*/
|
|
4
|
-
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
5
|
-
import { join, basename, extname } from 'node:path';
|
|
4
|
+
import { readFileSync, readdirSync, existsSync, statSync, lstatSync, realpathSync } from 'node:fs';
|
|
5
|
+
import { join, basename, extname, sep } from 'node:path';
|
|
6
6
|
import { homedir } from 'node:os';
|
|
7
|
+
import { UsageError } from './flags.js';
|
|
8
|
+
import { diag, classifyError } from './log.js';
|
|
9
|
+
import { sanitizeForTerminal } from './sanitize.js';
|
|
7
10
|
const PROJECT_DIR = '.prompts';
|
|
8
11
|
const USER_DIR = join(homedir(), '.prompts');
|
|
9
12
|
function loadFromDir(dir, source) {
|
|
13
|
+
// The per-file escape check below trusts the resolved directory as its root,
|
|
14
|
+
// so a checked-out repo must not be able to replace the project .prompts
|
|
15
|
+
// entry itself with a link to somewhere else on the machine. ~/.prompts is
|
|
16
|
+
// the user's own and may be a link. lstat runs before existsSync (which
|
|
17
|
+
// follows links) so a dangling project link is explained rather than skipped.
|
|
18
|
+
if (source === 'project') {
|
|
19
|
+
try {
|
|
20
|
+
if (lstatSync(dir).isSymbolicLink()) {
|
|
21
|
+
diag('loader_dir_symlink', { status: 'refused' }, sanitizeForTerminal(`promptargs: ${dir} is a symlink; the project .prompts directory must be a real directory`));
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (err.code === 'ENOENT')
|
|
27
|
+
return [];
|
|
28
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
29
|
+
diag('loader_dir_unreadable', { error_class: classifyError(err) }, sanitizeForTerminal(`promptargs: cannot stat ${dir}: ${msg}`));
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
10
33
|
if (!existsSync(dir))
|
|
11
34
|
return [];
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
35
|
+
let entries;
|
|
36
|
+
try {
|
|
37
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
41
|
+
diag('loader_dir_unreadable', { error_class: classifyError(err) }, sanitizeForTerminal(`promptargs: cannot read ${dir}: ${msg}`));
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
// Symlinked templates must resolve to a file inside this .prompts dir; a
|
|
45
|
+
// cloned repo must not be able to make `promptargs x` read ~/.ssh/id_rsa.
|
|
46
|
+
let realDir;
|
|
47
|
+
try {
|
|
48
|
+
realDir = realpathSync(dir);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
52
|
+
diag('loader_dir_unreadable', { error_class: classifyError(err) }, sanitizeForTerminal(`promptargs: cannot resolve ${dir}: ${msg}`));
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
const realDirPrefix = realDir.endsWith(sep) ? realDir : realDir + sep;
|
|
56
|
+
const templates = [];
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
const f = entry.name;
|
|
59
|
+
if (!f.endsWith('.md'))
|
|
60
|
+
continue;
|
|
61
|
+
const path = join(dir, f);
|
|
62
|
+
const isLink = entry.isSymbolicLink();
|
|
63
|
+
try {
|
|
64
|
+
const isFile = isLink ? statSync(path).isFile() : entry.isFile();
|
|
65
|
+
if (!isFile)
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
continue; // dangling symlink
|
|
70
|
+
}
|
|
71
|
+
const template = { name: basename(f, extname(f)), content: '', path, source };
|
|
72
|
+
try {
|
|
73
|
+
if (isLink) {
|
|
74
|
+
const target = realpathSync(path);
|
|
75
|
+
if (!target.startsWith(realDirPrefix)) {
|
|
76
|
+
template.error = `symlink target ${target} is outside ${dir}; templates must stay inside the .prompts directory`;
|
|
77
|
+
templates.push(template);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
template.content = readFileSync(path, 'utf8');
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
template.error = err instanceof Error ? err.message : String(err);
|
|
85
|
+
}
|
|
86
|
+
templates.push(template);
|
|
87
|
+
}
|
|
88
|
+
return templates;
|
|
20
89
|
}
|
|
21
90
|
export function loadTemplates(cwd) {
|
|
22
91
|
const projectDir = join(cwd || process.cwd(), PROJECT_DIR);
|
|
@@ -31,6 +100,10 @@ export function loadTemplates(cwd) {
|
|
|
31
100
|
return Array.from(byName.values());
|
|
32
101
|
}
|
|
33
102
|
export function findTemplate(name, cwd) {
|
|
34
|
-
|
|
103
|
+
const tpl = loadTemplates(cwd).find(t => t.name === name);
|
|
104
|
+
if (tpl?.error) {
|
|
105
|
+
throw new UsageError(`Template "${tpl.name}" at ${tpl.path} could not be read: ${tpl.error}`);
|
|
106
|
+
}
|
|
107
|
+
return tpl;
|
|
35
108
|
}
|
|
36
109
|
//# sourceMappingURL=loader.js.map
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in structured diagnostics. With PROMPTARGS_LOG=json, diagnostics are
|
|
3
|
+
* written to stderr as one JSON object per line with a fixed, bounded field
|
|
4
|
+
* set. Template contents, argument values, paths and URLs are never logged.
|
|
5
|
+
*/
|
|
6
|
+
export type LogEvent = 'ui_host_rejected' | 'ui_host_rejected_total' | 'ui_token_rejected' | 'ui_token_rejected_total' | 'ui_asset_error' | 'ui_request' | 'ui_start_error' | 'ui_browser_open_failed' | 'cli_iteration' | 'cli_error' | 'loader_dir_unreadable' | 'loader_dir_symlink';
|
|
7
|
+
export type ErrorClass = 'usage' | 'not_found' | 'io' | 'port_in_use' | 'unknown';
|
|
8
|
+
export interface LogFields {
|
|
9
|
+
status?: number | string;
|
|
10
|
+
duration_ms?: number;
|
|
11
|
+
error_class?: ErrorClass;
|
|
12
|
+
count?: number;
|
|
13
|
+
current?: number;
|
|
14
|
+
total?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function jsonLogEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
17
|
+
export declare function classifyError(err: unknown): ErrorClass;
|
|
18
|
+
export declare function diag(event: LogEvent, fields: LogFields, legacy?: string): void;
|
|
19
|
+
export declare function logRequest(status: number, startedAt: bigint): void;
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in structured diagnostics. With PROMPTARGS_LOG=json, diagnostics are
|
|
3
|
+
* written to stderr as one JSON object per line with a fixed, bounded field
|
|
4
|
+
* set. Template contents, argument values, paths and URLs are never logged.
|
|
5
|
+
*/
|
|
6
|
+
export function jsonLogEnabled(env = process.env) {
|
|
7
|
+
return env.PROMPTARGS_LOG === 'json';
|
|
8
|
+
}
|
|
9
|
+
export function classifyError(err) {
|
|
10
|
+
const code = err?.code;
|
|
11
|
+
if (code === 'ENOENT')
|
|
12
|
+
return 'not_found';
|
|
13
|
+
if (code === 'EADDRINUSE')
|
|
14
|
+
return 'port_in_use';
|
|
15
|
+
if (typeof code === 'string' && code.startsWith('E'))
|
|
16
|
+
return 'io';
|
|
17
|
+
if (err?.name === 'UsageError')
|
|
18
|
+
return 'usage';
|
|
19
|
+
return 'unknown';
|
|
20
|
+
}
|
|
21
|
+
// Writes a JSON line when enabled; otherwise prints the legacy text fallback
|
|
22
|
+
// (when given) so default output stays byte-for-byte unchanged.
|
|
23
|
+
export function diag(event, fields, legacy) {
|
|
24
|
+
if (!jsonLogEnabled()) {
|
|
25
|
+
if (legacy !== undefined)
|
|
26
|
+
console.error(legacy);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const line = { event };
|
|
30
|
+
for (const key of ['status', 'duration_ms', 'error_class', 'count', 'current', 'total']) {
|
|
31
|
+
if (fields[key] !== undefined)
|
|
32
|
+
line[key] = fields[key];
|
|
33
|
+
}
|
|
34
|
+
console.error(JSON.stringify(line));
|
|
35
|
+
}
|
|
36
|
+
// Request logging has no legacy output, so it is silent unless enabled.
|
|
37
|
+
export function logRequest(status, startedAt) {
|
|
38
|
+
const duration_ms = Number((process.hrtime.bigint() - startedAt) / 1000n) / 1000;
|
|
39
|
+
diag('ui_request', { status, duration_ms });
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA2BH,MAAM,UAAU,cAAc,CAAC,MAAyB,OAAO,CAAC,GAAG;IACjE,OAAO,GAAG,CAAC,cAAc,KAAK,MAAM,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,MAAM,IAAI,GAAI,GAAyC,EAAE,IAAI,CAAC;IAC9D,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,WAAW,CAAC;IAC1C,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,aAAa,CAAC;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClE,IAAK,GAAyB,EAAE,IAAI,KAAK,YAAY;QAAE,OAAO,OAAO,CAAC;IACtE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,6EAA6E;AAC7E,gEAAgE;AAChE,MAAM,UAAU,IAAI,CAAC,KAAe,EAAE,MAAiB,EAAE,MAAe;IACtE,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACtB,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAA4B,EAAE,KAAK,EAAE,CAAC;IAChD,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAU,EAAE,CAAC;QACjG,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,SAAiB;IAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;IACjF,IAAI,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;AAC9C,CAAC"}
|
package/dist/parser.js
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* Uses Mustache for expansion, with a promptargs extension for defaults.
|
|
4
4
|
*/
|
|
5
5
|
import Mustache from 'mustache';
|
|
6
|
+
// Kept local (not imported from flags.ts) because ui.html loads parser.js in the browser,
|
|
7
|
+
// where only parser.js/iterate.js/mustache.mjs are served (see STATIC_JS_ROUTES in ui.ts).
|
|
8
|
+
function usageError(message) {
|
|
9
|
+
const e = new Error(message);
|
|
10
|
+
e.name = 'UsageError';
|
|
11
|
+
return e;
|
|
12
|
+
}
|
|
6
13
|
// Exported so any code that needs to recognize the same {{var}} / {{var=default}}
|
|
7
14
|
// grammar (e.g. CLI syntax highlighting) reuses this single definition instead
|
|
8
15
|
// of re-declaring the pattern and risking drift.
|
|
@@ -12,16 +19,38 @@ import Mustache from 'mustache';
|
|
|
12
19
|
// recognize would still be handed to Mustache as a variable, which renders it
|
|
13
20
|
// as an empty string — the blank silently vanished instead of being asked for,
|
|
14
21
|
// filled from --flags, highlighted by `show`, or preserved as {{name}}.
|
|
15
|
-
//
|
|
16
|
-
|
|
22
|
+
// Padding around the = and trailing padding after a default are not part of
|
|
23
|
+
// the default ({{ name = value }} has the default "value").
|
|
24
|
+
// Ampersand tags ({{&name}}) are Mustache's unescaped-variable alias and are
|
|
25
|
+
// the same blank as {{name}}.
|
|
26
|
+
export const VAR_PATTERN = /\{\{\s*(?:&\s*)?([\w-]+)(?:\s*=\s*([^}]*?))?\s*\}\}/g;
|
|
27
|
+
// Dotted names ({{repo.owner}}) are Mustache context paths, which promptargs
|
|
28
|
+
// never fills; they would silently render empty, so they are rejected.
|
|
29
|
+
// The lookbehind skips triple-mustache tags; sigil tags ({{#x}}, {{!c}}) do
|
|
30
|
+
// not start with a name character and never match.
|
|
31
|
+
const DOTTED_PATTERN = /(?<!\{)\{\{\s*(?:&\s*)?([\w-]+\.[\w.-]*)\s*(?:=[^}]*)?\}\}/;
|
|
17
32
|
export function parseVars(template) {
|
|
18
|
-
const seen = new Set();
|
|
19
33
|
const vars = [];
|
|
34
|
+
// The first offending tag aborts; the message is built from the name only
|
|
35
|
+
// (restricted to [\w.-]) so raw template bytes never reach the terminal.
|
|
36
|
+
const dotted = DOTTED_PATTERN.exec(template);
|
|
37
|
+
if (dotted) {
|
|
38
|
+
const name = dotted[1];
|
|
39
|
+
throw usageError(`Unsupported variable name "${name}": dotted names are not supported; use {{${name.replace(/\./g, '_')}}}`);
|
|
40
|
+
}
|
|
20
41
|
for (const match of template.matchAll(VAR_PATTERN)) {
|
|
21
42
|
const name = match[1];
|
|
22
|
-
|
|
43
|
+
const existing = vars.find((v) => v.name === name);
|
|
44
|
+
if (existing) {
|
|
45
|
+
const dflt = match[2];
|
|
46
|
+
if (dflt === undefined)
|
|
47
|
+
continue;
|
|
48
|
+
// First default wins; later occurrences may restate it (e.g. a code
|
|
49
|
+
// fence using a different casing) without being an error.
|
|
50
|
+
if (existing.defaultValue === undefined)
|
|
51
|
+
existing.defaultValue = dflt;
|
|
23
52
|
continue;
|
|
24
|
-
|
|
53
|
+
}
|
|
25
54
|
vars.push({
|
|
26
55
|
name,
|
|
27
56
|
defaultValue: match[2],
|
|
@@ -32,18 +61,19 @@ export function parseVars(template) {
|
|
|
32
61
|
}
|
|
33
62
|
export function expand(template, values) {
|
|
34
63
|
const vars = parseVars(template);
|
|
35
|
-
const view =
|
|
64
|
+
const view = Object.assign(Object.create(null), values);
|
|
36
65
|
for (const v of vars) {
|
|
37
|
-
if (!(v.name
|
|
66
|
+
if (!Object.hasOwn(view, v.name) && v.defaultValue !== undefined) {
|
|
38
67
|
view[v.name] = v.defaultValue;
|
|
39
68
|
}
|
|
40
69
|
// Preserve unfilled vars as {{name}} in output
|
|
41
|
-
if (!(v.name
|
|
70
|
+
if (!Object.hasOwn(view, v.name)) {
|
|
42
71
|
view[v.name] = `{{${v.name}}}`;
|
|
43
72
|
}
|
|
44
73
|
}
|
|
45
74
|
// Convert {{var=default}} to {{var}} so Mustache can handle it
|
|
46
|
-
|
|
75
|
+
// The & sigil is kept so Mustache still sees an unescaped variable tag.
|
|
76
|
+
const normalized = template.replace(VAR_PATTERN, (match, name) => /^\{\{\s*&/.test(match) ? `{{&${name}}}` : `{{${name}}}`);
|
|
47
77
|
// Disable HTML escaping for this render only — we want raw text output.
|
|
48
78
|
// Passed via the per-call config (4th arg) rather than assigning to the
|
|
49
79
|
// module-level Mustache.escape, which would permanently disable escaping
|
package/dist/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
package/dist/resolver.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resolve variable values: flags → auto-detect → defaults → ask.
|
|
3
|
-
* Handles array expansion (comma-separated, globs, @file
|
|
3
|
+
* Handles array expansion (comma-separated, globs, @file).
|
|
4
4
|
*/
|
|
5
5
|
import type { TemplateVar } from './parser.js';
|
|
6
6
|
export interface ResolvedValues {
|
|
7
7
|
values: Record<string, string>;
|
|
8
8
|
iterations: Record<string, string>[];
|
|
9
|
+
/** Names whose value was filled from the template default. */
|
|
10
|
+
defaulted: Set<string>;
|
|
9
11
|
}
|
|
10
12
|
export declare function resolve(vars: TemplateVar[], flags: Record<string, string>, interactive: boolean, cross?: boolean): Promise<ResolvedValues>;
|
package/dist/resolver.js
CHANGED
|
@@ -1,36 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resolve variable values: flags → auto-detect → defaults → ask.
|
|
3
|
-
* Handles array expansion (comma-separated, globs, @file
|
|
3
|
+
* Handles array expansion (comma-separated, globs, @file).
|
|
4
4
|
*/
|
|
5
5
|
import { createInterface } from 'node:readline';
|
|
6
6
|
import { readFileSync, readdirSync, existsSync } from 'node:fs';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { autodetect } from './autodetect.js';
|
|
9
|
+
import { UsageError } from './flags.js';
|
|
9
10
|
import { cartesian, zip } from './iterate.js';
|
|
10
|
-
function
|
|
11
|
-
// @file — read lines from file
|
|
12
|
-
if (raw.startsWith('@') && existsSync(raw.slice(1))) {
|
|
13
|
-
return readFileSync(raw.slice(1), 'utf8')
|
|
14
|
-
.split('\n')
|
|
15
|
-
.map((l) => l.trim())
|
|
16
|
-
.filter(Boolean);
|
|
17
|
-
}
|
|
18
|
-
// - (stdin) handled at CLI level before this
|
|
19
|
-
if (raw === '-')
|
|
20
|
-
return [raw];
|
|
11
|
+
function expandPiece(piece) {
|
|
21
12
|
// Glob pattern — expanded in-process (never via a shell) to avoid
|
|
22
13
|
// command injection through crafted values.
|
|
23
|
-
if (
|
|
24
|
-
const files = expandGlob(
|
|
14
|
+
if (piece.includes('*') || piece.includes('?')) {
|
|
15
|
+
const files = expandGlob(piece);
|
|
25
16
|
if (files.length > 0)
|
|
26
17
|
return files;
|
|
27
18
|
// Not a valid glob, treat as literal
|
|
28
19
|
}
|
|
29
|
-
|
|
20
|
+
return [piece];
|
|
21
|
+
}
|
|
22
|
+
function expandArrayValue(raw, varName) {
|
|
23
|
+
// @file — read lines from file
|
|
24
|
+
if (raw.startsWith('@') && existsSync(raw.slice(1))) {
|
|
25
|
+
const filePath = raw.slice(1);
|
|
26
|
+
try {
|
|
27
|
+
return readFileSync(filePath, 'utf8')
|
|
28
|
+
.split('\n')
|
|
29
|
+
.map((l) => l.trim())
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.flatMap(expandPiece);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const e = err;
|
|
35
|
+
if (e.code === 'EISDIR') {
|
|
36
|
+
throw new UsageError(`Variable "${varName}": @${filePath} is a directory, not a file; pass @FILE with one value per line`);
|
|
37
|
+
}
|
|
38
|
+
throw new UsageError(`Variable "${varName}": could not read @${filePath}: ${e.message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// A bare '-' is a literal value, not stdin.
|
|
42
|
+
if (raw === '-')
|
|
43
|
+
return [raw];
|
|
44
|
+
// Comma-separated: split first so each piece can be a glob
|
|
30
45
|
if (raw.includes(',')) {
|
|
31
|
-
return raw.split(',').map(s => s.trim()).filter(Boolean);
|
|
46
|
+
return raw.split(',').map(s => s.trim()).filter(Boolean).flatMap(expandPiece);
|
|
32
47
|
}
|
|
33
|
-
return
|
|
48
|
+
return expandPiece(raw);
|
|
34
49
|
}
|
|
35
50
|
function segmentToRegExp(segment) {
|
|
36
51
|
const escaped = segment
|
|
@@ -39,13 +54,54 @@ function segmentToRegExp(segment) {
|
|
|
39
54
|
.replace(/\?/g, '.');
|
|
40
55
|
return new RegExp(`^${escaped}$`);
|
|
41
56
|
}
|
|
57
|
+
function descendantDirs(base) {
|
|
58
|
+
const out = [];
|
|
59
|
+
let entries;
|
|
60
|
+
try {
|
|
61
|
+
entries = readdirSync(base === '' ? '.' : base, { withFileTypes: true });
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
for (const entry of entries) {
|
|
67
|
+
if (entry.name.startsWith('.') || !entry.isDirectory())
|
|
68
|
+
continue;
|
|
69
|
+
const p = base === '' ? entry.name : join(base, entry.name);
|
|
70
|
+
out.push(p, ...descendantDirs(p));
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
function filesIn(base) {
|
|
75
|
+
try {
|
|
76
|
+
return readdirSync(base === '' ? '.' : base, { withFileTypes: true })
|
|
77
|
+
.filter(e => !e.name.startsWith('.') && !e.isDirectory())
|
|
78
|
+
.map(e => (base === '' ? e.name : join(base, e.name)));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
42
84
|
function expandGlob(pattern) {
|
|
43
85
|
const absolute = pattern.startsWith('/');
|
|
44
86
|
const segments = pattern.split('/').filter(Boolean);
|
|
45
87
|
let bases = [absolute ? '/' : ''];
|
|
46
|
-
for (
|
|
88
|
+
for (let i = 0; i < segments.length; i++) {
|
|
89
|
+
const segment = segments[i];
|
|
47
90
|
const next = [];
|
|
48
|
-
if (
|
|
91
|
+
if (segment === '**') {
|
|
92
|
+
// Consecutive ** segments behave as one
|
|
93
|
+
if (segments[i + 1] === '**')
|
|
94
|
+
continue;
|
|
95
|
+
const trailing = i === segments.length - 1;
|
|
96
|
+
for (const base of bases) {
|
|
97
|
+
const dirs = [base, ...descendantDirs(base)];
|
|
98
|
+
next.push(...dirs);
|
|
99
|
+
if (trailing)
|
|
100
|
+
for (const d of dirs)
|
|
101
|
+
next.push(...filesIn(d));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else if (!segment.includes('*') && !segment.includes('?')) {
|
|
49
105
|
for (const base of bases) {
|
|
50
106
|
const p = base === '' ? segment : join(base, segment);
|
|
51
107
|
if (existsSync(p))
|
|
@@ -75,24 +131,27 @@ function expandGlob(pattern) {
|
|
|
75
131
|
if (bases.length === 0)
|
|
76
132
|
break;
|
|
77
133
|
}
|
|
78
|
-
return bases.sort();
|
|
134
|
+
return [...new Set(bases)].sort();
|
|
79
135
|
}
|
|
80
136
|
export async function resolve(vars, flags, interactive, cross = false) {
|
|
81
|
-
const values =
|
|
82
|
-
const arrayVars =
|
|
137
|
+
const values = Object.create(null);
|
|
138
|
+
const arrayVars = Object.create(null);
|
|
139
|
+
const defaulted = new Set();
|
|
83
140
|
let hasArrays = false;
|
|
84
141
|
for (const v of vars) {
|
|
85
142
|
// 1. Check flags
|
|
86
|
-
if (v.name
|
|
87
|
-
const expanded = expandArrayValue(flags[v.name]);
|
|
143
|
+
if (Object.hasOwn(flags, v.name)) {
|
|
144
|
+
const expanded = expandArrayValue(flags[v.name], v.name);
|
|
88
145
|
if (expanded.length > 1) {
|
|
89
146
|
arrayVars[v.name] = expanded;
|
|
90
147
|
hasArrays = true;
|
|
148
|
+
continue;
|
|
91
149
|
}
|
|
92
|
-
|
|
150
|
+
// An empty expansion falls through as if the flag were absent
|
|
151
|
+
if (expanded.length === 1) {
|
|
93
152
|
values[v.name] = expanded[0];
|
|
153
|
+
continue;
|
|
94
154
|
}
|
|
95
|
-
continue;
|
|
96
155
|
}
|
|
97
156
|
// 2. Auto-detect
|
|
98
157
|
const auto = autodetect(v.name);
|
|
@@ -103,42 +162,54 @@ export async function resolve(vars, flags, interactive, cross = false) {
|
|
|
103
162
|
// 3. Default
|
|
104
163
|
if (v.defaultValue !== undefined) {
|
|
105
164
|
values[v.name] = v.defaultValue;
|
|
165
|
+
defaulted.add(v.name);
|
|
106
166
|
continue;
|
|
107
167
|
}
|
|
108
168
|
// 4. Ask interactively
|
|
109
169
|
if (interactive) {
|
|
110
|
-
const answer = await ask(` ${v.name}:
|
|
111
|
-
const expanded = expandArrayValue(answer);
|
|
170
|
+
const answer = await ask(` ${v.name}: `, v.name);
|
|
171
|
+
const expanded = expandArrayValue(answer, v.name);
|
|
112
172
|
if (expanded.length > 1) {
|
|
113
173
|
arrayVars[v.name] = expanded;
|
|
114
174
|
hasArrays = true;
|
|
115
175
|
}
|
|
116
176
|
else {
|
|
117
|
-
values[v.name] = expanded[0];
|
|
177
|
+
values[v.name] = expanded[0] ?? '';
|
|
118
178
|
}
|
|
119
179
|
}
|
|
120
180
|
}
|
|
121
181
|
// Build iterations
|
|
122
182
|
if (!hasArrays) {
|
|
123
|
-
return { values, iterations: [values] };
|
|
183
|
+
return { values, iterations: [values], defaulted };
|
|
124
184
|
}
|
|
125
185
|
const arrayNames = Object.keys(arrayVars);
|
|
126
186
|
const iterations = [];
|
|
127
187
|
const arrays = arrayNames.map(n => arrayVars[n]);
|
|
128
188
|
const combos = cross ? cartesian(arrays) : zip(arrays);
|
|
129
189
|
for (const combo of combos) {
|
|
130
|
-
const iter =
|
|
190
|
+
const iter = Object.assign(Object.create(null), values);
|
|
131
191
|
for (let j = 0; j < arrayNames.length; j++) {
|
|
132
192
|
iter[arrayNames[j]] = combo[j];
|
|
133
193
|
}
|
|
134
194
|
iterations.push(iter);
|
|
135
195
|
}
|
|
136
|
-
return { values, iterations };
|
|
196
|
+
return { values, iterations, defaulted };
|
|
137
197
|
}
|
|
138
|
-
function ask(prompt) {
|
|
198
|
+
function ask(prompt, name) {
|
|
139
199
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
140
|
-
return new Promise(resolve => {
|
|
200
|
+
return new Promise((resolve, reject) => {
|
|
201
|
+
let settled = false;
|
|
202
|
+
// Fires on stdin EOF before an answer; without it the Promise never settles.
|
|
203
|
+
rl.on('close', () => {
|
|
204
|
+
if (settled)
|
|
205
|
+
return;
|
|
206
|
+
settled = true;
|
|
207
|
+
reject(new UsageError(`Variable "${name}" has no value and stdin is closed; pass --${name}=<value> or give the blank a default`));
|
|
208
|
+
});
|
|
141
209
|
rl.question(prompt, (answer) => {
|
|
210
|
+
if (settled)
|
|
211
|
+
return;
|
|
212
|
+
settled = true;
|
|
142
213
|
rl.close();
|
|
143
214
|
resolve(answer.trim());
|
|
144
215
|
});
|
package/dist/resolver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/status.d.ts
CHANGED
package/dist/status.js
CHANGED
|
@@ -3,19 +3,20 @@
|
|
|
3
3
|
* Shows current template state: filled vars, unfilled vars, progress.
|
|
4
4
|
*/
|
|
5
5
|
import { sanitizeForTerminal } from './sanitize.js';
|
|
6
|
-
export function renderStatus(templateName, vars, values, iteration) {
|
|
6
|
+
export function renderStatus(templateName, vars, values, iteration, defaulted) {
|
|
7
7
|
const parts = [];
|
|
8
8
|
for (const v of vars) {
|
|
9
|
-
const val = values[v.name];
|
|
9
|
+
const val = Object.hasOwn(values, v.name) ? values[v.name] : undefined;
|
|
10
10
|
if (val !== undefined) {
|
|
11
|
-
const
|
|
11
|
+
const isDefault = defaulted ? defaulted.has(v.name) : v.defaultValue === val;
|
|
12
|
+
const source = isDefault ? '(default)' : '';
|
|
12
13
|
parts.push(`${v.name}=${val}${source}`);
|
|
13
14
|
}
|
|
14
15
|
else {
|
|
15
16
|
parts.push(`${v.name}=___`);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
|
-
const allFilled = vars.every(v => v.name
|
|
19
|
+
const allFilled = vars.every(v => Object.hasOwn(values, v.name));
|
|
19
20
|
const icon = allFilled ? '✅' : '📋';
|
|
20
21
|
const progress = iteration ? ` [${iteration.current}/${iteration.total}]` : '';
|
|
21
22
|
// Values may come from repo-controlled sources (templates, git diff);
|
package/dist/status.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,UAAU,YAAY,CAC1B,YAAoB,EACpB,IAAmB,EACnB,MAA8B,EAC9B,SAA8C;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,UAAU,YAAY,CAC1B,YAAoB,EACpB,IAAmB,EACnB,MAA8B,EAC9B,SAA8C,EAC9C,SAA+B;IAE/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACvE,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,KAAK,GAAG,CAAC;YAC7E,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACpC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/E,sEAAsE;IACtE,+DAA+D;IAC/D,OAAO,mBAAmB,CAAC,GAAG,IAAI,IAAI,YAAY,GAAG,QAAQ,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxF,CAAC"}
|
package/dist/ui.d.ts
CHANGED
|
@@ -10,4 +10,7 @@ export interface StartUIOptions {
|
|
|
10
10
|
openBrowser?: boolean;
|
|
11
11
|
}
|
|
12
12
|
export declare function buildUIHtml(rawHtml: string, envVars: EnvData): string;
|
|
13
|
+
export declare const UI_TOKEN_PARAM = "t";
|
|
14
|
+
export declare const PAGE_HEADERS: Readonly<Record<string, string>>;
|
|
15
|
+
export declare function requestCarriesToken(url: string | undefined, token: string): boolean;
|
|
13
16
|
export declare function startUI(port?: number, options?: StartUIOptions): Server;
|