tstyche 1.0.0-rc.1 → 1.0.0-rc.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.0.0-rc.2] - 2024-02-14
4
+
5
+ ### Fixed
6
+
7
+ - Use the `isTypeRelatedTo()` method directly, to make strict subtype checks possible ([#127](https://github.com/tstyche/tstyche/pull/127), [#126](https://github.com/tstyche/tstyche/pull/126))
8
+
3
9
  ## [1.0.0-rc.1] - 2024-02-10
4
10
 
5
11
  ### Changed
@@ -130,6 +136,7 @@
130
136
 
131
137
  _First pre-release._
132
138
 
139
+ [1.0.0-rc.2]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc.2
133
140
  [1.0.0-rc.1]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc.1
134
141
  [1.0.0-rc]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-rc
135
142
  [1.0.0-beta.9]: https://github.com/tstyche/tstyche/releases/tag/v1.0.0-beta.9
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  [![license][license-badge]][license-url]
5
5
  [![packagephobia][packagephobia-badge]][packagephobia-url]
6
6
  [![coverage][coverage-badge]][coverage-url]
7
+ [![discord][discord-badge]][discord-url]
7
8
 
8
9
  The Essential Type Testing Tool.
9
10
 
@@ -75,6 +76,10 @@ This simple!
75
76
 
76
77
  Visit [https://tstyche.org](https://tstyche.org) to view the full documentation.
77
78
 
79
+ ## Feedback
80
+
81
+ If you have any questions or suggestions, [start a discussion](https://github.com/tstyche/tstyche/discussions/new/choose) or [open an issue](https://github.com/tstyche/tstyche/issues/new/choose) on GitHub. Preferring a chat? Join our [Discord server][discord-url].
82
+
78
83
  ## License
79
84
 
80
85
  [MIT][license-url] © TSTyche
@@ -87,3 +92,5 @@ Visit [https://tstyche.org](https://tstyche.org) to view the full documentation.
87
92
  [packagephobia-url]: https://packagephobia.com/result?p=tstyche
88
93
  [coverage-badge]: https://badgen.net/codacy/coverage/a581ca5c323a455886b7bdd9623c4ec8
89
94
  [coverage-url]: https://app.codacy.com/gh/tstyche/tstyche/coverage/dashboard
95
+ [discord-badge]: https://badgen.net/static/chat/on%20Discord
96
+ [discord-url]: https://discord.gg/gCSasd3QJq
@@ -179,7 +179,7 @@ declare class ConfigService {
179
179
  declare class TSTyche {
180
180
  #private;
181
181
  readonly resolvedConfig: ResolvedConfig;
182
- static readonly version = "__version__";
182
+ static readonly version = "1.0.0-rc.2";
183
183
  constructor(resolvedConfig: ResolvedConfig, storeService: StoreService);
184
184
  run(testFiles: Array<string | URL>): Promise<void>;
185
185
  }
@@ -441,10 +441,14 @@ interface MatchResult {
441
441
  explain: () => Array<Diagnostic>;
442
442
  isMatch: boolean;
443
443
  }
444
+ type Relation = Map<string, unknown>;
444
445
  interface TypeChecker extends ts.TypeChecker {
445
- isTypeAssignableTo: (source: ts.Type, target: ts.Type) => boolean;
446
- isTypeIdenticalTo: (source: ts.Type, target: ts.Type) => boolean;
447
- isTypeSubtypeOf: (source: ts.Type, target: ts.Type) => boolean;
446
+ isTypeRelatedTo: (source: ts.Type, target: ts.Type, relation: Relation) => boolean;
447
+ relation: {
448
+ assignable: Relation;
449
+ identity: Relation;
450
+ subtype: Relation;
451
+ };
448
452
  }
449
453
 
450
454
  declare class PrimitiveTypeMatcher {
package/build/tstyche.js CHANGED
@@ -1742,7 +1742,7 @@ class ToBeAssignable {
1742
1742
  : [Diagnostic.error(`Type '${targetTypeText}' is not assignable to type '${sourceTypeText}'.`)];
1743
1743
  }
1744
1744
  match(sourceType, targetType, isNot) {
1745
- const isMatch = this.typeChecker.isTypeAssignableTo(targetType, sourceType);
1745
+ const isMatch = this.typeChecker.isTypeRelatedTo(targetType, sourceType, this.typeChecker.relation.assignable);
1746
1746
  return {
1747
1747
  explain: () => this.#explain(sourceType, targetType, isNot),
1748
1748
  isMatch,
@@ -1763,7 +1763,7 @@ class ToEqual {
1763
1763
  : [Diagnostic.error(`Type '${targetTypeText}' is not identical to type '${sourceTypeText}'.`)];
1764
1764
  }
1765
1765
  match(sourceType, targetType, isNot) {
1766
- const isMatch = this.typeChecker.isTypeIdenticalTo(sourceType, targetType);
1766
+ const isMatch = this.typeChecker.isTypeRelatedTo(sourceType, targetType, this.typeChecker.relation.identity);
1767
1767
  return {
1768
1768
  explain: () => this.#explain(sourceType, targetType, isNot),
1769
1769
  isMatch,
@@ -1825,7 +1825,7 @@ class ToMatch {
1825
1825
  : [Diagnostic.error(`Type '${targetTypeText}' is not a subtype of type '${sourceTypeText}'.`)];
1826
1826
  }
1827
1827
  match(sourceType, targetType, isNot) {
1828
- const isMatch = this.typeChecker.isTypeSubtypeOf(sourceType, targetType);
1828
+ const isMatch = this.typeChecker.isTypeRelatedTo(sourceType, targetType, this.typeChecker.relation.subtype);
1829
1829
  return {
1830
1830
  explain: () => this.#explain(sourceType, targetType, isNot),
1831
1831
  isMatch,
@@ -1971,7 +1971,7 @@ class Expect {
1971
1971
  this.toRaiseError = new ToRaiseError(this.compiler, this.typeChecker);
1972
1972
  }
1973
1973
  static assertTypeChecker(typeChecker) {
1974
- return ("isTypeAssignableTo" in typeChecker && "isTypeIdenticalTo" in typeChecker && "isTypeSubtypeOf" in typeChecker);
1974
+ return ("isTypeRelatedTo" in typeChecker && "relation" in typeChecker);
1975
1975
  }
1976
1976
  #getType(node) {
1977
1977
  return this.compiler.isExpression(node)
@@ -2030,7 +2030,7 @@ class Expect {
2030
2030
  const sourceType = this.#getType(assertion.source[0]);
2031
2031
  const nonPrimitiveType = { flags: this.compiler.TypeFlags.NonPrimitive };
2032
2032
  if (sourceType.flags & (this.compiler.TypeFlags.Any | this.compiler.TypeFlags.Never)
2033
- || !this.typeChecker.isTypeAssignableTo(sourceType, nonPrimitiveType)) {
2033
+ || !this.typeChecker.isTypeRelatedTo(sourceType, nonPrimitiveType, this.typeChecker.relation.assignable)) {
2034
2034
  this.#onSourceArgumentMustBeObjectType(assertion.source[0], expectResult);
2035
2035
  return;
2036
2036
  }
@@ -2528,7 +2528,7 @@ class TestFileRunner {
2528
2528
  }
2529
2529
  const typeChecker = program.getTypeChecker();
2530
2530
  if (!Expect.assertTypeChecker(typeChecker)) {
2531
- const text = "The required 'isTypeAssignableTo()', 'isTypeIdenticalTo()' and 'isTypeSubtypeOf()' methods are missing in the provided type checker.";
2531
+ const text = "The required 'isTypeRelatedTo()' method is missing in the provided type checker.";
2532
2532
  EventEmitter.dispatch(["file:error", { diagnostics: [Diagnostic.error(text)], result: fileResult }]);
2533
2533
  return;
2534
2534
  }
@@ -2580,7 +2580,7 @@ class TSTyche {
2580
2580
  #abortController = new AbortController();
2581
2581
  #storeService;
2582
2582
  #taskRunner;
2583
- static version = "1.0.0-rc.1";
2583
+ static version = "1.0.0-rc.2";
2584
2584
  constructor(resolvedConfig, storeService) {
2585
2585
  this.resolvedConfig = resolvedConfig;
2586
2586
  this.#storeService = storeService;
@@ -2591,12 +2591,11 @@ class TSTyche {
2591
2591
  EventEmitter.addHandler(([eventName, payload]) => {
2592
2592
  if (eventName.includes("error") || eventName.includes("fail")) {
2593
2593
  if ("diagnostics" in payload
2594
- && !payload.diagnostics.some(({ category }) => category === "error")) {
2595
- return;
2596
- }
2597
- process.exitCode = 1;
2598
- if (this.resolvedConfig.failFast) {
2599
- this.#abortController.abort();
2594
+ && payload.diagnostics.some((diagnostic) => diagnostic.category === "error")) {
2595
+ process.exitCode = 1;
2596
+ if (this.resolvedConfig.failFast) {
2597
+ this.#abortController.abort();
2598
+ }
2600
2599
  }
2601
2600
  }
2602
2601
  });
@@ -3531,10 +3530,14 @@ class StoreService {
3531
3530
  const candidatePaths = [Path.join(Path.dirname(modulePath), "tsserverlibrary.js"), modulePath];
3532
3531
  for (const candidatePath of candidatePaths) {
3533
3532
  const sourceText = await fs.readFile(candidatePath, { encoding: "utf8" });
3534
- const modifiedSourceText = sourceText.replace("return checker;", "return { ...checker, isTypeIdenticalTo, isTypeSubtypeOf };");
3535
- if (modifiedSourceText.length === sourceText.length) {
3533
+ if (!sourceText.includes("isTypeRelatedTo")) {
3536
3534
  continue;
3537
3535
  }
3536
+ const toExpose = [
3537
+ "isTypeRelatedTo",
3538
+ "relation: { assignable: assignableRelation, identity: identityRelation, subtype: strictSubtypeRelation }",
3539
+ ];
3540
+ const modifiedSourceText = sourceText.replace("return checker;", `return { ...checker, ${toExpose.join(", ")} };`);
3538
3541
  const compiledWrapper = vm.compileFunction(modifiedSourceText, ["exports", "require", "module", "__filename", "__dirname"], { filename: candidatePath });
3539
3542
  compiledWrapper(exports, createRequire(candidatePath), module, candidatePath, Path.dirname(candidatePath));
3540
3543
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "The Essential Type Testing Tool.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -17,6 +17,7 @@
17
17
  "type": "git",
18
18
  "url": "git+https://github.com/tstyche/tstyche.git"
19
19
  },
20
+ "funding": "https://github.com/tstyche/tstyche?sponsor=1",
20
21
  "license": "MIT",
21
22
  "type": "module",
22
23
  "exports": {
@@ -37,15 +38,15 @@
37
38
  "bench": "./benchmarks/tstyche.bench.sh",
38
39
  "build": "rollup --config rollup.config.js",
39
40
  "build:watch": "yarn build --sourcemap --watch",
40
- "clean": "rm -rf build",
41
- "generate": "yarn generate:schema && yarn generate:types",
42
- "generate:schema": "node ./models/__scripts__/generate-schema.js",
43
- "generate:types": "node ./models/__scripts__/generate-types.js",
44
41
  "check": "yarn check:spelling && yarn check:formatting",
45
- "check:spelling": "cspell --config cspell.config.json --quiet",
46
42
  "check:formatting": "dprint check",
43
+ "check:spelling": "cspell --config cspell.config.json --quiet",
47
44
  "check:types": "tsc --noEmit --project tsconfig.json",
45
+ "clean": "rm -rf build",
48
46
  "format": "dprint fmt",
47
+ "generate": "yarn generate:schema && yarn generate:types",
48
+ "generate:schema": "node ./models/__scripts__/generate-schema.js",
49
+ "generate:types": "node ./models/__scripts__/generate-types.js",
49
50
  "lint": "eslint ./ --config eslint.config.json --ext .js,.cts,.ts,.tsx",
50
51
  "prepack": "yarn clean && yarn build",
51
52
  "prepublish": "yarn test",
@@ -60,8 +61,8 @@
60
61
  "@jest/globals": "29.7.0",
61
62
  "@rollup/plugin-typescript": "11.1.6",
62
63
  "@types/node": "20.11.17",
63
- "@typescript-eslint/eslint-plugin": "6.21.0",
64
- "@typescript-eslint/parser": "6.21.0",
64
+ "@typescript-eslint/eslint-plugin": "7.0.1",
65
+ "@typescript-eslint/parser": "7.0.1",
65
66
  "ajv": "8.12.0",
66
67
  "c8": "9.1.0",
67
68
  "cspell": "8.3.2",
@@ -69,13 +70,13 @@
69
70
  "eslint": "8.56.0",
70
71
  "eslint-import-resolver-typescript": "3.6.1",
71
72
  "eslint-plugin-import": "2.29.1",
72
- "eslint-plugin-jest": "27.6.3",
73
+ "eslint-plugin-jest": "27.8.0",
73
74
  "eslint-plugin-jest-formatting": "3.1.0",
74
- "eslint-plugin-simple-import-sort": "11.0.0",
75
+ "eslint-plugin-simple-import-sort": "12.0.0",
75
76
  "jest": "29.7.0",
76
77
  "jest-serializer-ansi-escapes": "2.0.1",
77
78
  "magic-string": "0.30.7",
78
- "rollup": "4.9.6",
79
+ "rollup": "4.10.0",
79
80
  "rollup-plugin-dts": "6.1.0",
80
81
  "ts-node": "10.9.2",
81
82
  "tslib": "2.6.2",