supercov 0.0.44 → 0.0.45

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.
Files changed (37) hide show
  1. package/README.md +21 -12
  2. package/docs/agent-loop.md +12 -8
  3. package/docs/assertion-agent.md +156 -0
  4. package/docs/assertion-evidence.md +9 -694
  5. package/docs/assertion-maps.md +252 -0
  6. package/docs/assertions.md +82 -0
  7. package/docs/cli.md +23 -8
  8. package/docs/coverage-model.md +12 -0
  9. package/package.json +34 -35
  10. package/runtime/javascript/runtime.mjs +18 -33
  11. package/schemas/assertions.schema.json +276 -0
  12. package/analyzers/typescript/README.md +0 -59
  13. package/analyzers/typescript/bin/compiler-identity.mjs +0 -78
  14. package/analyzers/typescript/bin/identity.mjs +0 -71
  15. package/analyzers/typescript/bin/query.mjs +0 -29
  16. package/analyzers/typescript/dist/analyze.js +0 -5273
  17. package/analyzers/typescript/dist/archive.js +0 -337
  18. package/analyzers/typescript/dist/awaited-observations.js +0 -376
  19. package/analyzers/typescript/dist/build-identity.json +0 -1
  20. package/analyzers/typescript/dist/compiler.js +0 -32
  21. package/analyzers/typescript/dist/frontend.js +0 -75
  22. package/analyzers/typescript/dist/mock-counts.js +0 -2517
  23. package/analyzers/typescript/dist/native-frontend.js +0 -271
  24. package/analyzers/typescript/dist/pragmas.js +0 -186
  25. package/analyzers/typescript/dist/types.js +0 -1
  26. package/analyzers/typescript/package.json +0 -27
  27. package/analyzers/typescript/src/analyze.ts +0 -6180
  28. package/analyzers/typescript/src/archive.ts +0 -471
  29. package/analyzers/typescript/src/awaited-observations.ts +0 -561
  30. package/analyzers/typescript/src/compiler.ts +0 -49
  31. package/analyzers/typescript/src/frontend.ts +0 -136
  32. package/analyzers/typescript/src/mock-counts.ts +0 -3219
  33. package/analyzers/typescript/src/native-frontend.ts +0 -315
  34. package/analyzers/typescript/src/pragmas.ts +0 -284
  35. package/analyzers/typescript/src/types.ts +0 -45
  36. package/analyzers/typescript/tsconfig.json +0 -12
  37. package/docs/code-verification.md +0 -4
