tstyche 3.0.0-beta.5 → 3.0.0-beta.6
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/tstyche.d.ts +32 -21
- package/build/tstyche.js +207 -236
- package/package.json +4 -4
package/build/tstyche.d.ts
CHANGED
|
@@ -132,7 +132,8 @@ declare enum OptionBrand {
|
|
|
132
132
|
|
|
133
133
|
declare enum OptionGroup {
|
|
134
134
|
CommandLine = 2,
|
|
135
|
-
ConfigFile = 4
|
|
135
|
+
ConfigFile = 4,
|
|
136
|
+
ResolvedConfig = 6
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
declare class ConfigDiagnosticText {
|
|
@@ -146,6 +147,7 @@ declare class ConfigDiagnosticText {
|
|
|
146
147
|
static testFileMatchCannotStartWith(segment: string): Array<string>;
|
|
147
148
|
static requiresValueType(optionName: string, optionBrand: OptionBrand, optionGroup: OptionGroup): string;
|
|
148
149
|
static unknownOption(optionName: string): string;
|
|
150
|
+
static usage(optionName: string, optionBrand: OptionBrand, optionGroup: OptionGroup): Promise<Array<string>>;
|
|
149
151
|
static versionIsNotSupported(value: string): string;
|
|
150
152
|
static watchCannotBeEnabled(): string;
|
|
151
153
|
}
|
|
@@ -305,6 +307,8 @@ interface ListTypeOptionDefinition extends BaseOptionDefinition {
|
|
|
305
307
|
declare class Options {
|
|
306
308
|
#private;
|
|
307
309
|
static for(optionGroup: OptionGroup): Map<string, OptionDefinition>;
|
|
310
|
+
static resolve(optionName: string, optionValue: string, rootPath?: string): string;
|
|
311
|
+
static validate(optionDefinition: OptionDefinition | ItemDefinition, optionValue: string, optionGroup: OptionGroup, onDiagnostics: DiagnosticsHandler$1, origin?: DiagnosticOrigin): Promise<void>;
|
|
308
312
|
}
|
|
309
313
|
|
|
310
314
|
declare const defaultOptions: Required<ConfigFileOptions>;
|
|
@@ -714,25 +718,6 @@ declare class ResultHandler implements EventHandler {
|
|
|
714
718
|
on([event, payload]: Event): void;
|
|
715
719
|
}
|
|
716
720
|
|
|
717
|
-
interface Hooks {
|
|
718
|
-
/**
|
|
719
|
-
* Is called after configuration is resolved and allows to modify it.
|
|
720
|
-
*/
|
|
721
|
-
config?: (resolvedConfig: ResolvedConfig) => ResolvedConfig | Promise<ResolvedConfig>;
|
|
722
|
-
/**
|
|
723
|
-
* Is called after test files are selected and allows to modify the list.
|
|
724
|
-
*/
|
|
725
|
-
select?: (testFiles: Array<string>) => Array<string | URL> | Promise<Array<string | URL>>;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
declare class HooksService {
|
|
729
|
-
#private;
|
|
730
|
-
static addHandler(hooks: Hooks): void;
|
|
731
|
-
static call(hook: "config", resolvedConfig: ResolvedConfig): Promise<ResolvedConfig>;
|
|
732
|
-
static call(hook: "select", testFiles: Array<string>): Promise<Array<string | URL>>;
|
|
733
|
-
static removeHandlers(): void;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
721
|
type InputHandler = (chunk: string) => void;
|
|
737
722
|
declare class InputService {
|
|
738
723
|
#private;
|
|
@@ -849,6 +834,32 @@ declare class Path {
|
|
|
849
834
|
static resolve(...filePaths: Array<string>): string;
|
|
850
835
|
}
|
|
851
836
|
|
|
837
|
+
interface SelectHookContext {
|
|
838
|
+
resolvedConfig: ResolvedConfig;
|
|
839
|
+
}
|
|
840
|
+
interface Plugin {
|
|
841
|
+
/**
|
|
842
|
+
* The name of this plugin.
|
|
843
|
+
*/
|
|
844
|
+
name: string;
|
|
845
|
+
/**
|
|
846
|
+
* Is called after configuration is resolved and allows to modify it.
|
|
847
|
+
*/
|
|
848
|
+
config?: (resolvedConfig: ResolvedConfig) => ResolvedConfig | Promise<ResolvedConfig>;
|
|
849
|
+
/**
|
|
850
|
+
* Is called after test files are selected and allows to modify the list.
|
|
851
|
+
*/
|
|
852
|
+
select?: (this: SelectHookContext, testFiles: Array<string>) => Array<string | URL> | Promise<Array<string | URL>>;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
type Hooks = Required<Omit<Plugin, "name">>;
|
|
856
|
+
declare class PluginService {
|
|
857
|
+
#private;
|
|
858
|
+
static addHandler(plugin: Plugin): void;
|
|
859
|
+
static call<T extends keyof Hooks>(hook: T, argument: Parameters<Hooks[T]>[0], context: ThisParameterType<Hooks[T]>): Promise<Awaited<ReturnType<Hooks[T]>>>;
|
|
860
|
+
static removeHandlers(): void;
|
|
861
|
+
}
|
|
862
|
+
|
|
852
863
|
declare class ProjectService {
|
|
853
864
|
#private;
|
|
854
865
|
constructor(resolvedConfig: ResolvedConfig, compiler: typeof ts);
|
|
@@ -917,4 +928,4 @@ declare class WatchService {
|
|
|
917
928
|
watch(cancellationToken: CancellationToken): AsyncIterable<Array<Task>>;
|
|
918
929
|
}
|
|
919
930
|
|
|
920
|
-
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, type CommandLineOptions, Config, ConfigDiagnosticText, type ConfigFileOptions, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, type DiagnosticsHandler$1 as DiagnosticsHandler, type EnvironmentOptions, type Event, EventEmitter, type EventHandler, ExitCodeHandler, ExpectResult, ExpectService, type FileWatchHandler, FileWatcher, type
|
|
931
|
+
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, type CommandLineOptions, Config, ConfigDiagnosticText, type ConfigFileOptions, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, type DiagnosticsHandler$1 as DiagnosticsHandler, type EnvironmentOptions, type Event, EventEmitter, type EventHandler, ExitCodeHandler, ExpectResult, ExpectService, type FileWatchHandler, FileWatcher, type InputHandler, InputService, type ItemDefinition, Line, ListReporter, type MatchResult, OptionBrand, type OptionDefinition, OptionGroup, Options, OutputService, Path, type Plugin, PluginService, ProjectResult, ProjectService, type Reporter, type ReporterEvent, type ResolvedConfig, Result, ResultCount, ResultHandler, ResultStatus, ResultTiming, Runner, Scribbler, ScribblerJsx, type ScribblerOptions, Select, SelectDiagnosticText, SetupReporter, SourceFile, Store, SummaryReporter, TargetResult, type TargetResultStatus, Task, TaskResult, type TaskResultStatus, TestMember, TestMemberBrand, TestMemberFlags, TestResult, TestTree, Text, type TypeChecker, Version, type WatchHandler, WatchReporter, WatchService, Watcher, type WatcherOptions, addsPackageText, defaultOptions, describeNameText, diagnosticText, environmentOptions, fileViewText, formattedText, helpText, summaryText, taskStatusText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
package/build/tstyche.js
CHANGED
|
@@ -1,64 +1,12 @@
|
|
|
1
|
-
import { writeFileSync, rmSync, existsSync, watch } from 'node:fs';
|
|
2
1
|
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
5
2
|
import { createRequire } from 'node:module';
|
|
6
3
|
import vm from 'node:vm';
|
|
7
4
|
import os from 'node:os';
|
|
8
5
|
import process from 'node:process';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { writeFileSync, rmSync, existsSync, watch } from 'node:fs';
|
|
9
8
|
import streamConsumers from 'node:stream/consumers';
|
|
10
|
-
|
|
11
|
-
class ConfigDiagnosticText {
|
|
12
|
-
static expected(element) {
|
|
13
|
-
return `Expected ${element}.`;
|
|
14
|
-
}
|
|
15
|
-
static expectsListItemType(optionName, optionBrand) {
|
|
16
|
-
return `Item of the '${optionName}' list must be of type ${optionBrand}.`;
|
|
17
|
-
}
|
|
18
|
-
static expectsValue(optionName, optionGroup) {
|
|
19
|
-
optionName = ConfigDiagnosticText.#optionName(optionName, optionGroup);
|
|
20
|
-
return `Option '${optionName}' expects a value.`;
|
|
21
|
-
}
|
|
22
|
-
static fileDoesNotExist(filePath) {
|
|
23
|
-
return `The specified path '${filePath}' does not exist.`;
|
|
24
|
-
}
|
|
25
|
-
static moduleWasNotFound(specifier) {
|
|
26
|
-
return `The specified module '${specifier}' was not found.`;
|
|
27
|
-
}
|
|
28
|
-
static #optionName(optionName, optionGroup) {
|
|
29
|
-
switch (optionGroup) {
|
|
30
|
-
case 2:
|
|
31
|
-
return `--${optionName}`;
|
|
32
|
-
case 4:
|
|
33
|
-
return optionName;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
static seen(element) {
|
|
37
|
-
return `The ${element} was seen here.`;
|
|
38
|
-
}
|
|
39
|
-
static testFileMatchCannotStartWith(segment) {
|
|
40
|
-
return [
|
|
41
|
-
`A test file match pattern cannot start with '${segment}'.`,
|
|
42
|
-
"The test files are only collected within the 'rootPath' directory.",
|
|
43
|
-
];
|
|
44
|
-
}
|
|
45
|
-
static requiresValueType(optionName, optionBrand, optionGroup) {
|
|
46
|
-
optionName = ConfigDiagnosticText.#optionName(optionName, optionGroup);
|
|
47
|
-
return `Option '${optionName}' requires a value of type ${optionBrand}.`;
|
|
48
|
-
}
|
|
49
|
-
static unknownOption(optionName) {
|
|
50
|
-
return `Unknown option '${optionName}'.`;
|
|
51
|
-
}
|
|
52
|
-
static versionIsNotSupported(value) {
|
|
53
|
-
if (value === "current") {
|
|
54
|
-
return "Cannot use 'current' as a target. Failed to resolve the path to the currently installed TypeScript module.";
|
|
55
|
-
}
|
|
56
|
-
return `TypeScript version '${value}' is not supported.`;
|
|
57
|
-
}
|
|
58
|
-
static watchCannotBeEnabled() {
|
|
59
|
-
return "Watch mode cannot be enabled in continuous integration environment.";
|
|
60
|
-
}
|
|
61
|
-
}
|
|
9
|
+
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
62
10
|
|
|
63
11
|
class DiagnosticOrigin {
|
|
64
12
|
assertion;
|
|
@@ -169,49 +117,6 @@ class SourceFile {
|
|
|
169
117
|
}
|
|
170
118
|
}
|
|
171
119
|
|
|
172
|
-
class EventEmitter {
|
|
173
|
-
static instanceCount = 0;
|
|
174
|
-
static #handlers = new Map();
|
|
175
|
-
static #reporters = new Map();
|
|
176
|
-
#scope;
|
|
177
|
-
constructor() {
|
|
178
|
-
this.#scope = EventEmitter.instanceCount++;
|
|
179
|
-
EventEmitter.#handlers.set(this.#scope, new Set());
|
|
180
|
-
EventEmitter.#reporters.set(this.#scope, new Set());
|
|
181
|
-
}
|
|
182
|
-
addHandler(handler) {
|
|
183
|
-
EventEmitter.#handlers.get(this.#scope)?.add(handler);
|
|
184
|
-
}
|
|
185
|
-
addReporter(reporter) {
|
|
186
|
-
EventEmitter.#reporters.get(this.#scope)?.add(reporter);
|
|
187
|
-
}
|
|
188
|
-
static dispatch(event) {
|
|
189
|
-
function forEachHandler(handlers, event) {
|
|
190
|
-
for (const handler of handlers) {
|
|
191
|
-
handler.on(event);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
for (const handlers of EventEmitter.#handlers.values()) {
|
|
195
|
-
forEachHandler(handlers, event);
|
|
196
|
-
}
|
|
197
|
-
for (const handlers of EventEmitter.#reporters.values()) {
|
|
198
|
-
forEachHandler(handlers, event);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
removeHandler(handler) {
|
|
202
|
-
EventEmitter.#handlers.get(this.#scope)?.delete(handler);
|
|
203
|
-
}
|
|
204
|
-
removeReporter(reporter) {
|
|
205
|
-
EventEmitter.#reporters.get(this.#scope)?.delete(reporter);
|
|
206
|
-
}
|
|
207
|
-
removeHandlers() {
|
|
208
|
-
EventEmitter.#handlers.get(this.#scope)?.clear();
|
|
209
|
-
}
|
|
210
|
-
removeReporters() {
|
|
211
|
-
EventEmitter.#reporters.get(this.#scope)?.clear();
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
120
|
class Path {
|
|
216
121
|
static normalizeSlashes;
|
|
217
122
|
static {
|
|
@@ -317,6 +222,49 @@ class Environment {
|
|
|
317
222
|
|
|
318
223
|
const environmentOptions = Environment.resolve();
|
|
319
224
|
|
|
225
|
+
class EventEmitter {
|
|
226
|
+
static instanceCount = 0;
|
|
227
|
+
static #handlers = new Map();
|
|
228
|
+
static #reporters = new Map();
|
|
229
|
+
#scope;
|
|
230
|
+
constructor() {
|
|
231
|
+
this.#scope = EventEmitter.instanceCount++;
|
|
232
|
+
EventEmitter.#handlers.set(this.#scope, new Set());
|
|
233
|
+
EventEmitter.#reporters.set(this.#scope, new Set());
|
|
234
|
+
}
|
|
235
|
+
addHandler(handler) {
|
|
236
|
+
EventEmitter.#handlers.get(this.#scope)?.add(handler);
|
|
237
|
+
}
|
|
238
|
+
addReporter(reporter) {
|
|
239
|
+
EventEmitter.#reporters.get(this.#scope)?.add(reporter);
|
|
240
|
+
}
|
|
241
|
+
static dispatch(event) {
|
|
242
|
+
function forEachHandler(handlers, event) {
|
|
243
|
+
for (const handler of handlers) {
|
|
244
|
+
handler.on(event);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const handlers of EventEmitter.#handlers.values()) {
|
|
248
|
+
forEachHandler(handlers, event);
|
|
249
|
+
}
|
|
250
|
+
for (const handlers of EventEmitter.#reporters.values()) {
|
|
251
|
+
forEachHandler(handlers, event);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
removeHandler(handler) {
|
|
255
|
+
EventEmitter.#handlers.get(this.#scope)?.delete(handler);
|
|
256
|
+
}
|
|
257
|
+
removeReporter(reporter) {
|
|
258
|
+
EventEmitter.#reporters.get(this.#scope)?.delete(reporter);
|
|
259
|
+
}
|
|
260
|
+
removeHandlers() {
|
|
261
|
+
EventEmitter.#handlers.get(this.#scope)?.clear();
|
|
262
|
+
}
|
|
263
|
+
removeReporters() {
|
|
264
|
+
EventEmitter.#reporters.get(this.#scope)?.clear();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
320
268
|
class Version {
|
|
321
269
|
static isGreaterThan(source, target) {
|
|
322
270
|
return !(source === target) && Version.#satisfies(source, target);
|
|
@@ -809,90 +757,73 @@ class Store {
|
|
|
809
757
|
}
|
|
810
758
|
}
|
|
811
759
|
|
|
812
|
-
class
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
760
|
+
class ConfigDiagnosticText {
|
|
761
|
+
static expected(element) {
|
|
762
|
+
return `Expected ${element}.`;
|
|
763
|
+
}
|
|
764
|
+
static expectsListItemType(optionName, optionBrand) {
|
|
765
|
+
return `Item of the '${optionName}' list must be of type ${optionBrand}.`;
|
|
766
|
+
}
|
|
767
|
+
static expectsValue(optionName, optionGroup) {
|
|
768
|
+
optionName = ConfigDiagnosticText.#optionName(optionName, optionGroup);
|
|
769
|
+
return `Option '${optionName}' expects a value.`;
|
|
770
|
+
}
|
|
771
|
+
static fileDoesNotExist(filePath) {
|
|
772
|
+
return `The specified path '${filePath}' does not exist.`;
|
|
773
|
+
}
|
|
774
|
+
static moduleWasNotFound(specifier) {
|
|
775
|
+
return `The specified module '${specifier}' was not found.`;
|
|
816
776
|
}
|
|
817
|
-
|
|
818
|
-
|
|
777
|
+
static #optionName(optionName, optionGroup) {
|
|
778
|
+
return optionGroup === 2 ? `--${optionName}` : optionName;
|
|
779
|
+
}
|
|
780
|
+
static seen(element) {
|
|
781
|
+
return `The ${element} was seen here.`;
|
|
782
|
+
}
|
|
783
|
+
static testFileMatchCannotStartWith(segment) {
|
|
784
|
+
return [
|
|
785
|
+
`A test file match pattern cannot start with '${segment}'.`,
|
|
786
|
+
"The test files are only collected within the 'rootPath' directory.",
|
|
787
|
+
];
|
|
788
|
+
}
|
|
789
|
+
static requiresValueType(optionName, optionBrand, optionGroup) {
|
|
790
|
+
const optionNameText = ConfigDiagnosticText.#optionName(optionName, optionGroup);
|
|
791
|
+
return `Option '${optionNameText}' requires a value of type ${optionBrand}.`;
|
|
792
|
+
}
|
|
793
|
+
static unknownOption(optionName) {
|
|
794
|
+
return `Unknown option '${optionName}'.`;
|
|
795
|
+
}
|
|
796
|
+
static async usage(optionName, optionBrand, optionGroup) {
|
|
797
|
+
const text = [];
|
|
819
798
|
switch (optionName) {
|
|
820
799
|
case "target": {
|
|
821
|
-
switch (
|
|
800
|
+
switch (optionGroup) {
|
|
822
801
|
case 2:
|
|
823
|
-
|
|
802
|
+
text.push("Value for the '--target' option must be a single tag or a comma separated list.", "Usage examples: '--target 4.9', '--target latest', '--target 4.9,5.3.2,current'.");
|
|
824
803
|
break;
|
|
825
804
|
case 4:
|
|
826
|
-
|
|
805
|
+
text.push("Item of the 'target' list must be a supported version tag.");
|
|
827
806
|
break;
|
|
828
807
|
}
|
|
829
808
|
const supportedTags = await Store.getSupportedTags();
|
|
830
809
|
if (supportedTags != null) {
|
|
831
|
-
|
|
810
|
+
text.push(`Supported tags: ${["'", supportedTags.join("', '"), "'"].join("")}.`);
|
|
832
811
|
}
|
|
833
812
|
break;
|
|
834
813
|
}
|
|
835
814
|
default:
|
|
836
|
-
|
|
815
|
+
text.push(ConfigDiagnosticText.requiresValueType(optionName, optionBrand, optionGroup));
|
|
837
816
|
}
|
|
838
|
-
return
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
class OptionValidator {
|
|
843
|
-
#onDiagnostics;
|
|
844
|
-
#optionGroup;
|
|
845
|
-
#optionUsageText;
|
|
846
|
-
constructor(optionGroup, onDiagnostics) {
|
|
847
|
-
this.#optionGroup = optionGroup;
|
|
848
|
-
this.#onDiagnostics = onDiagnostics;
|
|
849
|
-
this.#optionUsageText = new OptionUsageText(this.#optionGroup);
|
|
817
|
+
return text;
|
|
850
818
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
if (["findup", "ignore"].includes(optionValue)) {
|
|
855
|
-
break;
|
|
856
|
-
}
|
|
857
|
-
case "config":
|
|
858
|
-
case "rootPath":
|
|
859
|
-
if (!existsSync(optionValue)) {
|
|
860
|
-
this.#onDiagnostics(Diagnostic.error(ConfigDiagnosticText.fileDoesNotExist(optionValue), origin));
|
|
861
|
-
}
|
|
862
|
-
break;
|
|
863
|
-
case "reporters":
|
|
864
|
-
if (["list", "summary"].includes(optionValue)) {
|
|
865
|
-
break;
|
|
866
|
-
}
|
|
867
|
-
case "plugins":
|
|
868
|
-
try {
|
|
869
|
-
await import(optionValue);
|
|
870
|
-
}
|
|
871
|
-
catch {
|
|
872
|
-
this.#onDiagnostics(Diagnostic.error(ConfigDiagnosticText.moduleWasNotFound(optionValue), origin));
|
|
873
|
-
}
|
|
874
|
-
break;
|
|
875
|
-
case "target":
|
|
876
|
-
if ((await Store.validateTag(optionValue)) === false) {
|
|
877
|
-
this.#onDiagnostics(Diagnostic.error([
|
|
878
|
-
ConfigDiagnosticText.versionIsNotSupported(optionValue),
|
|
879
|
-
...(await this.#optionUsageText.get(optionName, optionBrand)),
|
|
880
|
-
], origin));
|
|
881
|
-
}
|
|
882
|
-
break;
|
|
883
|
-
case "testFileMatch":
|
|
884
|
-
for (const segment of ["/", "../"]) {
|
|
885
|
-
if (optionValue.startsWith(segment)) {
|
|
886
|
-
this.#onDiagnostics(Diagnostic.error(ConfigDiagnosticText.testFileMatchCannotStartWith(segment), origin));
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
break;
|
|
890
|
-
case "watch":
|
|
891
|
-
if (environmentOptions.isCi) {
|
|
892
|
-
this.#onDiagnostics(Diagnostic.error(ConfigDiagnosticText.watchCannotBeEnabled(), origin));
|
|
893
|
-
}
|
|
894
|
-
break;
|
|
819
|
+
static versionIsNotSupported(value) {
|
|
820
|
+
if (value === "current") {
|
|
821
|
+
return "Cannot use 'current' as a target. Failed to resolve the path to the currently installed TypeScript module.";
|
|
895
822
|
}
|
|
823
|
+
return `TypeScript version '${value}' is not supported.`;
|
|
824
|
+
}
|
|
825
|
+
static watchCannotBeEnabled() {
|
|
826
|
+
return "Watch mode cannot be enabled in continuous integration environment.";
|
|
896
827
|
}
|
|
897
828
|
}
|
|
898
829
|
|
|
@@ -1039,29 +970,89 @@ class Options {
|
|
|
1039
970
|
}
|
|
1040
971
|
return definitionMap;
|
|
1041
972
|
}
|
|
973
|
+
static resolve(optionName, optionValue, rootPath = ".") {
|
|
974
|
+
switch (optionName) {
|
|
975
|
+
case "tsconfig":
|
|
976
|
+
if (["findup", "ignore"].includes(optionValue)) {
|
|
977
|
+
break;
|
|
978
|
+
}
|
|
979
|
+
case "config":
|
|
980
|
+
case "rootPath":
|
|
981
|
+
optionValue = Path.resolve(rootPath, optionValue);
|
|
982
|
+
break;
|
|
983
|
+
case "plugins":
|
|
984
|
+
case "reporters":
|
|
985
|
+
if (optionValue.startsWith(".")) {
|
|
986
|
+
optionValue = pathToFileURL(Path.join(Path.relative(".", rootPath), optionValue)).toString();
|
|
987
|
+
}
|
|
988
|
+
break;
|
|
989
|
+
}
|
|
990
|
+
return optionValue;
|
|
991
|
+
}
|
|
992
|
+
static async validate(optionDefinition, optionValue, optionGroup, onDiagnostics, origin) {
|
|
993
|
+
switch (optionDefinition.name) {
|
|
994
|
+
case "tsconfig":
|
|
995
|
+
if (["findup", "ignore"].includes(optionValue)) {
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
case "config":
|
|
999
|
+
case "rootPath":
|
|
1000
|
+
if (!existsSync(optionValue)) {
|
|
1001
|
+
onDiagnostics(Diagnostic.error(ConfigDiagnosticText.fileDoesNotExist(optionValue), origin));
|
|
1002
|
+
}
|
|
1003
|
+
break;
|
|
1004
|
+
case "reporters":
|
|
1005
|
+
if (["list", "summary"].includes(optionValue)) {
|
|
1006
|
+
break;
|
|
1007
|
+
}
|
|
1008
|
+
case "plugins":
|
|
1009
|
+
try {
|
|
1010
|
+
await import(optionValue);
|
|
1011
|
+
}
|
|
1012
|
+
catch {
|
|
1013
|
+
onDiagnostics(Diagnostic.error(ConfigDiagnosticText.moduleWasNotFound(optionValue), origin));
|
|
1014
|
+
}
|
|
1015
|
+
break;
|
|
1016
|
+
case "target":
|
|
1017
|
+
if ((await Store.validateTag(optionValue)) === false) {
|
|
1018
|
+
onDiagnostics(Diagnostic.error([
|
|
1019
|
+
ConfigDiagnosticText.versionIsNotSupported(optionValue),
|
|
1020
|
+
await ConfigDiagnosticText.usage(optionDefinition.name, optionDefinition.brand, optionGroup),
|
|
1021
|
+
].flat(), origin));
|
|
1022
|
+
}
|
|
1023
|
+
break;
|
|
1024
|
+
case "testFileMatch":
|
|
1025
|
+
for (const segment of ["/", "../"]) {
|
|
1026
|
+
if (optionValue.startsWith(segment)) {
|
|
1027
|
+
onDiagnostics(Diagnostic.error(ConfigDiagnosticText.testFileMatchCannotStartWith(segment), origin));
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
break;
|
|
1031
|
+
case "watch":
|
|
1032
|
+
if (environmentOptions.isCi) {
|
|
1033
|
+
onDiagnostics(Diagnostic.error(ConfigDiagnosticText.watchCannotBeEnabled(), origin));
|
|
1034
|
+
}
|
|
1035
|
+
break;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1042
1038
|
}
|
|
1043
1039
|
|
|
1044
1040
|
class CommandLineParser {
|
|
1045
1041
|
#commandLineOptions;
|
|
1046
1042
|
#onDiagnostics;
|
|
1047
1043
|
#options;
|
|
1048
|
-
#optionGroup = 2;
|
|
1049
|
-
#optionUsageText;
|
|
1050
|
-
#optionValidator;
|
|
1051
1044
|
#pathMatch;
|
|
1052
1045
|
constructor(commandLine, pathMatch, onDiagnostics) {
|
|
1053
1046
|
this.#commandLineOptions = commandLine;
|
|
1054
1047
|
this.#pathMatch = pathMatch;
|
|
1055
1048
|
this.#onDiagnostics = onDiagnostics;
|
|
1056
|
-
this.#options = Options.for(
|
|
1057
|
-
this.#optionUsageText = new OptionUsageText(this.#optionGroup);
|
|
1058
|
-
this.#optionValidator = new OptionValidator(this.#optionGroup, this.#onDiagnostics);
|
|
1049
|
+
this.#options = Options.for(2);
|
|
1059
1050
|
}
|
|
1060
1051
|
async #onExpectsValue(optionDefinition) {
|
|
1061
1052
|
const text = [
|
|
1062
|
-
ConfigDiagnosticText.expectsValue(optionDefinition.name,
|
|
1063
|
-
|
|
1064
|
-
];
|
|
1053
|
+
ConfigDiagnosticText.expectsValue(optionDefinition.name, 2),
|
|
1054
|
+
await ConfigDiagnosticText.usage(optionDefinition.name, optionDefinition.brand, 2),
|
|
1055
|
+
].flat();
|
|
1065
1056
|
this.#onDiagnostics(Diagnostic.error(text));
|
|
1066
1057
|
}
|
|
1067
1058
|
async parse(commandLineArgs) {
|
|
@@ -1092,11 +1083,11 @@ class CommandLineParser {
|
|
|
1092
1083
|
let optionValue = this.#resolveOptionValue(commandLineArgs[index]);
|
|
1093
1084
|
switch (optionDefinition.brand) {
|
|
1094
1085
|
case "bareTrue":
|
|
1095
|
-
await
|
|
1086
|
+
await Options.validate(optionDefinition, optionValue, 2, this.#onDiagnostics);
|
|
1096
1087
|
this.#commandLineOptions[optionDefinition.name] = true;
|
|
1097
1088
|
break;
|
|
1098
1089
|
case "boolean":
|
|
1099
|
-
await
|
|
1090
|
+
await Options.validate(optionDefinition, optionValue, 2, this.#onDiagnostics);
|
|
1100
1091
|
this.#commandLineOptions[optionDefinition.name] = optionValue !== "false";
|
|
1101
1092
|
if (optionValue === "false" || optionValue === "true") {
|
|
1102
1093
|
index++;
|
|
@@ -1104,20 +1095,13 @@ class CommandLineParser {
|
|
|
1104
1095
|
break;
|
|
1105
1096
|
case "list":
|
|
1106
1097
|
if (optionValue !== "") {
|
|
1107
|
-
|
|
1098
|
+
const optionValues = optionValue
|
|
1108
1099
|
.split(",")
|
|
1109
1100
|
.map((value) => value.trim())
|
|
1110
|
-
.filter((value) => value !== "")
|
|
1111
|
-
|
|
1112
|
-
optionValues = optionValues.map((optionValue) => {
|
|
1113
|
-
if (optionValue.startsWith(".")) {
|
|
1114
|
-
return pathToFileURL(optionValue).toString();
|
|
1115
|
-
}
|
|
1116
|
-
return optionValue;
|
|
1117
|
-
});
|
|
1118
|
-
}
|
|
1101
|
+
.filter((value) => value !== "")
|
|
1102
|
+
.map((value) => Options.resolve(optionDefinition.name, value));
|
|
1119
1103
|
for (const optionValue of optionValues) {
|
|
1120
|
-
await
|
|
1104
|
+
await Options.validate(optionDefinition, optionValue, 2, this.#onDiagnostics);
|
|
1121
1105
|
}
|
|
1122
1106
|
this.#commandLineOptions[optionDefinition.name] = optionValues;
|
|
1123
1107
|
index++;
|
|
@@ -1127,11 +1111,8 @@ class CommandLineParser {
|
|
|
1127
1111
|
break;
|
|
1128
1112
|
case "string":
|
|
1129
1113
|
if (optionValue !== "") {
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
optionValue = Path.resolve(optionValue);
|
|
1133
|
-
}
|
|
1134
|
-
await this.#optionValidator.check(optionDefinition.name, optionValue, optionDefinition.brand);
|
|
1114
|
+
optionValue = Options.resolve(optionDefinition.name, optionValue);
|
|
1115
|
+
await Options.validate(optionDefinition, optionValue, 2, this.#onDiagnostics);
|
|
1135
1116
|
this.#commandLineOptions[optionDefinition.name] = optionValue;
|
|
1136
1117
|
index++;
|
|
1137
1118
|
break;
|
|
@@ -1279,21 +1260,18 @@ class ConfigFileParser {
|
|
|
1279
1260
|
#jsonScanner;
|
|
1280
1261
|
#onDiagnostics;
|
|
1281
1262
|
#options;
|
|
1282
|
-
#optionGroup = 4;
|
|
1283
|
-
#optionValidator;
|
|
1284
1263
|
#sourceFile;
|
|
1285
1264
|
constructor(configFileOptions, sourceFile, onDiagnostics) {
|
|
1286
1265
|
this.#configFileOptions = configFileOptions;
|
|
1287
1266
|
this.#sourceFile = sourceFile;
|
|
1288
1267
|
this.#onDiagnostics = onDiagnostics;
|
|
1289
|
-
this.#options = Options.for(
|
|
1268
|
+
this.#options = Options.for(4);
|
|
1290
1269
|
this.#jsonScanner = new JsonScanner(this.#sourceFile);
|
|
1291
|
-
this.#optionValidator = new OptionValidator(this.#optionGroup, this.#onDiagnostics);
|
|
1292
1270
|
}
|
|
1293
1271
|
#onRequiresValue(optionDefinition, jsonNode, isListItem) {
|
|
1294
1272
|
const text = isListItem
|
|
1295
1273
|
? ConfigDiagnosticText.expectsListItemType(optionDefinition.name, optionDefinition.brand)
|
|
1296
|
-
: ConfigDiagnosticText.requiresValueType(optionDefinition.name, optionDefinition.brand,
|
|
1274
|
+
: ConfigDiagnosticText.requiresValueType(optionDefinition.name, optionDefinition.brand, 4);
|
|
1297
1275
|
this.#onDiagnostics(Diagnostic.error(text, jsonNode.origin));
|
|
1298
1276
|
}
|
|
1299
1277
|
async #parseValue(optionDefinition, isListItem = false) {
|
|
@@ -1316,17 +1294,9 @@ class ConfigFileParser {
|
|
|
1316
1294
|
this.#onRequiresValue(optionDefinition, jsonNode, isListItem);
|
|
1317
1295
|
break;
|
|
1318
1296
|
}
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
optionValue = pathToFileURL(Path.join(configFilePath, optionValue)).toString();
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
if (optionDefinition.name === "rootPath" ||
|
|
1326
|
-
(optionDefinition.name === "tsconfig" && !["findup", "ignore"].includes(optionValue))) {
|
|
1327
|
-
optionValue = Path.resolve(Path.dirname(this.#sourceFile.fileName), optionValue);
|
|
1328
|
-
}
|
|
1329
|
-
await this.#optionValidator.check(optionDefinition.name, optionValue, optionDefinition.brand, jsonNode.origin);
|
|
1297
|
+
const rootPath = Path.dirname(this.#sourceFile.fileName);
|
|
1298
|
+
optionValue = Options.resolve(optionDefinition.name, optionValue, rootPath);
|
|
1299
|
+
await Options.validate(optionDefinition, optionValue, 4, this.#onDiagnostics, jsonNode.origin);
|
|
1330
1300
|
break;
|
|
1331
1301
|
}
|
|
1332
1302
|
case "list": {
|
|
@@ -1492,6 +1462,7 @@ var OptionGroup;
|
|
|
1492
1462
|
(function (OptionGroup) {
|
|
1493
1463
|
OptionGroup[OptionGroup["CommandLine"] = 2] = "CommandLine";
|
|
1494
1464
|
OptionGroup[OptionGroup["ConfigFile"] = 4] = "ConfigFile";
|
|
1465
|
+
OptionGroup[OptionGroup["ResolvedConfig"] = 6] = "ResolvedConfig";
|
|
1495
1466
|
})(OptionGroup || (OptionGroup = {}));
|
|
1496
1467
|
|
|
1497
1468
|
class CancellationHandler {
|
|
@@ -1837,25 +1808,6 @@ class ResultHandler {
|
|
|
1837
1808
|
}
|
|
1838
1809
|
}
|
|
1839
1810
|
|
|
1840
|
-
class HooksService {
|
|
1841
|
-
static #handlers = new Set();
|
|
1842
|
-
static addHandler(hooks) {
|
|
1843
|
-
HooksService.#handlers.add(hooks);
|
|
1844
|
-
}
|
|
1845
|
-
static async call(hook, options) {
|
|
1846
|
-
for (const handler of HooksService.#handlers) {
|
|
1847
|
-
const result = await handler[hook]?.(options);
|
|
1848
|
-
if (result != null) {
|
|
1849
|
-
options = result;
|
|
1850
|
-
}
|
|
1851
|
-
}
|
|
1852
|
-
return options;
|
|
1853
|
-
}
|
|
1854
|
-
static removeHandlers() {
|
|
1855
|
-
HooksService.#handlers.clear();
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
|
|
1859
1811
|
function jsx(type, props) {
|
|
1860
1812
|
return { props, type };
|
|
1861
1813
|
}
|
|
@@ -2237,6 +2189,25 @@ function watchUsageText() {
|
|
|
2237
2189
|
return jsx(Text, { children: usageText });
|
|
2238
2190
|
}
|
|
2239
2191
|
|
|
2192
|
+
class PluginService {
|
|
2193
|
+
static #handlers = new Map();
|
|
2194
|
+
static addHandler(plugin) {
|
|
2195
|
+
PluginService.#handlers.set(plugin.name, plugin);
|
|
2196
|
+
}
|
|
2197
|
+
static async call(hook, argument, context) {
|
|
2198
|
+
let result = argument;
|
|
2199
|
+
for (const [, plugin] of PluginService.#handlers) {
|
|
2200
|
+
if (hook in plugin) {
|
|
2201
|
+
result = await plugin[hook].call(context, result);
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
return result;
|
|
2205
|
+
}
|
|
2206
|
+
static removeHandlers() {
|
|
2207
|
+
PluginService.#handlers.clear();
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2240
2211
|
class BaseReporter {
|
|
2241
2212
|
resolvedConfig;
|
|
2242
2213
|
constructor(resolvedConfig) {
|
|
@@ -3781,7 +3752,7 @@ class ToRaiseError {
|
|
|
3781
3752
|
if (this.#compiler.isStringLiteralLike(targetNode)) {
|
|
3782
3753
|
return this.#compiler.flattenDiagnosticMessageText(diagnostic.messageText, " ", 0).includes(targetNode.text);
|
|
3783
3754
|
}
|
|
3784
|
-
return Number.parseInt(targetNode.text) === diagnostic.code;
|
|
3755
|
+
return Number.parseInt(targetNode.text, 10) === diagnostic.code;
|
|
3785
3756
|
}
|
|
3786
3757
|
}
|
|
3787
3758
|
|
|
@@ -4126,7 +4097,7 @@ class TaskRunner {
|
|
|
4126
4097
|
class Runner {
|
|
4127
4098
|
#eventEmitter = new EventEmitter();
|
|
4128
4099
|
#resolvedConfig;
|
|
4129
|
-
static version = "3.0.0-beta.
|
|
4100
|
+
static version = "3.0.0-beta.6";
|
|
4130
4101
|
constructor(resolvedConfig) {
|
|
4131
4102
|
this.#resolvedConfig = resolvedConfig;
|
|
4132
4103
|
}
|
|
@@ -4250,11 +4221,11 @@ class Cli {
|
|
|
4250
4221
|
}
|
|
4251
4222
|
continue;
|
|
4252
4223
|
}
|
|
4253
|
-
for (const
|
|
4254
|
-
const
|
|
4255
|
-
|
|
4224
|
+
for (const pluginIdentifier of resolvedConfig.plugins) {
|
|
4225
|
+
const plugin = (await import(pluginIdentifier)).default;
|
|
4226
|
+
PluginService.addHandler(plugin);
|
|
4256
4227
|
}
|
|
4257
|
-
resolvedConfig = await
|
|
4228
|
+
resolvedConfig = await PluginService.call("config", resolvedConfig, {});
|
|
4258
4229
|
if (commandLine.includes("--showConfig")) {
|
|
4259
4230
|
OutputService.writeMessage(formattedText({ ...resolvedConfig, ...environmentOptions }));
|
|
4260
4231
|
continue;
|
|
@@ -4275,7 +4246,7 @@ class Cli {
|
|
|
4275
4246
|
continue;
|
|
4276
4247
|
}
|
|
4277
4248
|
}
|
|
4278
|
-
testFiles = await
|
|
4249
|
+
testFiles = await PluginService.call("select", testFiles, { resolvedConfig });
|
|
4279
4250
|
if (commandLine.includes("--listFiles")) {
|
|
4280
4251
|
OutputService.writeMessage(formattedText(testFiles.map((testFile) => testFile.toString())));
|
|
4281
4252
|
continue;
|
|
@@ -4284,7 +4255,7 @@ class Cli {
|
|
|
4284
4255
|
this.#eventEmitter.removeReporter(setupReporter);
|
|
4285
4256
|
const runner = new Runner(resolvedConfig);
|
|
4286
4257
|
await runner.run(testFiles, cancellationToken);
|
|
4287
|
-
|
|
4258
|
+
PluginService.removeHandlers();
|
|
4288
4259
|
} while (cancellationToken.reason === "configChange");
|
|
4289
4260
|
this.#eventEmitter.removeHandlers();
|
|
4290
4261
|
}
|
|
@@ -4316,4 +4287,4 @@ class Cli {
|
|
|
4316
4287
|
}
|
|
4317
4288
|
}
|
|
4318
4289
|
|
|
4319
|
-
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, EventEmitter, ExitCodeHandler, ExpectResult, ExpectService, FileWatcher,
|
|
4290
|
+
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, EventEmitter, ExitCodeHandler, ExpectResult, ExpectService, FileWatcher, InputService, Line, ListReporter, OptionBrand, OptionGroup, Options, OutputService, Path, PluginService, ProjectResult, ProjectService, Result, ResultCount, ResultHandler, ResultStatus, ResultTiming, Runner, Scribbler, Select, SelectDiagnosticText, SetupReporter, SourceFile, Store, SummaryReporter, TargetResult, Task, TaskResult, TestMember, TestMemberBrand, TestMemberFlags, TestResult, TestTree, Text, Version, WatchReporter, WatchService, Watcher, addsPackageText, defaultOptions, describeNameText, diagnosticText, environmentOptions, fileViewText, formattedText, helpText, summaryText, taskStatusText, testNameText, usesCompilerText, waitingForFileChangesText, watchUsageText };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tstyche",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.6",
|
|
4
4
|
"description": "The Essential Type Testing Tool.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@biomejs/biome": "1.9.4",
|
|
65
65
|
"@rollup/plugin-typescript": "12.1.1",
|
|
66
|
-
"@types/node": "20.
|
|
67
|
-
"@types/react": "18.3.
|
|
66
|
+
"@types/node": "20.17.1",
|
|
67
|
+
"@types/react": "18.3.12",
|
|
68
68
|
"ajv": "8.17.1",
|
|
69
69
|
"cspell": "8.15.4",
|
|
70
70
|
"magic-string": "0.30.12",
|
|
71
71
|
"monocart-coverage-reports": "2.11.1",
|
|
72
72
|
"pretty-ansi": "2.0.0",
|
|
73
|
-
"rollup": "4.24.
|
|
73
|
+
"rollup": "4.24.2",
|
|
74
74
|
"rollup-plugin-dts": "6.1.1",
|
|
75
75
|
"tslib": "2.8.0",
|
|
76
76
|
"typescript": "5.6.3"
|