ts-semver-checks-core 0.2.0 → 0.3.0

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,9 @@
1
+ import ts from "typescript";
2
+ import type { Finding } from "./findings.js";
3
+ /**
4
+ * Refine structural findings using assignability. Returns a new list; findings
5
+ * that turn out to be false positives are omitted. If the combined program can't
6
+ * be built, the input findings are returned unchanged.
7
+ */
8
+ export declare function refineFindings(findings: readonly Finding[], oldEntry: string, newEntry: string, compilerOptions?: ts.CompilerOptions): Finding[];
9
+ //# sourceMappingURL=assignability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignability.d.ts","sourceRoot":"","sources":["../src/assignability.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AA8C7C;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,EAAE,CAAC,eAAe,GACnC,OAAO,EAAE,CAUX"}
@@ -0,0 +1,144 @@
1
+ import * as path from "node:path";
2
+ import ts from "typescript";
3
+ const DEFAULT_COMPILER_OPTIONS = {
4
+ target: ts.ScriptTarget.ES2022,
5
+ module: ts.ModuleKind.NodeNext,
6
+ moduleResolution: ts.ModuleResolutionKind.NodeNext,
7
+ strict: true,
8
+ skipLibCheck: true,
9
+ noEmit: true,
10
+ };
11
+ const PARAM_PATH = /^(.+)\.params\[(\d+)\]$/;
12
+ const RETURN_PATH = /^(.+)\.returnType$/;
13
+ /**
14
+ * Refine structural findings using assignability. Returns a new list; findings
15
+ * that turn out to be false positives are omitted. If the combined program can't
16
+ * be built, the input findings are returned unchanged.
17
+ */
18
+ export function refineFindings(findings, oldEntry, newEntry, compilerOptions) {
19
+ const cmp = buildComparison(oldEntry, newEntry, compilerOptions);
20
+ if (!cmp)
21
+ return [...findings];
22
+ const out = [];
23
+ for (const finding of findings) {
24
+ const refined = refineOne(finding, cmp);
25
+ if (refined)
26
+ out.push(refined);
27
+ }
28
+ return out;
29
+ }
30
+ function buildComparison(oldEntry, newEntry, compilerOptions) {
31
+ const oldPath = path.resolve(oldEntry);
32
+ const newPath = path.resolve(newEntry);
33
+ if (oldPath === newPath)
34
+ return undefined;
35
+ let program;
36
+ try {
37
+ program = ts.createProgram({
38
+ rootNames: [oldPath, newPath],
39
+ options: { ...DEFAULT_COMPILER_OPTIONS, ...compilerOptions },
40
+ });
41
+ }
42
+ catch {
43
+ return undefined;
44
+ }
45
+ const checker = program.getTypeChecker();
46
+ const oldFns = collectFunctions(program, checker, oldPath);
47
+ const newFns = collectFunctions(program, checker, newPath);
48
+ if (!oldFns || !newFns)
49
+ return undefined;
50
+ return { checker, oldFns, newFns };
51
+ }
52
+ function collectFunctions(program, checker, entry) {
53
+ const sourceFile = program.getSourceFile(entry);
54
+ if (!sourceFile)
55
+ return undefined;
56
+ const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
57
+ if (!moduleSymbol)
58
+ return new Map();
59
+ const result = new Map();
60
+ const add = (name, symbol) => {
61
+ const resolved = symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
62
+ if ((resolved.getFlags() & ts.SymbolFlags.Function) === 0)
63
+ return;
64
+ const decl = resolved.getDeclarations()?.[0] ?? resolved.valueDeclaration;
65
+ if (!decl)
66
+ return;
67
+ const type = checker.getTypeOfSymbolAtLocation(resolved, decl);
68
+ const signatures = type.getCallSignatures();
69
+ // Only single-signature functions are refined; overloads are left as-is.
70
+ if (signatures.length !== 1)
71
+ return;
72
+ const sig = signatures[0];
73
+ const params = sig.getParameters().map((p) => {
74
+ const pd = p.valueDeclaration ?? p.declarations?.[0];
75
+ return pd ? checker.getTypeOfSymbolAtLocation(p, pd) : checker.getTypeOfSymbol(p);
76
+ });
77
+ result.set(name, { params, ret: sig.getReturnType() });
78
+ };
79
+ for (const exp of checker.getExportsOfModule(moduleSymbol)) {
80
+ add(exp_name(exp), exp);
81
+ }
82
+ const exportEquals = moduleSymbol.exports?.get("export=");
83
+ if (exportEquals)
84
+ add("export=", exportEquals);
85
+ return result;
86
+ }
87
+ function exp_name(symbol) {
88
+ return symbol.getName();
89
+ }
90
+ function refineOne(finding, cmp) {
91
+ if (finding.code === "param.typeChanged") {
92
+ const m = PARAM_PATH.exec(finding.path);
93
+ if (!m)
94
+ return finding;
95
+ const fnName = m[1];
96
+ const index = Number(m[2]);
97
+ const oldT = cmp.oldFns.get(fnName)?.params[index];
98
+ const newT = cmp.newFns.get(fnName)?.params[index];
99
+ if (!oldT || !newT)
100
+ return finding;
101
+ const oldToNew = cmp.checker.isTypeAssignableTo(oldT, newT);
102
+ const newToOld = cmp.checker.isTypeAssignableTo(newT, oldT);
103
+ if (oldToNew && newToOld)
104
+ return null; // equivalent types → false positive
105
+ if (oldToNew) {
106
+ // New parameter accepts everything the old one did → widening → safe.
107
+ return {
108
+ ...finding,
109
+ level: "minor",
110
+ code: "param.typeWidened",
111
+ message: finding.message.replace("type changed", "type widened") +
112
+ " (still accepts all previous inputs).",
113
+ };
114
+ }
115
+ return finding; // narrowed or incompatible → stays major
116
+ }
117
+ if (finding.code === "returnType.changed") {
118
+ const m = RETURN_PATH.exec(finding.path);
119
+ if (!m)
120
+ return finding;
121
+ const fnName = m[1];
122
+ const oldR = cmp.oldFns.get(fnName)?.ret;
123
+ const newR = cmp.newFns.get(fnName)?.ret;
124
+ if (!oldR || !newR)
125
+ return finding;
126
+ const newToOld = cmp.checker.isTypeAssignableTo(newR, oldR);
127
+ const oldToNew = cmp.checker.isTypeAssignableTo(oldR, newR);
128
+ if (newToOld && oldToNew)
129
+ return null; // equivalent
130
+ if (newToOld) {
131
+ // New return is a subtype of the old one → narrowing → safe for consumers.
132
+ return {
133
+ ...finding,
134
+ level: "minor",
135
+ code: "returnType.narrowed",
136
+ message: finding.message.replace("changed", "narrowed") +
137
+ " (a subtype of the previous return type).",
138
+ };
139
+ }
140
+ return finding; // widened or incompatible → stays major
141
+ }
142
+ return finding;
143
+ }
144
+ //# sourceMappingURL=assignability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignability.js","sourceRoot":"","sources":["../src/assignability.ts"],"names":[],"mappings":"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"}
package/dist/check.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type ts from "typescript";
1
2
  import type { ApiSurface, SemverLevel } from "./model.js";
