headlamp 0.1.33 → 0.1.35
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 +104 -152
- package/bin/.gitkeep +4 -0
- package/bin/darwin-arm64/headlamp +0 -0
- package/dist/cli.cjs +50 -61814
- package/dist/postinstall.cjs +181 -0
- package/package.json +24 -61
- package/dist/cli.cjs.map +0 -7
- package/dist/index.js +0 -63488
- package/dist/index.js.map +0 -7
- package/dist/jest/reporter.cjs +0 -193
- package/dist/jest/setup.cjs +0 -201
- package/scripts/build.mjs +0 -123
- package/scripts/postinstall.mjs +0 -13
- package/scripts/print-publish-log.mjs +0 -29
package/dist/jest/reporter.cjs
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
/* eslint-disable global-require */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
3
|
-
/* eslint-disable import/no-dynamic-require */
|
|
4
|
-
|
|
5
|
-
const fs = require('node:fs');
|
|
6
|
-
const path = require('node:path');
|
|
7
|
-
|
|
8
|
-
const print = (payload) => {
|
|
9
|
-
try {
|
|
10
|
-
const line = `[JEST-BRIDGE-EVENT] ${JSON.stringify(payload)}`;
|
|
11
|
-
(process.stderr || process.stdout).write(`${line}\n`);
|
|
12
|
-
} catch {}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const isObject = (v) => typeof v === 'object' && v !== null;
|
|
16
|
-
const sanitizeError = (err) => {
|
|
17
|
-
if (!isObject(err)) return err;
|
|
18
|
-
const out = {};
|
|
19
|
-
const name = err.name || (err.constructor && err.constructor.name) || undefined;
|
|
20
|
-
if (name) out.name = String(name);
|
|
21
|
-
if (typeof err.message === 'string') out.message = err.message;
|
|
22
|
-
if (typeof err.stack === 'string') out.stack = err.stack;
|
|
23
|
-
if (err.code !== undefined) out.code = err.code;
|
|
24
|
-
if (err.expected !== undefined) out.expected = err.expected;
|
|
25
|
-
if (err.received !== undefined) out.received = err.received;
|
|
26
|
-
if (err.matcherResult && isObject(err.matcherResult)) {
|
|
27
|
-
const mr = err.matcherResult;
|
|
28
|
-
let messageText;
|
|
29
|
-
try {
|
|
30
|
-
messageText =
|
|
31
|
-
typeof mr.message === 'function'
|
|
32
|
-
? String(mr.message())
|
|
33
|
-
: typeof mr.message === 'string'
|
|
34
|
-
? mr.message
|
|
35
|
-
: undefined;
|
|
36
|
-
} catch {}
|
|
37
|
-
out.matcherResult = {
|
|
38
|
-
matcherName: typeof mr.matcherName === 'string' ? mr.matcherName : undefined,
|
|
39
|
-
message: messageText,
|
|
40
|
-
stack: typeof mr.stack === 'string' ? mr.stack : undefined,
|
|
41
|
-
expected: mr.expected,
|
|
42
|
-
received: mr.received,
|
|
43
|
-
actual: mr.actual,
|
|
44
|
-
pass: typeof mr.pass === 'boolean' ? mr.pass : undefined,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
if (err.cause) {
|
|
48
|
-
out.cause = sanitizeError(err.cause);
|
|
49
|
-
}
|
|
50
|
-
// Copy own enumerable props to preserve custom data
|
|
51
|
-
try {
|
|
52
|
-
for (const key of Object.keys(err)) {
|
|
53
|
-
if (!(key in out)) out[key] = err[key];
|
|
54
|
-
}
|
|
55
|
-
} catch {}
|
|
56
|
-
return out;
|
|
57
|
-
};
|
|
58
|
-
const sanitizeDetail = (d) => {
|
|
59
|
-
if (typeof d === 'string') return d;
|
|
60
|
-
if (!isObject(d)) return d;
|
|
61
|
-
// Common Jest detail shapes
|
|
62
|
-
const out = {};
|
|
63
|
-
if (d.message) out.message = d.message;
|
|
64
|
-
if (d.stack) out.stack = d.stack;
|
|
65
|
-
if (d.error) out.error = sanitizeError(d.error);
|
|
66
|
-
if (d.matcherResult) {
|
|
67
|
-
out.matcherResult = sanitizeError({ matcherResult: d.matcherResult }).matcherResult;
|
|
68
|
-
}
|
|
69
|
-
if (d.expected !== undefined) out.expected = d.expected;
|
|
70
|
-
if (d.received !== undefined) out.received = d.received;
|
|
71
|
-
// Copy the rest
|
|
72
|
-
try {
|
|
73
|
-
for (const key of Object.keys(d)) {
|
|
74
|
-
if (!(key in out)) out[key] = d[key];
|
|
75
|
-
}
|
|
76
|
-
} catch {}
|
|
77
|
-
return out;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
class BridgeReporter {
|
|
81
|
-
constructor(globalConfig, options) {
|
|
82
|
-
this.out =
|
|
83
|
-
process.env.JEST_BRIDGE_OUT ||
|
|
84
|
-
(options && options.outFile) ||
|
|
85
|
-
path.join(process.cwd(), 'coverage', 'jest-run.json');
|
|
86
|
-
this.buf = { startTime: Date.now(), testResults: [], aggregated: null };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
onRunStart() {
|
|
90
|
-
this.buf.startTime = Date.now();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
onTestResult(_test, tr) {
|
|
94
|
-
const mapAssertion = (a) => ({
|
|
95
|
-
title: a.title,
|
|
96
|
-
fullName: a.fullName || [...(a.ancestorTitles || []), a.title].join(' '),
|
|
97
|
-
status: a.status,
|
|
98
|
-
timedOut: Boolean(
|
|
99
|
-
a.status === 'failed' &&
|
|
100
|
-
String(a.failureMessages || '')
|
|
101
|
-
.toLowerCase()
|
|
102
|
-
.includes('timed out'),
|
|
103
|
-
),
|
|
104
|
-
duration: a.duration || 0,
|
|
105
|
-
location: a.location || null,
|
|
106
|
-
failureMessages: (a.failureMessages || []).map(String),
|
|
107
|
-
failureDetails: (a.failureDetails || []).map(sanitizeDetail),
|
|
108
|
-
});
|
|
109
|
-
this.buf.testResults.push({
|
|
110
|
-
testFilePath: tr.testFilePath,
|
|
111
|
-
// Consider suite-level errors as failures even when no individual assertions failed
|
|
112
|
-
status:
|
|
113
|
-
(tr && typeof tr.numFailingTests === 'number' && tr.numFailingTests > 0) ||
|
|
114
|
-
Boolean(tr.testExecError) ||
|
|
115
|
-
Boolean(tr.failureMessage)
|
|
116
|
-
? 'failed'
|
|
117
|
-
: 'passed',
|
|
118
|
-
timedOut: Boolean(
|
|
119
|
-
(tr.testExecError &&
|
|
120
|
-
/timed out/i.test(
|
|
121
|
-
String(tr.testExecError && (tr.testExecError.message || tr.testExecError)),
|
|
122
|
-
)) ||
|
|
123
|
-
/timed out/i.test(String(tr.failureMessage || '')),
|
|
124
|
-
),
|
|
125
|
-
failureMessage: tr.failureMessage || '',
|
|
126
|
-
failureDetails: (tr.failureDetails || []).map(sanitizeDetail),
|
|
127
|
-
testExecError: tr.testExecError ? sanitizeError(tr.testExecError) : null,
|
|
128
|
-
console: tr.console || null,
|
|
129
|
-
perfStats: tr.perfStats || {},
|
|
130
|
-
testResults: (tr.testResults || []).map(mapAssertion),
|
|
131
|
-
});
|
|
132
|
-
try {
|
|
133
|
-
print({
|
|
134
|
-
type: 'suiteComplete',
|
|
135
|
-
testPath: tr.testFilePath,
|
|
136
|
-
numPassingTests: tr.numPassingTests,
|
|
137
|
-
numFailingTests: tr.numFailingTests,
|
|
138
|
-
});
|
|
139
|
-
} catch {}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
onRunComplete(_contexts, agg) {
|
|
143
|
-
// Compute timed out counts heuristically from test results & errors
|
|
144
|
-
const suiteTimedOut = (r) =>
|
|
145
|
-
Boolean(
|
|
146
|
-
(r.testExecError &&
|
|
147
|
-
/timed out/i.test(
|
|
148
|
-
String(r.testExecError && (r.testExecError.message || r.testExecError)),
|
|
149
|
-
)) ||
|
|
150
|
-
/timed out/i.test(String(r.failureMessage || '')),
|
|
151
|
-
);
|
|
152
|
-
const fileTimeouts = this.buf.testResults.filter(suiteTimedOut);
|
|
153
|
-
const testTimeouts = this.buf.testResults
|
|
154
|
-
.flatMap((r) => r.testResults || [])
|
|
155
|
-
.filter((a) => a && a.timedOut);
|
|
156
|
-
// Recompute suite pass/fail counts to include suite-level errors/timeouts
|
|
157
|
-
const totalSuites = typeof agg.numTotalTestSuites === 'number' ? agg.numTotalTestSuites : 0;
|
|
158
|
-
const failedSuites = this.buf.testResults.filter(
|
|
159
|
-
(r) => r.status === 'failed' || r.testExecError || r.failureMessage,
|
|
160
|
-
).length;
|
|
161
|
-
const passedSuites = Math.max(0, totalSuites - failedSuites);
|
|
162
|
-
const failedAssertions = typeof agg.numFailedTests === 'number' ? agg.numFailedTests : 0;
|
|
163
|
-
const suiteOnlyFailures = Math.max(0, failedSuites - failedAssertions);
|
|
164
|
-
const failedTestsInclSuiteErrors = failedAssertions + suiteOnlyFailures;
|
|
165
|
-
|
|
166
|
-
this.buf.aggregated = {
|
|
167
|
-
numTotalTestSuites: totalSuites,
|
|
168
|
-
numPassedTestSuites: passedSuites,
|
|
169
|
-
numFailedTestSuites: failedSuites,
|
|
170
|
-
numTotalTests: agg.numTotalTests,
|
|
171
|
-
numPassedTests: agg.numPassedTests,
|
|
172
|
-
numFailedTests: failedTestsInclSuiteErrors,
|
|
173
|
-
numPendingTests: agg.numPendingTests,
|
|
174
|
-
numTodoTests: agg.numTodoTests,
|
|
175
|
-
numTimedOutTests: testTimeouts.length,
|
|
176
|
-
numTimedOutTestSuites: fileTimeouts.length,
|
|
177
|
-
startTime: agg.startTime,
|
|
178
|
-
success:
|
|
179
|
-
Boolean(agg.success) &&
|
|
180
|
-
failedSuites === 0 &&
|
|
181
|
-
failedTestsInclSuiteErrors === 0 &&
|
|
182
|
-
fileTimeouts.length === 0,
|
|
183
|
-
runTimeMs: agg.testResults.reduce(
|
|
184
|
-
(t, r) => t + Math.max(0, (r.perfStats?.end || 0) - (r.perfStats?.start || 0)),
|
|
185
|
-
0,
|
|
186
|
-
),
|
|
187
|
-
};
|
|
188
|
-
fs.mkdirSync(path.dirname(this.out), { recursive: true });
|
|
189
|
-
fs.writeFileSync(this.out, JSON.stringify(this.buf), 'utf8');
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
module.exports = BridgeReporter;
|
package/dist/jest/setup.cjs
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
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/scripts/build.mjs
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { rm, mkdir, writeFile, chmod, cp } from 'node:fs/promises';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
|
|
4
|
-
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
5
|
-
import { build } from 'esbuild';
|
|
6
|
-
|
|
7
|
-
const root = resolve(new URL('.', import.meta.url).pathname, '..');
|
|
8
|
-
const src = resolve(root, 'src');
|
|
9
|
-
const dist = resolve(root, 'dist');
|
|
10
|
-
|
|
11
|
-
await rm(dist, { recursive: true, force: true });
|
|
12
|
-
await mkdir(dist, { recursive: true });
|
|
13
|
-
|
|
14
|
-
// Build ESM library output (index.js)
|
|
15
|
-
await build({
|
|
16
|
-
entryPoints: [resolve(src, 'index.ts')],
|
|
17
|
-
outdir: dist,
|
|
18
|
-
format: 'esm',
|
|
19
|
-
platform: 'node',
|
|
20
|
-
target: ['node18'],
|
|
21
|
-
bundle: true,
|
|
22
|
-
sourcemap: true,
|
|
23
|
-
external: [
|
|
24
|
-
'fs',
|
|
25
|
-
'path',
|
|
26
|
-
'os',
|
|
27
|
-
'crypto',
|
|
28
|
-
'stream',
|
|
29
|
-
'util',
|
|
30
|
-
'events',
|
|
31
|
-
'assert',
|
|
32
|
-
'buffer',
|
|
33
|
-
'querystring',
|
|
34
|
-
'url',
|
|
35
|
-
'http',
|
|
36
|
-
'https',
|
|
37
|
-
'zlib',
|
|
38
|
-
'child_process',
|
|
39
|
-
'cluster',
|
|
40
|
-
'dgram',
|
|
41
|
-
'dns',
|
|
42
|
-
'domain',
|
|
43
|
-
'http2',
|
|
44
|
-
'net',
|
|
45
|
-
'perf_hooks',
|
|
46
|
-
'process',
|
|
47
|
-
'punycode',
|
|
48
|
-
'readline',
|
|
49
|
-
'repl',
|
|
50
|
-
'string_decoder',
|
|
51
|
-
'tls',
|
|
52
|
-
'tty',
|
|
53
|
-
'v8',
|
|
54
|
-
'vm',
|
|
55
|
-
'worker_threads',
|
|
56
|
-
// Keep Istanbul libs external to avoid bundling CJS that requires('fs')
|
|
57
|
-
// which breaks in ESM bundles on Node 20+ with dynamic require shim
|
|
58
|
-
'istanbul-lib-coverage',
|
|
59
|
-
'istanbul-lib-report',
|
|
60
|
-
'istanbul-reports',
|
|
61
|
-
],
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// Build CJS CLI output (cli.cjs) to support CJS-only deps and dynamic require
|
|
65
|
-
await build({
|
|
66
|
-
entryPoints: [resolve(src, 'cli.ts')],
|
|
67
|
-
outfile: resolve(dist, 'cli.cjs'),
|
|
68
|
-
format: 'cjs',
|
|
69
|
-
platform: 'node',
|
|
70
|
-
target: ['node18'],
|
|
71
|
-
bundle: true,
|
|
72
|
-
sourcemap: true,
|
|
73
|
-
external: [
|
|
74
|
-
// keep Node core externals trivial
|
|
75
|
-
'fs',
|
|
76
|
-
'path',
|
|
77
|
-
'os',
|
|
78
|
-
'crypto',
|
|
79
|
-
'stream',
|
|
80
|
-
'util',
|
|
81
|
-
'events',
|
|
82
|
-
'assert',
|
|
83
|
-
'buffer',
|
|
84
|
-
'querystring',
|
|
85
|
-
'url',
|
|
86
|
-
'http',
|
|
87
|
-
'https',
|
|
88
|
-
'zlib',
|
|
89
|
-
'child_process',
|
|
90
|
-
'cluster',
|
|
91
|
-
'dgram',
|
|
92
|
-
'dns',
|
|
93
|
-
'domain',
|
|
94
|
-
'http2',
|
|
95
|
-
'net',
|
|
96
|
-
'perf_hooks',
|
|
97
|
-
'process',
|
|
98
|
-
'punycode',
|
|
99
|
-
'readline',
|
|
100
|
-
'repl',
|
|
101
|
-
'string_decoder',
|
|
102
|
-
'tls',
|
|
103
|
-
'tty',
|
|
104
|
-
'v8',
|
|
105
|
-
'vm',
|
|
106
|
-
'worker_threads',
|
|
107
|
-
// Externalize Istanbul + picomatch so their internal dynamic requires resolve correctly
|
|
108
|
-
'istanbul-lib-coverage',
|
|
109
|
-
'istanbul-lib-report',
|
|
110
|
-
'istanbul-reports',
|
|
111
|
-
'picomatch',
|
|
112
|
-
],
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// Create a Node shebang for the CLI
|
|
116
|
-
const cliPath = resolve(dist, 'cli.cjs');
|
|
117
|
-
const cliContent = await (await import('node:fs/promises')).readFile(cliPath, 'utf8');
|
|
118
|
-
await writeFile(cliPath, `#!/usr/bin/env node\n${cliContent}`);
|
|
119
|
-
await chmod(cliPath, 0o755);
|
|
120
|
-
|
|
121
|
-
// Copy Jest runtime assets (reporter/setup) to dist so Jest can require them by absolute path
|
|
122
|
-
await mkdir(resolve(dist, 'jest'), { recursive: true });
|
|
123
|
-
await cp(resolve(src, 'jest'), resolve(dist, 'jest'), { recursive: true });
|
package/scripts/postinstall.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { chmod } from 'node:fs/promises';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
|
|
4
|
-
const EXECUTABLE_MODE = 0o755;
|
|
5
|
-
|
|
6
|
-
(async () => {
|
|
7
|
-
try {
|
|
8
|
-
const cli = resolve(new URL('.', import.meta.url).pathname, '..', 'dist', 'cli.cjs');
|
|
9
|
-
await chmod(cli, EXECUTABLE_MODE);
|
|
10
|
-
} catch {
|
|
11
|
-
// ignore (best-effort)
|
|
12
|
-
}
|
|
13
|
-
})();
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { resolve, dirname } from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
|
|
5
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
const rootDir = resolve(__dirname, '..');
|
|
7
|
-
|
|
8
|
-
const pkgJsonPath = resolve(rootDir, 'package.json');
|
|
9
|
-
const pkgRaw = await readFile(pkgJsonPath, 'utf8');
|
|
10
|
-
const pkg = JSON.parse(pkgRaw);
|
|
11
|
-
|
|
12
|
-
const date = new Date();
|
|
13
|
-
// Detect the user's/system timezone; fall back to TZ env or UTC if unavailable
|
|
14
|
-
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone ?? process.env.TZ ?? 'UTC';
|
|
15
|
-
// Friendly: "5:58 PM" (narrow no-break space before AM/PM to prevent wrapping)
|
|
16
|
-
const ts = new Intl.DateTimeFormat('en-US', {
|
|
17
|
-
hour: 'numeric',
|
|
18
|
-
minute: '2-digit',
|
|
19
|
-
hour12: true,
|
|
20
|
-
timeZone: tz,
|
|
21
|
-
// If you want "CDT"/"CST", uncomment:
|
|
22
|
-
// timeZoneName: 'short',
|
|
23
|
-
})
|
|
24
|
-
.format(date)
|
|
25
|
-
.replace(' AM', '\u202FAM')
|
|
26
|
-
.replace(' PM', '\u202FPM');
|
|
27
|
-
|
|
28
|
-
// eslint-disable-next-line no-console
|
|
29
|
-
console.log(`[${ts}] ${pkg.name}@${pkg.version} published in store.`);
|