-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcli.cjs
More file actions
75 lines (61 loc) · 2.87 KB
/
Copy pathcli.cjs
File metadata and controls
75 lines (61 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
'use strict';
const process = require('node:process');
if (process.argv.slice(2).includes('-?')) {
// eslint-disable-next-line no-console
console.log(`Usage: texample [files] [blockIdx] [-r <file>]... [-c <config>] [-i] [-?]
files comma-separated list of markdown files (default ./README.md)
blockIdx 0-based index of a single \`\`\`javascript block to run
-r <path> ESM file evaluated in the example's vm context before the example
runs. May be repeated to chain multiple setup files. Paths are
resolved relative to cwd. Use this to mutate the sandbox itself
(e.g. override globalThis.fetch).
-c <path> JSON config file with { "require": [...], "node-option": [...] }
\`require\` paths are resolved relative to the config file and run
as -r setup files in the vm context; \`node-option\` entries are
appended to the always-on defaults (--experimental-vm-modules
--no-warnings) and forwarded as --<option> in execArgv. Use this
for process-level setup that has to be in place before texample
itself can run (e.g. extra Node flags, host-process polyfills).
-i exit 0 even when an example throws — errors are still printed to
stderr, but the process status is silenced.
-? show this help
The vm context defaults to globalThis — examples have access to fetch,
EventTarget, performance, and the rest of Node's runtime. Each invocation runs
in its own forked child process, so mutations don't leak across runs.
Examples:
texample ./README.md
texample ./README.md,./docs/API.md
texample ./README.md 2
texample ./example.md -r ./deny-fetch.mjs -r ./mock-time.mjs
texample ./example.md -c ./texample-config.json`);
return;
}
const vm = require('node:vm');
const { resolve: resolvePath } = require('node:path');
const { ExampleEvaluator } = require('./dist/index.cjs');
if (!('SourceTextModule' in vm)) throw new Error('No SourceTextModule in vm, try using node --experimental-vm-modules flag');
const CWD = process.cwd();
const packageDefinition = require(resolvePath(CWD, 'package.json'));
let blockIdx = NaN;
let markdownFiles = './README.md';
let ignoreExit = false;
const setupFiles = [];
const argv = process.argv.slice(2);
for (let i = 0; i < argv.length; i++) {
const arg = argv[i];
if (arg === '-g') continue;
else if (arg === '-i') ignoreExit = true;
else if (arg === '-r') setupFiles.push(argv[++i]);
else if (!isNaN(Number(arg))) blockIdx = Number(arg);
else markdownFiles = arg;
}
run().catch((err) => {
// eslint-disable-next-line no-console
console.error(err.stack);
if (!ignoreExit) process.exitCode = 1;
});
async function run() {
for (const filePath of markdownFiles.split(',')) {
await new ExampleEvaluator(filePath, packageDefinition, CWD, undefined, setupFiles).evaluate(blockIdx);
}
}