1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | exports.captureOutput = captureOutput;
|
7 | exports.runCommand = runCommand;
|
8 | exports.runHook = runHook;
|
9 | const core_1 = require("@oclif/core");
|
10 | const ansis_1 = __importDefault(require("ansis"));
|
11 | const debug_1 = __importDefault(require("debug"));
|
12 | const node_path_1 = require("node:path");
|
13 | const debug = (0, debug_1.default)('oclif-test');
|
14 | function traverseFilePathUntil(filename, predicate) {
|
15 | let current = filename;
|
16 | while (!predicate(current)) {
|
17 | current = (0, node_path_1.dirname)(current);
|
18 | }
|
19 | return current;
|
20 | }
|
21 | function findRoot() {
|
22 | return (process.env.OCLIF_TEST_ROOT ??
|
23 |
|
24 | Object.values(require.cache).find((m) => m?.children.includes(module))?.filename ??
|
25 | traverseFilePathUntil(
|
26 |
|
27 | require.main?.path ?? module.path, (p) => !(p.includes('node_modules') || p.includes('.pnpm') || p.includes('.yarn'))));
|
28 | }
|
29 | function makeLoadOptions(loadOpts) {
|
30 | return loadOpts ?? { root: findRoot() };
|
31 | }
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 | function splitString(str) {
|
45 | return (str.match(/(?:[^\s"]+|"[^"]*")+/g) ?? []).map((s) => s.replaceAll(/^"|"$|(?<==)"/g, ''));
|
46 | }
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 | async function captureOutput(fn, opts) {
|
60 | const print = opts?.print ?? false;
|
61 | const stripAnsi = opts?.stripAnsi ?? true;
|
62 | const originals = {
|
63 | NODE_ENV: process.env.NODE_ENV,
|
64 | stderr: process.stderr.write,
|
65 | stdout: process.stdout.write,
|
66 | };
|
67 | const output = {
|
68 | stderr: [],
|
69 | stdout: [],
|
70 | };
|
71 | const toString = (str) => (stripAnsi ? ansis_1.default.strip(str.toString()) : str.toString());
|
72 | const getStderr = () => output.stderr.map((b) => toString(b)).join('');
|
73 | const getStdout = () => output.stdout.map((b) => toString(b)).join('');
|
74 | const mock = (std) => (str, encoding, cb) => {
|
75 | output[std].push(str);
|
76 | if (print) {
|
77 | if (encoding !== null && typeof encoding === 'function') {
|
78 | cb = encoding;
|
79 | encoding = undefined;
|
80 | }
|
81 | originals[std].apply(process[std], [str, encoding, cb]);
|
82 | }
|
83 | else if (typeof cb === 'function')
|
84 | cb();
|
85 | return true;
|
86 | };
|
87 | process.stdout.write = mock('stdout');
|
88 | process.stderr.write = mock('stderr');
|
89 | process.env.NODE_ENV = 'test';
|
90 | try {
|
91 | const result = await fn();
|
92 | return {
|
93 | result: result,
|
94 | stderr: getStderr(),
|
95 | stdout: getStdout(),
|
96 | };
|
97 | }
|
98 | catch (error) {
|
99 | return {
|
100 | ...(error instanceof core_1.Errors.CLIError && { error: { ...error, message: toString(error.message) } }),
|
101 | ...(error instanceof Error && { error: { ...error, message: toString(error.message) } }),
|
102 | stderr: getStderr(),
|
103 | stdout: getStdout(),
|
104 | };
|
105 | }
|
106 | finally {
|
107 | process.stderr.write = originals.stderr;
|
108 | process.stdout.write = originals.stdout;
|
109 | process.env.NODE_ENV = originals.NODE_ENV;
|
110 | }
|
111 | }
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | async function runCommand(args, loadOpts, captureOpts) {
|
126 | const loadOptions = makeLoadOptions(loadOpts);
|
127 | const argsArray = splitString((Array.isArray(args) ? args : [args]).join(' '));
|
128 | const [id, ...rest] = argsArray;
|
129 | const finalArgs = id === '.' ? rest : argsArray;
|
130 | debug('loadOpts: %O', loadOptions);
|
131 | debug('args: %O', finalArgs);
|
132 | return captureOutput(async () => (0, core_1.run)(finalArgs, loadOptions), captureOpts);
|
133 | }
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | async function runHook(hook, options, loadOpts, captureOpts) {
|
149 | const loadOptions = makeLoadOptions(loadOpts);
|
150 | debug('loadOpts: %O', loadOptions);
|
151 | return captureOutput(async () => {
|
152 | const config = await core_1.Config.load(loadOptions);
|
153 | return config.runHook(hook, options);
|
154 | }, captureOpts);
|
155 | }
|