@@ -144,9 +144,6 @@ function createState() {
144
144
  decisions: /* @__PURE__ */ new Map(),
145
145
  hits: /* @__PURE__ */ new Set(),
146
146
  events: [],
147
- // Position of the test-file statement currently executing ("file:line:column"), set by the
148
- // instrumented test module; production hits recorded meanwhile are attributed to it.
149
- testStatement: void 0,
150
147
  // Per value-position logical expression (`a && b`, `a || b`, `a ?? b`): the distinct
151
148
  // (right operand evaluated?, result truthy?) pairs seen, keyed by branch id.
152
149
  logicals: /* @__PURE__ */ new Map(),
@@ -317,7 +314,6 @@ function resetCoverage(testId2) {
317
314
  state.decisions.clear();
318
315
  state.hits.clear();
319
316
  state.events.length = 0;
320
- state.testStatement = void 0;
321
317
  state.logicals.clear();
322
318
  state.eventKeys.clear();
323
319
  state.probeV2ContextEpochs.clear();
@@ -758,8 +754,8 @@ function withNodeAssertionPhase(operation, source, callback) {
758
754
  const existing = context.phaseId && assertionPhaseState(scope).phaseIds.has(context.phaseId);
759
755
  if (existing)
760
756
  return callback();
761
- // The adapter's stack is only a fallback. Avoid formatting it when a lexical
762
- // probe already supplied the active phase's exact original-source identity.
757
+ // A lexical occurrence already identifies its source. Stack fallback is lazy
758
+ // and qualified so transformed coordinates cannot impersonate original ones.
763
759
  if (typeof source === "function")
764
760
  source = source();
765
761
  const bridged = (_a8 = runtimeGlobal.__SUPERCOV_ASSERTION_PHASE_BRIDGE__) == null ? void 0 : _a8.call(runtimeGlobal, operation, source, callback);
@@ -792,15 +788,12 @@ function withNodeAssertionPhase(operation, source, callback) {
792
788
  throw cleanInstrumentationStack(error);
793
789
  }
794
790
  }
795
- // Resolve the target exactly once, before argument evaluation, just like a
796
- // native call reference. The closure carries only source identity and receiver;
797
- // it never captures an assertion phase or mutable current-statement state across
798
- // await. Rejected arguments therefore create no phase, and awaited producer work
799
- // is not retroactively attributed to the assertion invocation.
800
- function bindNodeAssertion(operation, source, receiver, method) {
801
- const target = method === void 0 ? receiver : receiver[method];
802
- const thisArgument = method === void 0 ? void 0 : receiver;
803
- return (...args) => withNodeAssertionPhase(operation, source, () => Reflect.apply(target, thisArgument, args));
791
+ // Callee binding preserves receiver, getter/evaluation order, spreads and the
792
+ // original await/yield placement. Only the matcher call opens the phase.
793
+ function bindNodeAssertionPhase(operation, source, target, property = null) {
794
+ const callback = property === null ? target : target[property];
795
+ const receiver = property === null ? undefined : target;
796
+ return (...args) => withNodeAssertionPhase(operation, source, () => Reflect.apply(callback, receiver, args));
804
797
  }
805
798
  function takeNodeAssertionPhases(scope) {
806
799
  var _a8, _b;
@@ -995,31 +988,25 @@ function recordBrowserEvent(event) {
995
988
  state.events.push(event);
996
989
  return true;
997
990
  }
998
- function testStatement(source) {
999
- state.testStatement = typeof source === "string" && source.length > 0 ? source : void 0;
1000
- }
1001
- function statementFields() {
1002
- return state.testStatement ? { statementId: state.testStatement } : {};
1003
- }
1004
991
  function coverageHit(id) {
1005
992
  state.hits.add(id);
1006
993
  const timestampMs = Date.now();
1007
994
  const phaseId = currentPhaseId();
1008
995
  if (isBrowser) {
1009
- if (recordBrowserEvent(__spreadProps(__spreadValues(__spreadValues({
996
+ if (recordBrowserEvent(__spreadProps(__spreadValues({
1010
997
  type: "hit",
1011
998
  id,
1012
999
  timestampMs
1013
- }, phaseId ? { phaseId } : {}), statementFields()), {
1000
+ }, phaseId ? { phaseId } : {}), {
1014
1001
  environment: "browser"
1015
1002
  })))
1016
1003
  persistBrowser();
1017
1004
  } else {
1018
- appendServer(__spreadValues(__spreadValues({
1005
+ appendServer(__spreadValues({
1019
1006
  type: "hit",
1020
1007
  id,
1021
1008
  timestampMs
1022
- }, phaseId ? { phaseId } : {}), statementFields()));
1009
+ }, phaseId ? { phaseId } : {}));
1023
1010
  }
1024
1011
  }
1025
1012
  function registerProbeV2(definition) {
@@ -1254,22 +1241,22 @@ function mcdcEnd(frame, value) {
1254
1241
  const timestampMs = Date.now();
1255
1242
  const phaseId = currentPhaseId();
1256
1243
  if (isBrowser) {
1257
- if (recordBrowserEvent(__spreadProps(__spreadValues(__spreadValues({
1244
+ if (recordBrowserEvent(__spreadProps(__spreadValues({
1258
1245
  type: "decision",
1259
1246
  id: decision.meta.id,
1260
1247
  vector,
1261
1248
  timestampMs
1262
- }, phaseId ? { phaseId } : {}), statementFields()), {
1249
+ }, phaseId ? { phaseId } : {}), {
1263
1250
  environment: "browser"
1264
1251
  })))
1265
1252
  persistBrowser();
1266
1253
  } else {
1267
- appendServer(__spreadValues(__spreadValues({
1254
+ appendServer(__spreadValues({
1268
1255
  type: "decision",
1269
1256
  meta: decision.meta,
1270
1257
  vector,
1271
1258
  timestampMs
1272
- }, phaseId ? { phaseId } : {}), statementFields()));
1259
+ }, phaseId ? { phaseId } : {}));
1273
1260
  }
1274
1261
  return value;
1275
1262
  }
@@ -1310,13 +1297,12 @@ const directRuntimeApi = {
1310
1297
  selectionEnd,
1311
1298
  selectionRight,
1312
1299
  takeNodeAssertionPhases,
1313
- bindNodeAssertion,
1314
- testStatement,
1315
1300
  tryBegin,
1316
1301
  tryCatch,
1317
1302
  tryEnd,
1318
1303
  withCoverageCarrier,
1319
1304
  withNodeAssertionPhase,
1305
+ bindNodeAssertionPhase,
1320
1306
  withRequestPhase,
1321
1307
  writeExclusiveBackgroundRecord
1322
1308
  };
@@ -1361,13 +1347,12 @@ export {
1361
1347
  selectionEnd,
1362
1348
  selectionRight,
1363
1349
  takeNodeAssertionPhases,
1364
- bindNodeAssertion,
1365
- testStatement,
1366
1350
  tryBegin,
1367
1351
  tryCatch,
1368
1352
  tryEnd,
1369
1353
  withCoverageCarrier,
1370
1354
  withNodeAssertionPhase,
1355
+ bindNodeAssertionPhase,
1371
1356
  withRequestPhase,
1372
1357
  writeExclusiveBackgroundRecord
1373
1358
  };
@@ -0,0 +1,276 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "AssertionMap",
4
+ "type": "object",
5
+ "properties": {
6
+ "schemaVersion": {
7
+ "type": "integer",
8
+ "format": "uint32",
9
+ "minimum": 2,
10
+ "maximum": 2
11
+ },
12
+ "assertions": {
13
+ "type": "array",
14
+ "items": {
15
+ "$ref": "#/$defs/Assertion"
16
+ }
17
+ },
18
+ "changeAssessments": {
19
+ "type": "array",
20
+ "items": {
21
+ "$ref": "#/$defs/ChangeAssessment"
22
+ }
23
+ },
24
+ "retiredAssertions": {
25
+ "type": "array",
26
+ "items": {
27
+ "$ref": "#/$defs/Retired"
28
+ }
29
+ }
30
+ },
31
+ "additionalProperties": false,
32
+ "required": [
33
+ "schemaVersion",
34
+ "assertions"
35
+ ],
36
+ "$defs": {
37
+ "Assertion": {
38
+ "type": "object",
39
+ "properties": {
40
+ "id": {
41
+ "type": "string"
42
+ },
43
+ "at": {
44
+ "$ref": "#/$defs/Anchor"
45
+ },
46
+ "questions": {
47
+ "type": "array",
48
+ "items": {
49
+ "type": "string"
50
+ }
51
+ },
52
+ "observes": {
53
+ "type": "array",
54
+ "items": {
55
+ "type": "string"
56
+ },
57
+ "default": []
58
+ },
59
+ "flows": {
60
+ "type": "array",
61
+ "items": {
62
+ "$ref": "#/$defs/Flow"
63
+ },
64
+ "default": []
65
+ }
66
+ },
67
+ "additionalProperties": false,
68
+ "required": [
69
+ "id",
70
+ "at"
71
+ ]
72
+ },
73
+ "Anchor": {
74
+ "description": "One-based lines and UTF-8 byte columns, for every language. Text is exact.",
75
+ "type": "object",
76
+ "properties": {
77
+ "file": {
78
+ "type": "string"
79
+ },
80
+ "line": {
81
+ "type": "integer",
82
+ "format": "uint",
83
+ "minimum": 0
84
+ },
85
+ "column": {
86
+ "type": "integer",
87
+ "format": "uint",
88
+ "minimum": 0
89
+ },
90
+ "text": {
91
+ "type": "string"
92
+ }
93
+ },
94
+ "additionalProperties": false,
95
+ "required": [
96
+ "file",
97
+ "line",
98
+ "column",
99
+ "text"
100
+ ]
101
+ },
102
+ "Flow": {
103
+ "type": "object",
104
+ "properties": {
105
+ "id": {
106
+ "type": "string"
107
+ },
108
+ "basis": {
109
+ "type": [
110
+ "string",
111
+ "null"
112
+ ],
113
+ "pattern": "^scov2:[0-9a-f]{64}$"
114
+ },
115
+ "explanation": {
116
+ "type": "string"
117
+ },
118
+ "appliesTo": {
119
+ "type": "array",
120
+ "items": {
121
+ "$ref": "#/$defs/TestSelector"
122
+ }
123
+ },
124
+ "nodes": {
125
+ "type": "array",
126
+ "items": {
127
+ "$ref": "#/$defs/Node"
128
+ }
129
+ },
130
+ "edges": {
131
+ "type": "array",
132
+ "items": {
133
+ "$ref": "#/$defs/Edge"
134
+ },
135
+ "default": []
136
+ },
137
+ "countsAsAsserted": {
138
+ "type": "array",
139
+ "items": {
140
+ "type": "string"
141
+ }
142
+ },
143
+ "watch": {
144
+ "type": "array",
145
+ "items": {
146
+ "type": "string"
147
+ }
148
+ },
149
+ "questions": {
150
+ "type": "array",
151
+ "items": {
152
+ "type": "string"
153
+ }
154
+ }
155
+ },
156
+ "additionalProperties": false,
157
+ "required": [
158
+ "id",
159
+ "basis",
160
+ "explanation",
161
+ "appliesTo",
162
+ "nodes",
163
+ "countsAsAsserted",
164
+ "watch"
165
+ ]
166
+ },
167
+ "TestSelector": {
168
+ "type": "object",
169
+ "properties": {
170
+ "file": {
171
+ "type": "string"
172
+ },
173
+ "name": {
174
+ "type": "string"
175
+ }
176
+ },
177
+ "additionalProperties": false,
178
+ "required": [
179
+ "file",
180
+ "name"
181
+ ]
182
+ },
183
+ "Node": {
184
+ "type": "object",
185
+ "properties": {
186
+ "id": {
187
+ "type": "string"
188
+ },
189
+ "at": {
190
+ "$ref": "#/$defs/Anchor"
191
+ },
192
+ "role": {
193
+ "type": "string"
194
+ },
195
+ "meaning": {
196
+ "type": "string"
197
+ }
198
+ },
199
+ "additionalProperties": false,
200
+ "required": [
201
+ "id",
202
+ "at"
203
+ ]
204
+ },
205
+ "Edge": {
206
+ "type": "object",
207
+ "properties": {
208
+ "from": {
209
+ "type": "string"
210
+ },
211
+ "to": {
212
+ "type": "string"
213
+ },
214
+ "kind": {
215
+ "type": "string"
216
+ },
217
+ "basis": {
218
+ "type": "string"
219
+ }
220
+ },
221
+ "additionalProperties": false,
222
+ "required": [
223
+ "from",
224
+ "to",
225
+ "kind"
226
+ ]
227
+ },
228
+ "ChangeAssessment": {
229
+ "type": "object",
230
+ "properties": {
231
+ "id": {
232
+ "type": "string"
233
+ },
234
+ "basis": {
235
+ "type": [
236
+ "string",
237
+ "null"
238
+ ],
239
+ "pattern": "^scov2:[0-9a-f]{64}$"
240
+ },
241
+ "affectedFlows": {
242
+ "type": "array",
243
+ "items": {
244
+ "type": "string"
245
+ }
246
+ },
247
+ "explanation": {
248
+ "type": "string"
249
+ }
250
+ },
251
+ "additionalProperties": false,
252
+ "required": [
253
+ "id",
254
+ "basis",
255
+ "affectedFlows",
256
+ "explanation"
257
+ ]
258
+ },
259
+ "Retired": {
260
+ "type": "object",
261
+ "properties": {
262
+ "assertion": {
263
+ "$ref": "#/$defs/Assertion"
264
+ },
265
+ "reason": {
266
+ "type": "string"
267
+ }
268
+ },
269
+ "additionalProperties": false,
270
+ "required": [
271
+ "assertion",
272
+ "reason"
273
+ ]
274
+ }
275
+ }
276
+ }
@@ -1,59 +0,0 @@
1
- # JS/TS assertion analyzer (internal)
2
-
3
- This private package is the post-run analysis component used by Supercov's
4
- `runs <run> assertions` command. It is bundled in the npm distribution, not
5
- published as a separate CLI or SDK.
6
-
7
- See [Assertion evidence](../../docs/assertion-evidence.md) for public commands,
8
- pragma syntax, report interpretation and supported scope.
9
-
10
- ## Product boundary
11
-
12
- - `bin/query.mjs` is the CLI-to-analyzer JSON transport. It accepts an ordinary
13
- archive representation prepared by Rust, validates identities and returns facts.
14
- - `bin/identity.mjs` checks the analyzer source/build identity; its direct
15
- invocation writes that identity during the build.
16
- - `bin/compiler-identity.mjs` fingerprints the project's compiler implementation.
17
- - `src/archive.ts` validates the archive protocol, source positions and attempt
18
- ownership, then constructs query-local evidence in memory.
19
- - `src/analyze.ts` extracts source-flow facts and exact assertion witnesses.
20
- The Rust engine joins those facts into candidate classifications.
21
- - `src/mock-counts.ts` models bounded synchronous console-mock count histories,
22
- keeping count evidence separate from general value-protection claims.
23
- - `src/awaited-observations.ts` recognizes bounded native child-capture/poll
24
- source patterns for hint attachment, without manufacturing runtime witnesses.
25
- - `src/frontend.ts` and `src/native-frontend.ts` implement the legacy and native
26
- TypeScript compiler boundaries. `src/pragmas.ts` validates optional hints.
27
-
28
- There is no converted-input command, on-disk research input, V8 remapping,
29
- mutation runner or diagnostic-ablation option in the product interface.
30
- Source files ship to support build-identity verification; tests and research
31
- tools do not ship. Assertion candidates remain unverified, not safety proofs.
32
- Only executable JavaScript and its build identity ship from `dist`; there is no
33
- public SDK declaration surface or generated source-map payload.
34
-
35
- ## Build and test
36
-
37
- From this directory:
38
-
39
- ```sh
40
- npm ci --ignore-scripts
41
- npm test
42
- ```
43
-
44
- The build uses pinned TypeScript 5.8.3 explicitly. Project analysis uses the
45
- project's compiler; native 7.0.2 has a separate frontend and identity checks.
46
- Native compiler processes close after both successful and failed queries.
47
-
48
- From the repository root, exercise real Node/Vitest archives and the installed
49
- npm package:
50
-
51
- ```sh
52
- npm run test:asserted-integration
53
- npm run test:asserted-package
54
- ```
55
-
56
- Controlled unit fixtures test parser, flow and witness rules. The ordinary-archive
57
- integration tests execute real suites and explicit behavioral counterexamples.
58
- Compiler-path and identity regressions run across supported CI platforms.
59
- Historical external-cohort research is not part of the default suite or product.
@@ -1,78 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { readFileSync, readdirSync } from "node:fs";
3
- import { dirname, resolve } from "node:path";
4
- import { createRequire } from "node:module";
5
- import { pathToFileURL } from "node:url";
6
- import { projectCompilerPath } from "../dist/compiler.js";
7
-
8
- /** Hash the native implementation as well as its JS client; version.cjs alone is not the compiler. */
9
- export function compilerIdentity(projectRoot) {
10
- return compilerIdentityFromEntry(projectCompilerPath(projectRoot));
11
- }
12
-
13
- export function compilerIdentityFromEntry(entry) {
14
- const require = createRequire(pathToFileURL(entry));
15
- const { version } = require(entry);
16
- const entrySha256 = createHash("sha256")
17
- .update(readFileSync(entry))
18
- .digest("hex");
19
- if (version !== "7.0.2")
20
- return { backend: "typescript-legacy", version, sha256: entrySha256 };
21
- const packageRoot = dirname(require.resolve("typescript/package.json"));
22
- const platform = `@typescript/typescript-${process.platform}-${process.arch}`;
23
- let nativeRoot;
24
- try {
25
- nativeRoot = dirname(require.resolve(`${platform}/package.json`));
26
- } catch (cause) {
27
- throw new Error(
28
- `TypeScript 7's native compiler dependency ${platform} is missing. Install the project's optional TypeScript dependencies before recapturing tests.`,
29
- { cause },
30
- );
31
- }
32
- const nativeMetadata = JSON.parse(
33
- readFileSync(resolve(nativeRoot, "package.json"), "utf8"),
34
- );
35
- if (nativeMetadata.name !== platform || nativeMetadata.version !== version)
36
- throw new Error(
37
- `TypeScript native package identity mismatch: expected ${platform}@${version}`,
38
- );
39
- const executable = resolve(
40
- nativeRoot,
41
- "lib",
42
- process.platform === "win32" ? "tsc.exe" : "tsc",
43
- );
44
- const nativeSha256 = createHash("sha256")
45
- .update(readFileSync(executable))
46
- .digest("hex");
47
- const hash = createHash("sha256");
48
- let files = 0;
49
- function walk(root, relative = "") {
50
- for (const file of readdirSync(resolve(root, relative), {
51
- withFileTypes: true,
52
- }).sort((a, b) => a.name.localeCompare(b.name))) {
53
- if (file.name === "node_modules") continue;
54
- const path = relative ? `${relative}/${file.name}` : file.name;
55
- if (file.isDirectory()) walk(root, path);
56
- else if (file.isFile()) {
57
- hash
58
- .update(path)
59
- .update("\0")
60
- .update(readFileSync(resolve(root, path)))
61
- .update("\0");
62
- files++;
63
- } else throw new Error(`Unsupported compiler package entry: ${path}`);
64
- }
65
- }
66
- hash.update("typescript-package\0");
67
- walk(packageRoot);
68
- hash.update("native-package\0");
69
- walk(nativeRoot);
70
- return {
71
- backend: "typescript-native-7",
72
- version,
73
- sha256: hash.digest("hex"),
74
- nativePackage: platform,
75
- nativeSha256,
76
- files,
77
- };
78
- }
@@ -1,71 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { readFileSync, writeFileSync } from "node:fs";
3
- import { resolve } from "node:path";
4
- import { fileURLToPath } from "node:url";
5
-
6
- const root = resolve(import.meta.dirname, "..");
7
- const sources = [
8
- "src/analyze.ts",
9
- "src/archive.ts",
10
- "src/awaited-observations.ts",
11
- "src/compiler.ts",
12
- "src/frontend.ts",
13
- "src/native-frontend.ts",
14
- "src/types.ts",
15
- "src/pragmas.ts",
16
- "src/mock-counts.ts",
17
- "bin/query.mjs",
18
- "bin/compiler-identity.mjs",
19
- "bin/identity.mjs",
20
- "tsconfig.json",
21
- // npm excludes package-lock.json from tarballs. Hash shipped build inputs,
22
- // not a checkout-only file, so installed and development checks are identical.
23
- "package.json",
24
- ];
25
- const outputs = [
26
- "dist/analyze.js",
27
- "dist/archive.js",
28
- "dist/awaited-observations.js",
29
- "dist/compiler.js",
30
- "dist/frontend.js",
31
- "dist/native-frontend.js",
32
- "dist/types.js",
33
- "dist/pragmas.js",
34
- "dist/mock-counts.js",
35
- ];
36
- function digest(files) {
37
- const hash = createHash("sha256");
38
- for (const file of files)
39
- hash
40
- .update(file)
41
- .update("\0")
42
- .update(readFileSync(resolve(root, file)))
43
- .update("\0");
44
- return hash.digest("hex");
45
- }
46
- export function identity() {
47
- return {
48
- schema: 1,
49
- sourceSha256: digest(sources),
50
- compiledSha256: digest(outputs),
51
- };
52
- }
53
- export function checkedIdentity() {
54
- const built = JSON.parse(
55
- readFileSync(resolve(root, "dist/build-identity.json"), "utf8"),
56
- );
57
- const current = identity();
58
- if (JSON.stringify(built) !== JSON.stringify(current))
59
- throw new Error(
60
- "Assertion analyzer build is stale or modified; rebuild analyzers/typescript",
61
- );
62
- return current;
63
- }
64
- if (
65
- process.argv[1] &&
66
- resolve(process.argv[1]) === fileURLToPath(import.meta.url)
67
- )
68
- writeFileSync(
69
- resolve(root, "dist/build-identity.json"),
70
- JSON.stringify(identity()) + "\n",
71
- );
@@ -1,29 +0,0 @@
1
- // First-party query transport, never executed by the test runner.
2
- import { readFileSync } from "node:fs";
3
- import { checkedIdentity } from "./identity.mjs";
4
-
5
- try {
6
- const analyzer = checkedIdentity();
7
- const input = JSON.parse(readFileSync(0, "utf8"));
8
- // Check the build before importing executable analyzer code.
9
- const { compilerIdentity } = await import("./compiler-identity.mjs");
10
- const { analyzeArchive } = await import("../dist/archive.js");
11
- const compiler = compilerIdentity(input.projectRoot);
12
- const compilerSha256 = compiler.sha256;
13
- const result = analyzeArchive(input);
14
- if (
15
- JSON.stringify(compilerIdentity(input.projectRoot)) !==
16
- JSON.stringify(compiler) ||
17
- JSON.stringify(checkedIdentity()) !== JSON.stringify(analyzer)
18
- )
19
- throw new Error("Analyzer or compiler changed during analysis");
20
- process.stdout.write(
21
- JSON.stringify({
22
- ...result,
23
- analyzer: { ...analyzer, compilerSha256, compiler },
24
- }),
25
- );
26
- } catch (error) {
27
- console.error(error instanceof Error ? error.message : String(error));
28
- process.exitCode = 1;
29
- }