tstyche 3.0.0-rc.0 → 3.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/build/index.d.cts +1 -1
- package/build/index.d.ts +1 -1
- package/build/tstyche.d.ts +1 -0
- package/build/tstyche.js +71 -30
- package/package.json +4 -4
package/build/index.d.cts
CHANGED
|
@@ -149,7 +149,7 @@ interface Matchers {
|
|
|
149
149
|
/**
|
|
150
150
|
* Checks if the source type raises an error.
|
|
151
151
|
*/
|
|
152
|
-
toRaiseError: (...target: Array<string | number>) => void;
|
|
152
|
+
toRaiseError: (...target: Array<string | number | RegExp>) => void;
|
|
153
153
|
}
|
|
154
154
|
interface Matchers {
|
|
155
155
|
/**
|
package/build/index.d.ts
CHANGED
|
@@ -149,7 +149,7 @@ interface Matchers {
|
|
|
149
149
|
/**
|
|
150
150
|
* Checks if the source type raises an error.
|
|
151
151
|
*/
|
|
152
|
-
toRaiseError: (...target: Array<string | number>) => void;
|
|
152
|
+
toRaiseError: (...target: Array<string | number | RegExp>) => void;
|
|
153
153
|
}
|
|
154
154
|
interface Matchers {
|
|
155
155
|
/**
|
package/build/tstyche.d.ts
CHANGED
|
@@ -558,6 +558,7 @@ interface MatchResult {
|
|
|
558
558
|
}
|
|
559
559
|
type Relation = Map<string, unknown>;
|
|
560
560
|
interface TypeChecker extends ts.TypeChecker {
|
|
561
|
+
isApplicableIndexType: (source: ts.Type, target: ts.Type) => boolean;
|
|
561
562
|
isTypeRelatedTo: (source: ts.Type, target: ts.Type, relation: Relation) => boolean;
|
|
562
563
|
relation: {
|
|
563
564
|
assignable: Relation;
|
package/build/tstyche.js
CHANGED
|
@@ -701,22 +701,23 @@ class Store {
|
|
|
701
701
|
static async #loadModule(modulePath) {
|
|
702
702
|
const exports = {};
|
|
703
703
|
const module = { exports };
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
}
|
|
704
|
+
const packageConfigText = await fs.readFile(Path.resolve(modulePath, "../../package.json"), { encoding: "utf8" });
|
|
705
|
+
const { version: packageVersion } = JSON.parse(packageConfigText);
|
|
706
|
+
if (!Version.isSatisfiedWith(packageVersion, "5.3")) {
|
|
707
|
+
modulePath = Path.resolve(modulePath, "../tsserverlibrary.js");
|
|
708
|
+
}
|
|
709
|
+
const sourceText = await fs.readFile(modulePath, { encoding: "utf8" });
|
|
710
|
+
const toExpose = [];
|
|
711
|
+
if (Version.isSatisfiedWith(packageVersion, "4.4")) {
|
|
712
|
+
toExpose.push("isApplicableIndexType");
|
|
713
|
+
}
|
|
714
|
+
if (!Version.isSatisfiedWith(packageVersion, "4.6")) {
|
|
715
|
+
toExpose.push("getTypeOfSymbol");
|
|
716
|
+
}
|
|
717
|
+
toExpose.push("isTypeRelatedTo", "relation: { assignable: assignableRelation, identity: identityRelation, subtype: strictSubtypeRelation }");
|
|
718
|
+
const modifiedSourceText = sourceText.replace("return checker;", `return { ...checker, ${toExpose.join(", ")} };`);
|
|
719
|
+
const compiledWrapper = vm.compileFunction(modifiedSourceText, ["exports", "require", "module", "__filename", "__dirname"], { filename: modulePath });
|
|
720
|
+
compiledWrapper(exports, createRequire(modulePath), module, modulePath, Path.dirname(modulePath));
|
|
720
721
|
return module.exports;
|
|
721
722
|
}
|
|
722
723
|
static #onDiagnostics(diagnostic) {
|
|
@@ -961,19 +962,29 @@ class Options {
|
|
|
961
962
|
}
|
|
962
963
|
return definitionMap;
|
|
963
964
|
}
|
|
965
|
+
static #getCanonicalOptionName(optionName) {
|
|
966
|
+
return optionName.startsWith("--") ? optionName.slice(2) : optionName;
|
|
967
|
+
}
|
|
968
|
+
static #isBuiltinReporter(optionValue) {
|
|
969
|
+
return ["list", "summary"].includes(optionValue);
|
|
970
|
+
}
|
|
971
|
+
static #isLookupStrategy(optionValue) {
|
|
972
|
+
return ["findup", "ignore"].includes(optionValue);
|
|
973
|
+
}
|
|
964
974
|
static resolve(optionName, optionValue, rootPath = ".") {
|
|
965
|
-
|
|
975
|
+
const canonicalOptionName = Options.#getCanonicalOptionName(optionName);
|
|
976
|
+
switch (canonicalOptionName) {
|
|
966
977
|
case "config":
|
|
967
978
|
case "rootPath":
|
|
968
979
|
case "tsconfig":
|
|
969
|
-
if (
|
|
980
|
+
if (canonicalOptionName === "tsconfig" && Options.#isLookupStrategy(optionValue)) {
|
|
970
981
|
break;
|
|
971
982
|
}
|
|
972
983
|
optionValue = Path.resolve(rootPath, optionValue);
|
|
973
984
|
break;
|
|
974
985
|
case "plugins":
|
|
975
986
|
case "reporters":
|
|
976
|
-
if (
|
|
987
|
+
if (canonicalOptionName === "reporters" && Options.#isBuiltinReporter(optionValue)) {
|
|
977
988
|
break;
|
|
978
989
|
}
|
|
979
990
|
try {
|
|
@@ -991,11 +1002,12 @@ class Options {
|
|
|
991
1002
|
return optionValue;
|
|
992
1003
|
}
|
|
993
1004
|
static async validate(optionName, optionValue, optionBrand, onDiagnostics, origin) {
|
|
994
|
-
|
|
1005
|
+
const canonicalOptionName = Options.#getCanonicalOptionName(optionName);
|
|
1006
|
+
switch (canonicalOptionName) {
|
|
995
1007
|
case "config":
|
|
996
1008
|
case "rootPath":
|
|
997
1009
|
case "tsconfig":
|
|
998
|
-
if (
|
|
1010
|
+
if (canonicalOptionName === "tsconfig" && Options.#isLookupStrategy(optionValue)) {
|
|
999
1011
|
break;
|
|
1000
1012
|
}
|
|
1001
1013
|
if (existsSync(optionValue)) {
|
|
@@ -1005,7 +1017,7 @@ class Options {
|
|
|
1005
1017
|
break;
|
|
1006
1018
|
case "plugins":
|
|
1007
1019
|
case "reporters":
|
|
1008
|
-
if (
|
|
1020
|
+
if (canonicalOptionName === "reporters" && Options.#isBuiltinReporter(optionValue)) {
|
|
1009
1021
|
break;
|
|
1010
1022
|
}
|
|
1011
1023
|
if (optionValue.startsWith("file:") && existsSync(new URL(optionValue))) {
|
|
@@ -3271,6 +3283,28 @@ class MatchWorker {
|
|
|
3271
3283
|
this.#typeChecker = typeChecker;
|
|
3272
3284
|
this.assertion = assertion;
|
|
3273
3285
|
}
|
|
3286
|
+
checkHasApplicableIndexType(sourceNode, targetNode) {
|
|
3287
|
+
const sourceType = this.getType(sourceNode);
|
|
3288
|
+
const targetType = this.getType(targetNode);
|
|
3289
|
+
if (Version.isSatisfiedWith(this.#compiler.version, "4.4")) {
|
|
3290
|
+
return this.#typeChecker
|
|
3291
|
+
.getIndexInfosOfType(sourceType)
|
|
3292
|
+
.some(({ keyType }) => this.#typeChecker.isApplicableIndexType(targetType, keyType));
|
|
3293
|
+
}
|
|
3294
|
+
if (targetType.flags & this.#compiler.TypeFlags.StringLiteral) {
|
|
3295
|
+
return sourceType.getStringIndexType() != null;
|
|
3296
|
+
}
|
|
3297
|
+
if (targetType.flags & this.#compiler.TypeFlags.NumberLiteral) {
|
|
3298
|
+
return (sourceType.getStringIndexType() ?? sourceType.getNumberIndexType()) != null;
|
|
3299
|
+
}
|
|
3300
|
+
return false;
|
|
3301
|
+
}
|
|
3302
|
+
checkHasProperty(sourceNode, propertyNameText) {
|
|
3303
|
+
const sourceType = this.getType(sourceNode);
|
|
3304
|
+
return sourceType
|
|
3305
|
+
.getProperties()
|
|
3306
|
+
.some((property) => this.#compiler.unescapeLeadingUnderscores(property.escapedName) === propertyNameText);
|
|
3307
|
+
}
|
|
3274
3308
|
checkIsAssignableTo(sourceNode, targetNode) {
|
|
3275
3309
|
const relation = this.#typeChecker.relation.assignable;
|
|
3276
3310
|
return this.#checkIsRelatedTo(sourceNode, targetNode, relation);
|
|
@@ -3281,7 +3315,9 @@ class MatchWorker {
|
|
|
3281
3315
|
}
|
|
3282
3316
|
checkIsIdenticalTo(sourceNode, targetNode) {
|
|
3283
3317
|
const relation = this.#typeChecker.relation.identity;
|
|
3284
|
-
return this.#checkIsRelatedTo(sourceNode, targetNode, relation)
|
|
3318
|
+
return (this.#checkIsRelatedTo(sourceNode, targetNode, relation) &&
|
|
3319
|
+
this.checkIsAssignableTo(sourceNode, targetNode) &&
|
|
3320
|
+
this.checkIsAssignableWith(sourceNode, targetNode));
|
|
3285
3321
|
}
|
|
3286
3322
|
checkIsSubtype(sourceNode, targetNode) {
|
|
3287
3323
|
const relation = this.#typeChecker.relation.subtype;
|
|
@@ -3643,7 +3679,7 @@ class ToHaveProperty {
|
|
|
3643
3679
|
diagnostics.push(Diagnostic.error(text, origin));
|
|
3644
3680
|
}
|
|
3645
3681
|
const targetType = matchWorker.getType(targetNode);
|
|
3646
|
-
let propertyNameText;
|
|
3682
|
+
let propertyNameText = "";
|
|
3647
3683
|
if (matchWorker.isStringOrNumberLiteralType(targetType)) {
|
|
3648
3684
|
propertyNameText = targetType.value.toString();
|
|
3649
3685
|
}
|
|
@@ -3660,9 +3696,8 @@ class ToHaveProperty {
|
|
|
3660
3696
|
onDiagnostics(diagnostics);
|
|
3661
3697
|
return;
|
|
3662
3698
|
}
|
|
3663
|
-
const isMatch =
|
|
3664
|
-
|
|
3665
|
-
});
|
|
3699
|
+
const isMatch = matchWorker.checkHasProperty(sourceNode, propertyNameText) ||
|
|
3700
|
+
matchWorker.checkHasApplicableIndexType(sourceNode, targetNode);
|
|
3666
3701
|
return {
|
|
3667
3702
|
explain: () => this.#explain(matchWorker, sourceNode, targetNode),
|
|
3668
3703
|
isMatch,
|
|
@@ -3722,8 +3757,10 @@ class ToRaiseError {
|
|
|
3722
3757
|
match(matchWorker, sourceNode, targetNodes, onDiagnostics) {
|
|
3723
3758
|
const diagnostics = [];
|
|
3724
3759
|
for (const targetNode of targetNodes) {
|
|
3725
|
-
if (!(this.#compiler.isStringLiteralLike(targetNode) ||
|
|
3726
|
-
|
|
3760
|
+
if (!(this.#compiler.isStringLiteralLike(targetNode) ||
|
|
3761
|
+
this.#compiler.isNumericLiteral(targetNode) ||
|
|
3762
|
+
this.#compiler.isRegularExpressionLiteral(targetNode))) {
|
|
3763
|
+
const expectedText = "a string, number or regular expression literal";
|
|
3727
3764
|
const text = ExpectDiagnosticText.argumentMustBe("target", expectedText);
|
|
3728
3765
|
const origin = DiagnosticOrigin.fromNode(targetNode);
|
|
3729
3766
|
diagnostics.push(Diagnostic.error(text, origin));
|
|
@@ -3748,6 +3785,10 @@ class ToRaiseError {
|
|
|
3748
3785
|
};
|
|
3749
3786
|
}
|
|
3750
3787
|
#matchExpectedError(diagnostic, targetNode) {
|
|
3788
|
+
if (this.#compiler.isRegularExpressionLiteral(targetNode)) {
|
|
3789
|
+
const targetRegex = new RegExp(...targetNode.text.slice(1).split("/"));
|
|
3790
|
+
return targetRegex.test(this.#compiler.flattenDiagnosticMessageText(diagnostic.messageText, " ", 0));
|
|
3791
|
+
}
|
|
3751
3792
|
if (this.#compiler.isStringLiteralLike(targetNode)) {
|
|
3752
3793
|
return this.#compiler.flattenDiagnosticMessageText(diagnostic.messageText, " ", 0).includes(targetNode.text);
|
|
3753
3794
|
}
|
|
@@ -4096,7 +4137,7 @@ class TaskRunner {
|
|
|
4096
4137
|
class Runner {
|
|
4097
4138
|
#eventEmitter = new EventEmitter();
|
|
4098
4139
|
#resolvedConfig;
|
|
4099
|
-
static version = "3.0.0-rc.
|
|
4140
|
+
static version = "3.0.0-rc.2";
|
|
4100
4141
|
constructor(resolvedConfig) {
|
|
4101
4142
|
this.#resolvedConfig = resolvedConfig;
|
|
4102
4143
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tstyche",
|
|
3
|
-
"version": "3.0.0-rc.
|
|
3
|
+
"version": "3.0.0-rc.2",
|
|
4
4
|
"description": "The Essential Type Testing Tool.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -63,16 +63,16 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@biomejs/biome": "1.9.4",
|
|
65
65
|
"@rollup/plugin-typescript": "12.1.1",
|
|
66
|
-
"@types/node": "22.8.
|
|
66
|
+
"@types/node": "22.8.6",
|
|
67
67
|
"@types/react": "18.3.12",
|
|
68
68
|
"ajv": "8.17.1",
|
|
69
|
-
"cspell": "8.15.
|
|
69
|
+
"cspell": "8.15.5",
|
|
70
70
|
"magic-string": "0.30.12",
|
|
71
71
|
"monocart-coverage-reports": "2.11.1",
|
|
72
72
|
"pretty-ansi": "2.0.0",
|
|
73
73
|
"rollup": "4.24.3",
|
|
74
74
|
"rollup-plugin-dts": "6.1.1",
|
|
75
|
-
"tslib": "2.8.
|
|
75
|
+
"tslib": "2.8.1",
|
|
76
76
|
"typescript": "5.6.3"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|