@hivecommons/promptargs 0.7.0 → 0.8.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 +100 -15
- package/dist/autodetect.js +24 -9
- package/dist/autodetect.js.map +1 -1
- package/dist/cli.js +51 -147
- package/dist/cli.js.map +1 -1
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +130 -0
- package/dist/commands.js.map +1 -0
- package/dist/flags.d.ts +14 -0
- package/dist/flags.js +57 -0
- package/dist/flags.js.map +1 -0
- package/dist/loader.d.ts +2 -0
- package/dist/loader.js +64 -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 +33 -7
- package/dist/parser.js.map +1 -1
- package/dist/resolver.d.ts +2 -0
- package/dist/resolver.js +60 -30
- 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.html +18 -5
- package/dist/ui.js +36 -11
- 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/ui.test.js
DELETED
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { get } from 'node:http';
|
|
4
|
-
import { createServer as createNetServer } from 'node:net';
|
|
5
|
-
import { spawnSync } from 'node:child_process';
|
|
6
|
-
import { copyFileSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
7
|
-
import { join, dirname } from 'node:path';
|
|
8
|
-
import { tmpdir } from 'node:os';
|
|
9
|
-
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
10
|
-
import { buildUIHtml, collectEnvVars, shouldSkipEnv, startUI, truncateValue, } from './ui.js';
|
|
11
|
-
test('shouldSkipEnv filters noisy shell and tooling variables', () => {
|
|
12
|
-
assert.equal(shouldSkipEnv('HOME'), true);
|
|
13
|
-
assert.equal(shouldSkipEnv('npm_config_cache'), true);
|
|
14
|
-
assert.equal(shouldSkipEnv('VSCODE_PID'), true);
|
|
15
|
-
assert.equal(shouldSkipEnv('PROMPTARGS_VISIBLE'), false);
|
|
16
|
-
});
|
|
17
|
-
test('truncateValue shortens long values and leaves short values unchanged', () => {
|
|
18
|
-
assert.equal(truncateValue('short', 10), 'short');
|
|
19
|
-
assert.equal(truncateValue('abcdefghijklmnopqrstuvwxyz', 8), 'abcdefgh...');
|
|
20
|
-
});
|
|
21
|
-
test('collectEnvVars includes terminal env values without skipped keys', () => {
|
|
22
|
-
const savedVisible = process.env['PROMPTARGS_TEST_VISIBLE'];
|
|
23
|
-
const savedHome = process.env['HOME'];
|
|
24
|
-
process.env['PROMPTARGS_TEST_VISIBLE'] = 'visible-value';
|
|
25
|
-
process.env['HOME'] = 'hidden-home';
|
|
26
|
-
try {
|
|
27
|
-
const env = collectEnvVars();
|
|
28
|
-
assert.equal(env.terminal['PROMPTARGS_TEST_VISIBLE'], 'visible-value');
|
|
29
|
-
assert.equal(env.terminal['HOME'], undefined);
|
|
30
|
-
}
|
|
31
|
-
finally {
|
|
32
|
-
if (savedVisible === undefined)
|
|
33
|
-
delete process.env['PROMPTARGS_TEST_VISIBLE'];
|
|
34
|
-
else
|
|
35
|
-
process.env['PROMPTARGS_TEST_VISIBLE'] = savedVisible;
|
|
36
|
-
if (savedHome === undefined)
|
|
37
|
-
delete process.env['HOME'];
|
|
38
|
-
else
|
|
39
|
-
process.env['HOME'] = savedHome;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
test('collectEnvVars omits credential-looking names and credential-shaped values', () => {
|
|
43
|
-
const keys = ['PROMPTARGS_TEST_SIGNING_KEY', 'PROMPTARGS_TEST_DB_URL', 'PROMPTARGS_TEST_PLAIN'];
|
|
44
|
-
const saved = Object.fromEntries(keys.map(k => [k, process.env[k]]));
|
|
45
|
-
process.env['PROMPTARGS_TEST_SIGNING_KEY'] = 'sig';
|
|
46
|
-
process.env['PROMPTARGS_TEST_DB_URL'] = 'postgres://app:hunter2@db.internal/app';
|
|
47
|
-
process.env['PROMPTARGS_TEST_PLAIN'] = 'plain';
|
|
48
|
-
try {
|
|
49
|
-
const env = collectEnvVars();
|
|
50
|
-
assert.equal(env.terminal['PROMPTARGS_TEST_SIGNING_KEY'], undefined);
|
|
51
|
-
assert.equal(env.terminal['PROMPTARGS_TEST_DB_URL'], undefined);
|
|
52
|
-
assert.equal(env.terminal['PROMPTARGS_TEST_PLAIN'], 'plain');
|
|
53
|
-
}
|
|
54
|
-
finally {
|
|
55
|
-
for (const k of keys) {
|
|
56
|
-
if (saved[k] === undefined)
|
|
57
|
-
delete process.env[k];
|
|
58
|
-
else
|
|
59
|
-
process.env[k] = saved[k];
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
test('buildUIHtml escapes env JSON so values cannot escape the script tag', () => {
|
|
64
|
-
const html = buildUIHtml('<html><head><script></script></head></html>', {
|
|
65
|
-
git: {},
|
|
66
|
-
terminal: { PROMPTARGS_TEST: '</script><script>alert(1)</script>' },
|
|
67
|
-
});
|
|
68
|
-
assert.match(html, /window\.__PROMPTARGS_ENV__/);
|
|
69
|
-
assert.doesNotMatch(html, /<\/script><script>alert\(1\)<\/script>/);
|
|
70
|
-
assert.match(html, /\\u003c\/script>\\u003cscript>alert\(1\)\\u003c\/script>/);
|
|
71
|
-
});
|
|
72
|
-
test('startUI binds a server that rejects non-local Host headers', async () => {
|
|
73
|
-
const server = startUI(0, { openBrowser: false });
|
|
74
|
-
await onceListening(server);
|
|
75
|
-
const { port } = server.address();
|
|
76
|
-
try {
|
|
77
|
-
const allowed = await request(port, '127.0.0.1:0');
|
|
78
|
-
assert.equal(allowed.statusCode, 200);
|
|
79
|
-
assert.match(allowed.body, /window\.__PROMPTARGS_ENV__/);
|
|
80
|
-
const forbidden = await request(port, 'evil.example');
|
|
81
|
-
assert.equal(forbidden.statusCode, 403);
|
|
82
|
-
assert.equal(forbidden.body, 'Forbidden');
|
|
83
|
-
}
|
|
84
|
-
finally {
|
|
85
|
-
await closeServer(server);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
test('startUI serves the parser/iterate/mustache modules the browser imports', async () => {
|
|
89
|
-
const server = startUI(0, { openBrowser: false });
|
|
90
|
-
await onceListening(server);
|
|
91
|
-
const { port } = server.address();
|
|
92
|
-
try {
|
|
93
|
-
const parser = await request(port, '127.0.0.1:0', '/parser.js');
|
|
94
|
-
assert.equal(parser.statusCode, 200);
|
|
95
|
-
assert.match(parser.contentType ?? '', /text\/javascript/);
|
|
96
|
-
assert.match(parser.body, /export function parseVars/);
|
|
97
|
-
assert.match(parser.body, /export const VAR_PATTERN/);
|
|
98
|
-
const iterate = await request(port, '127.0.0.1:0', '/iterate.js');
|
|
99
|
-
assert.equal(iterate.statusCode, 200);
|
|
100
|
-
assert.match(iterate.body, /export function cartesian/);
|
|
101
|
-
assert.match(iterate.body, /export function zip/);
|
|
102
|
-
const mustache = await request(port, '127.0.0.1:0', '/mustache.mjs');
|
|
103
|
-
assert.equal(mustache.statusCode, 200);
|
|
104
|
-
assert.match(mustache.body, /export default mustache/);
|
|
105
|
-
const missing = await request(port, '127.0.0.1:0', '/does-not-exist.js');
|
|
106
|
-
assert.equal(missing.statusCode, 200);
|
|
107
|
-
assert.match(missing.body, /window\.__PROMPTARGS_ENV__/);
|
|
108
|
-
}
|
|
109
|
-
finally {
|
|
110
|
-
await closeServer(server);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
test('startUI answers 404 for a static route whose backing file is missing', () => {
|
|
114
|
-
// Copy the compiled ui.js (plus its one local dep) into a directory
|
|
115
|
-
// without parser.js/iterate.js/mustache.mjs, so requesting a known static
|
|
116
|
-
// route hits the readFileSync catch branch.
|
|
117
|
-
const __dirnameUi = dirname(fileURLToPath(import.meta.url));
|
|
118
|
-
const dir = mkdtempSync(join(tmpdir(), 'promptargs-ui-static-'));
|
|
119
|
-
try {
|
|
120
|
-
for (const f of ['ui.js', 'ui.html', 'autodetect.js']) {
|
|
121
|
-
copyFileSync(join(__dirnameUi, f), join(dir, f));
|
|
122
|
-
}
|
|
123
|
-
writeFileSync(join(dir, 'package.json'), '{"type":"module"}');
|
|
124
|
-
// Intentionally omit parser.js/iterate.js/mustache.mjs so the route 404s.
|
|
125
|
-
const script = `
|
|
126
|
-
import { get } from 'node:http';
|
|
127
|
-
import(${JSON.stringify(pathToFileURL(join(dir, 'ui.js')).href)})
|
|
128
|
-
.then(m => {
|
|
129
|
-
const server = m.startUI(0, { openBrowser: false });
|
|
130
|
-
server.once('listening', () => {
|
|
131
|
-
const { port } = server.address();
|
|
132
|
-
get({
|
|
133
|
-
hostname: '127.0.0.1', port, path: '/parser.js',
|
|
134
|
-
headers: { Host: '127.0.0.1:0' },
|
|
135
|
-
}, res => {
|
|
136
|
-
process.stdout.write('STATUS:' + res.statusCode);
|
|
137
|
-
server.close(() => process.exit(0));
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
`;
|
|
142
|
-
const res = spawnSync(process.execPath, ['--input-type=module', '-e', script], {
|
|
143
|
-
encoding: 'utf-8',
|
|
144
|
-
timeout: 15000,
|
|
145
|
-
});
|
|
146
|
-
assert.match(res.stdout, /STATUS:404/, res.stderr);
|
|
147
|
-
}
|
|
148
|
-
finally {
|
|
149
|
-
rmSync(dir, { recursive: true, force: true });
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
function onceListening(server) {
|
|
153
|
-
if (server.listening)
|
|
154
|
-
return Promise.resolve();
|
|
155
|
-
return new Promise(resolve => server.once('listening', resolve));
|
|
156
|
-
}
|
|
157
|
-
function closeServer(server) {
|
|
158
|
-
return new Promise((resolve, reject) => {
|
|
159
|
-
server.close(err => err ? reject(err) : resolve());
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
function request(port, host, path = '/') {
|
|
163
|
-
return new Promise((resolve, reject) => {
|
|
164
|
-
const req = get({
|
|
165
|
-
hostname: '127.0.0.1',
|
|
166
|
-
port,
|
|
167
|
-
path,
|
|
168
|
-
headers: { Host: host },
|
|
169
|
-
}, res => {
|
|
170
|
-
let body = '';
|
|
171
|
-
res.setEncoding('utf8');
|
|
172
|
-
res.on('data', chunk => { body += chunk; });
|
|
173
|
-
res.on('end', () => resolve({
|
|
174
|
-
statusCode: res.statusCode ?? 0,
|
|
175
|
-
body,
|
|
176
|
-
contentType: res.headers['content-type'],
|
|
177
|
-
}));
|
|
178
|
-
});
|
|
179
|
-
req.on('error', reject);
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
// startUI exits the process on fatal errors, so those branches are
|
|
183
|
-
// exercised in a child node process rather than in-process.
|
|
184
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
185
|
-
function runStartUI(uiModulePath, port) {
|
|
186
|
-
const script = `
|
|
187
|
-
import(${JSON.stringify(pathToFileURL(uiModulePath).href)})
|
|
188
|
-
.then(m => m.startUI(${port}, { openBrowser: false }));
|
|
189
|
-
`;
|
|
190
|
-
const res = spawnSync(process.execPath, ['--input-type=module', '-e', script], {
|
|
191
|
-
encoding: 'utf-8',
|
|
192
|
-
timeout: 15000,
|
|
193
|
-
});
|
|
194
|
-
return { status: res.status, stderr: res.stderr };
|
|
195
|
-
}
|
|
196
|
-
test('startUI exits 1 with a port hint when the port is in use', async () => {
|
|
197
|
-
const blocker = createNetServer();
|
|
198
|
-
await new Promise(resolve => blocker.listen(0, '127.0.0.1', resolve));
|
|
199
|
-
const { port } = blocker.address();
|
|
200
|
-
try {
|
|
201
|
-
const res = runStartUI(join(__dirname, 'ui.js'), port);
|
|
202
|
-
assert.strictEqual(res.status, 1);
|
|
203
|
-
assert.match(res.stderr, new RegExp(`Port ${port} is in use`));
|
|
204
|
-
assert.match(res.stderr, new RegExp(`--port=${port + 1}`));
|
|
205
|
-
}
|
|
206
|
-
finally {
|
|
207
|
-
await new Promise(resolve => blocker.close(resolve));
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
test('startUI exits 1 with a reinstall hint when ui.html is missing', () => {
|
|
211
|
-
// Copy the compiled module (and its one local dep) somewhere without
|
|
212
|
-
// ui.html so the readFileSync catch branch runs.
|
|
213
|
-
const dir = mkdtempSync(join(tmpdir(), 'promptargs-ui-test-'));
|
|
214
|
-
try {
|
|
215
|
-
copyFileSync(join(__dirname, 'ui.js'), join(dir, 'ui.js'));
|
|
216
|
-
copyFileSync(join(__dirname, 'autodetect.js'), join(dir, 'autodetect.js'));
|
|
217
|
-
// Node 18 has no ESM syntax detection; mark the temp dir as ESM.
|
|
218
|
-
writeFileSync(join(dir, 'package.json'), '{"type":"module"}');
|
|
219
|
-
const res = runStartUI(join(dir, 'ui.js'), 0);
|
|
220
|
-
assert.strictEqual(res.status, 1);
|
|
221
|
-
assert.match(res.stderr, /UI file not found\. Reinstall @hivecommons\/promptargs\./);
|
|
222
|
-
}
|
|
223
|
-
finally {
|
|
224
|
-
rmSync(dir, { recursive: true, force: true });
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
test('startUI schedules a browser open by default', () => {
|
|
228
|
-
// openBrowser defaults to true; run in a child with an empty PATH so the
|
|
229
|
-
// platform open command is a harmless shell failure, never a real browser.
|
|
230
|
-
const script = `
|
|
231
|
-
import(${JSON.stringify(pathToFileURL(join(__dirname, 'ui.js')).href)})
|
|
232
|
-
.then(m => {
|
|
233
|
-
const server = m.startUI(0);
|
|
234
|
-
setTimeout(() => server.close(() => process.exit(0)), 900);
|
|
235
|
-
});
|
|
236
|
-
`;
|
|
237
|
-
const res = spawnSync(process.execPath, ['--input-type=module', '-e', script], {
|
|
238
|
-
encoding: 'utf-8',
|
|
239
|
-
timeout: 15000,
|
|
240
|
-
env: { ...process.env, PATH: '' },
|
|
241
|
-
});
|
|
242
|
-
assert.strictEqual(res.status, 0);
|
|
243
|
-
assert.match(res.stdout, /promptargs builder running at http:\/\/localhost:\d+/);
|
|
244
|
-
});
|
|
245
|
-
test('browser open picks the right command for each platform', () => {
|
|
246
|
-
// The darwin/win32 arms of the open-command ternary never run on Linux CI;
|
|
247
|
-
// force each platform value in a child and let the command fail on PATH=''.
|
|
248
|
-
for (const platform of ['darwin', 'win32', 'linux']) {
|
|
249
|
-
const script = `
|
|
250
|
-
Object.defineProperty(process, 'platform', { value: ${JSON.stringify(platform)} });
|
|
251
|
-
import(${JSON.stringify(pathToFileURL(join(__dirname, 'ui.js')).href)})
|
|
252
|
-
.then(m => {
|
|
253
|
-
const server = m.startUI(0);
|
|
254
|
-
setTimeout(() => server.close(() => process.exit(0)), 900);
|
|
255
|
-
});
|
|
256
|
-
`;
|
|
257
|
-
const res = spawnSync(process.execPath, ['--input-type=module', '-e', script], {
|
|
258
|
-
encoding: 'utf-8',
|
|
259
|
-
timeout: 15000,
|
|
260
|
-
env: { ...process.env, PATH: '' },
|
|
261
|
-
});
|
|
262
|
-
assert.strictEqual(res.status, 0, `platform ${platform}: ${res.stderr}`);
|
|
263
|
-
assert.match(res.stdout, /promptargs builder running at http:\/\/localhost:\d+/);
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
test('startUI rethrows non-EADDRINUSE server errors', async (t) => {
|
|
267
|
-
// Only run where binding port 1 really fails with EACCES; containers with
|
|
268
|
-
// ip_unprivileged_port_start=0 (or root) can bind it and would hang instead.
|
|
269
|
-
const probeErr = await new Promise(resolve => {
|
|
270
|
-
const probe = createNetServer();
|
|
271
|
-
probe.once('error', err => resolve(err));
|
|
272
|
-
probe.listen(1, '127.0.0.1', () => probe.close(() => resolve(null)));
|
|
273
|
-
});
|
|
274
|
-
if (probeErr?.code !== 'EACCES') {
|
|
275
|
-
t.skip('binding port 1 did not fail with EACCES');
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
const res = runStartUI(join(__dirname, 'ui.js'), 1);
|
|
279
|
-
assert.notStrictEqual(res.status, 0);
|
|
280
|
-
assert.match(res.stderr, /EACCES/);
|
|
281
|
-
assert.doesNotMatch(res.stderr, /is in use/);
|
|
282
|
-
});
|
|
283
|
-
//# sourceMappingURL=ui.test.js.map
|
package/dist/ui.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ui.test.js","sourceRoot":"","sources":["../src/ui.test.ts"],"names":[],"mappings":"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"}
|