headlamp 0.1.28 → 0.1.29

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.
@@ -0,0 +1,201 @@
1
+ /* eslint-disable global-require */
2
+ /* eslint-disable @typescript-eslint/no-require-imports */
3
+ /* eslint-disable import/no-dynamic-require */
4
+
5
+ (function setupBridge() {
6
+ try {
7
+ const print = (payload) => {
8
+ try {
9
+ const line = `[JEST-BRIDGE-EVENT] ${JSON.stringify(payload)}`;
10
+ (process.stderr || process.stdout).write(`${line}\n`);
11
+ } catch {}
12
+ };
13
+
14
+ const toErr = (x) => {
15
+ try {
16
+ return x instanceof Error ? x : new Error(String(x));
17
+ } catch {
18
+ return new Error('unknown');
19
+ }
20
+ };
21
+
22
+ const getCtx = () => {
23
+ try {
24
+ const st =
25
+ global.expect && typeof global.expect.getState === 'function'
26
+ ? global.expect.getState()
27
+ : {};
28
+ return { testPath: st.testPath, currentTestName: st.currentTestName };
29
+ } catch {
30
+ return {};
31
+ }
32
+ };
33
+
34
+ // Capture console output during tests
35
+ try {
36
+ const g = global;
37
+ const levels = ['log', 'info', 'warn', 'error'];
38
+ const originals = {};
39
+ const maxEntries = 200;
40
+ const toText = (args) => {
41
+ try {
42
+ return args.map((v) => (typeof v === 'string' ? v : JSON.stringify(v))).join(' ');
43
+ } catch {
44
+ return args.map(String).join(' ');
45
+ }
46
+ };
47
+ if (!g.__JEST_CONSOLE_BUFFER__) g.__JEST_CONSOLE_BUFFER__ = [];
48
+ for (const lvl of levels) {
49
+ try {
50
+ originals[lvl] =
51
+ g.console[lvl] && g.console[lvl].bind ? g.console[lvl].bind(g.console) : g.console[lvl];
52
+ g.console[lvl] = (...args) => {
53
+ try {
54
+ const buf = Array.isArray(g.__JEST_CONSOLE_BUFFER__)
55
+ ? g.__JEST_CONSOLE_BUFFER__
56
+ : (g.__JEST_CONSOLE_BUFFER__ = []);
57
+ const msg = toText(args);
58
+ buf.push({ type: lvl, message: msg, ts: Date.now() });
59
+ if (buf.length > maxEntries) buf.splice(0, buf.length - maxEntries);
60
+ const ctx = getCtx();
61
+ print({ type: 'console', level: lvl, message: msg, ...ctx });
62
+ } catch {}
63
+ try {
64
+ return originals[lvl](...args);
65
+ } catch {
66
+ return undefined;
67
+ }
68
+ };
69
+ } catch {}
70
+ }
71
+ } catch {}
72
+
73
+ // Process-level error hooks
74
+ try {
75
+ const onRej = (reason) => {
76
+ const e = toErr(reason);
77
+ const c = getCtx();
78
+ print({
79
+ type: 'unhandledRejection',
80
+ name: e.name,
81
+ message: e.message,
82
+ stack: e.stack,
83
+ code: e.code ?? undefined,
84
+ ...c,
85
+ });
86
+ };
87
+ const onExc = (error) => {
88
+ const e = toErr(error);
89
+ const c = getCtx();
90
+ print({
91
+ type: 'uncaughtException',
92
+ name: e.name,
93
+ message: e.message,
94
+ stack: e.stack,
95
+ code: e.code ?? undefined,
96
+ ...c,
97
+ });
98
+ };
99
+ process.on('unhandledRejection', onRej);
100
+ process.on('uncaughtException', onExc);
101
+ } catch {}
102
+
103
+ // HTTP response patch
104
+ try {
105
+ const http = require('node:http');
106
+ const PATCH_FLAG = Symbol.for('jestBridgePatched');
107
+ const ORIGINAL_KEY = Symbol.for('jestBridgeOriginalEmit');
108
+ const originalEmit =
109
+ http &&
110
+ http.Server &&
111
+ http.Server.prototype &&
112
+ typeof http.Server.prototype.emit === 'function'
113
+ ? http.Server.prototype.emit
114
+ : null;
115
+ if (originalEmit && !http.Server.prototype.emit[PATCH_FLAG]) {
116
+ const MAX = 64 * 1024;
117
+ const asString = (x) => {
118
+ try {
119
+ if (typeof x === 'string') return x;
120
+ if (Buffer.isBuffer(x)) return x.toString('utf8');
121
+ return String(x);
122
+ } catch {
123
+ return '';
124
+ }
125
+ };
126
+ const patched = function (eventName, req, res) {
127
+ try {
128
+ if (
129
+ eventName === 'request' &&
130
+ req &&
131
+ res &&
132
+ typeof res.write === 'function' &&
133
+ typeof res.end === 'function'
134
+ ) {
135
+ const startAt = Date.now();
136
+ const chunks = [];
137
+ const write = res.write.bind(res);
138
+ const end = res.end.bind(res);
139
+ const method = req.method ? String(req.method) : undefined;
140
+ const url =
141
+ req.originalUrl || req.url ? String(req.originalUrl || req.url) : undefined;
142
+ res.write = function (chunk, enc, cb) {
143
+ try {
144
+ const s = asString(chunk);
145
+ if (s) chunks.push(s);
146
+ } catch {}
147
+ return write(chunk, enc, cb);
148
+ };
149
+ res.end = function (chunk, enc, cb) {
150
+ try {
151
+ const s = asString(chunk);
152
+ if (s) chunks.push(s);
153
+ } catch {}
154
+ try {
155
+ const preview = chunks.join('').slice(0, MAX);
156
+ const statusCode =
157
+ typeof res.statusCode === 'number' ? res.statusCode : undefined;
158
+ const ctx = getCtx();
159
+ print({
160
+ type: 'httpResponse',
161
+ timestampMs: Date.now(),
162
+ durationMs: Math.max(0, Date.now() - startAt),
163
+ method,
164
+ url,
165
+ statusCode,
166
+ bodyPreview: preview,
167
+ ...ctx,
168
+ });
169
+ } catch {}
170
+ return end(chunk, enc, cb);
171
+ };
172
+ try {
173
+ res.on('close', () => {
174
+ try {
175
+ const ended =
176
+ typeof res.writableEnded === 'boolean' ? res.writableEnded : false;
177
+ if (!ended) {
178
+ const ctx = getCtx();
179
+ print({
180
+ type: 'httpAbort',
181
+ timestampMs: Date.now(),
182
+ durationMs: Math.max(0, Date.now() - startAt),
183
+ method,
184
+ url,
185
+ ...ctx,
186
+ });
187
+ }
188
+ } catch {}
189
+ });
190
+ } catch {}
191
+ }
192
+ } catch {}
193
+ return originalEmit.apply(this, arguments);
194
+ };
195
+ patched[PATCH_FLAG] = true;
196
+ patched[ORIGINAL_KEY] = originalEmit;
197
+ http.Server.prototype.emit = patched;
198
+ }
199
+ } catch {}
200
+ } catch {}
201
+ })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "headlamp",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "Coverage-first, runner-agnostic test UX CLI for Jest",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/scripts/build.mjs CHANGED
@@ -118,6 +118,6 @@ const cliContent = await (await import('node:fs/promises')).readFile(cliPath, 'u
118
118
  await writeFile(cliPath, `#!/usr/bin/env node\n${cliContent}`);
119
119
  await chmod(cliPath, 0o755);
120
120
 
121
- // Copy Jest runtime assets (env/reporter) to dist so Jest can require them by absolute path
121
+ // Copy Jest runtime assets (reporter/setup) to dist so Jest can require them by absolute path
122
122
  await mkdir(resolve(dist, 'jest'), { recursive: true });
123
123
  await cp(resolve(src, 'jest'), resolve(dist, 'jest'), { recursive: true });