2
3
  import { type Finding } from "./findings.js";
3
4
  export interface CheckResult {
@@ -7,7 +8,27 @@ export interface CheckResult {
7
8
  findings: Finding[];
8
9
  }
9
10
  /**
10
- * Convenience: diff two surfaces and classify the result in one step.
11
+ * Diff two already-extracted surfaces and classify the result.
12
+ *
13
+ * This is the pure, string-model path — use it when you only have serialized
14
+ * surfaces (e.g. a committed API lockfile). For the most accurate result when
15
+ * both source entry points are available, prefer {@link checkEntries}, which
16
+ * additionally applies assignability-based refinement.
11
17
  */
12
18
  export declare function checkSurfaces(before: ApiSurface, after: ApiSurface): CheckResult;
19
+ export interface CheckEntriesOptions {
20
+ /**
21
+ * Apply assignability-based refinement (distinguish widening from narrowing,
22
+ * drop false-positive type changes). Default: true.
23
+ */
24
+ assignability?: boolean;
25
+ compilerOptions?: ts.CompilerOptions;
26
+ }
27
+ /**
28
+ * Extract, diff, and classify two packages given their entry points. When
29
+ * `assignability` is enabled (default), a combined program is built from both
30
+ * entries so type changes can be classified by variance instead of the
31
+ * conservative string comparison.
32
+ */
33
+ export declare function checkEntries(oldEntry: string, newEntry: string, options?: CheckEntriesOptions): CheckResult;
13
34
  //# sourceMappingURL=check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,KAAK,EAAE,WAAW,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,WAAW,CAGhF"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI1D,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAErE,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,KAAK,EAAE,WAAW,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,WAAW,CAGhF;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,mBAAwB,GAChC,WAAW,CAWb"}
package/dist/check.js CHANGED
@@ -1,10 +1,33 @@
1
+ import { extractSurface } from "./extract.js";
1
2
  import { diffSurfaces } from "./diff.js";
3
+ import { refineFindings } from "./assignability.js";
2
4
  import { classify, sortFindings } from "./findings.js";
3
5
  /**
4
- * Convenience: diff two surfaces and classify the result in one step.
6
+ * Diff two already-extracted surfaces and classify the result.
7
+ *
8
+ * This is the pure, string-model path — use it when you only have serialized
9
+ * surfaces (e.g. a committed API lockfile). For the most accurate result when
10
+ * both source entry points are available, prefer {@link checkEntries}, which
11
+ * additionally applies assignability-based refinement.
5
12
  */
6
13
  export function checkSurfaces(before, after) {
7
14
  const findings = sortFindings(diffSurfaces(before, after));
8
15
  return { level: classify(findings), findings };
9
16
  }
17
+ /**
18
+ * Extract, diff, and classify two packages given their entry points. When
19
+ * `assignability` is enabled (default), a combined program is built from both
20
+ * entries so type changes can be classified by variance instead of the
21
+ * conservative string comparison.
22
+ */
23
+ export function checkEntries(oldEntry, newEntry, options = {}) {
24
+ const before = extractSurface({ entryPoint: oldEntry, compilerOptions: options.compilerOptions });
25
+ const after = extractSurface({ entryPoint: newEntry, compilerOptions: options.compilerOptions });
26
+ let findings = diffSurfaces(before, after);
27
+ if (options.assignability !== false) {
28
+ findings = refineFindings(findings, oldEntry, newEntry, options.compilerOptions);
29
+ }
30
+ findings = sortFindings(findings);
31
+ return { level: classify(findings), findings };
32
+ }
10
33
  //# sourceMappingURL=check.js.map
package/dist/check.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAgB,MAAM,eAAe,CAAC;AASrE;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAkB,EAAE,KAAiB;IACjE,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAC3D,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAgB,MAAM,eAAe,CAAC;AASrE;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAAkB,EAAE,KAAiB;IACjE,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAC3D,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;AACjD,CAAC;AAWD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,QAAgB,EAChB,UAA+B,EAAE;IAEjC,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAClG,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAEjG,IAAI,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,OAAO,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;QACpC,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACnF,CAAC;IAED,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAClC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;AACjD,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,8 +4,9 @@ export type { ExtractOptions } from "./extract.js";
4
4
  export { diffSurfaces } from "./diff.js";
5
5
  export { classify, sortFindings } from "./findings.js";
6
6
  export type { Finding } from "./findings.js";
7
- export { checkSurfaces } from "./check.js";
8
- export type { CheckResult } from "./check.js";
7
+ export { checkSurfaces, checkEntries } from "./check.js";
8
+ export type { CheckResult, CheckEntriesOptions } from "./check.js";
9
+ export { refineFindings } from "./assignability.js";
9
10
  export { renderReport } from "./report.js";
10
11
  export type { RenderOptions } from "./report.js";
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,aAAa,EACb,WAAW,EACX,UAAU,EACV,cAAc,EACd,cAAc,EACd,eAAe,EACf,SAAS,EACT,cAAc,EACd,WAAW,EACX,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,aAAa,EACb,WAAW,EACX,UAAU,EACV,cAAc,EACd,cAAc,EACd,eAAe,EACf,SAAS,EACT,cAAc,EACd,WAAW,EACX,UAAU,EACV,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { extractSurface } from "./extract.js";
2
2
  export { diffSurfaces } from "./diff.js";
3
3
  export { classify, sortFindings } from "./findings.js";
4
- export { checkSurfaces } from "./check.js";
4
+ export { checkSurfaces, checkEntries } from "./check.js";
5
+ export { refineFindings } from "./assignability.js";
5
6
  export { renderReport } from "./report.js";
6
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGvD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-semver-checks-core",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Core library: extract, diff and classify the exported type surface of a TypeScript package.",
5
5
  "keywords": [
6
6
  "semver",