tstyche 3.0.0-beta.5 → 3.0.0-rc.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.
- package/build/tstyche.d.ts +66 -165
- package/build/tstyche.js +234 -264
- package/package.json +5 -5
package/build/tstyche.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ declare class Diagnostic {
|
|
|
65
65
|
static warning(text: string | Array<string>, origin?: DiagnosticOrigin): Diagnostic;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
type DiagnosticsHandler
|
|
68
|
+
type DiagnosticsHandler<T extends Diagnostic | Array<Diagnostic> = Diagnostic> = (this: void, diagnostics: T) => void;
|
|
69
69
|
|
|
70
70
|
declare enum TestMemberBrand {
|
|
71
71
|
Describe = "describe",
|
|
@@ -130,22 +130,17 @@ declare enum OptionBrand {
|
|
|
130
130
|
List = "list"
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
declare enum OptionGroup {
|
|
134
|
-
CommandLine = 2,
|
|
135
|
-
ConfigFile = 4
|
|
136
|
-
}
|
|
137
|
-
|
|
138
133
|
declare class ConfigDiagnosticText {
|
|
139
|
-
#private;
|
|
140
134
|
static expected(element: string): string;
|
|
141
135
|
static expectsListItemType(optionName: string, optionBrand: OptionBrand): string;
|
|
142
|
-
static expectsValue(optionName: string
|
|
136
|
+
static expectsValue(optionName: string): string;
|
|
143
137
|
static fileDoesNotExist(filePath: string): string;
|
|
144
138
|
static moduleWasNotFound(specifier: string): string;
|
|
145
139
|
static seen(element: string): string;
|
|
146
140
|
static testFileMatchCannotStartWith(segment: string): Array<string>;
|
|
147
|
-
static requiresValueType(optionName: string, optionBrand: OptionBrand
|
|
141
|
+
static requiresValueType(optionName: string, optionBrand: OptionBrand): string;
|
|
148
142
|
static unknownOption(optionName: string): string;
|
|
143
|
+
static usage(optionName: string, optionBrand: OptionBrand): Promise<Array<string>>;
|
|
149
144
|
static versionIsNotSupported(value: string): string;
|
|
150
145
|
static watchCannotBeEnabled(): string;
|
|
151
146
|
}
|
|
@@ -283,12 +278,12 @@ declare class Config {
|
|
|
283
278
|
static resolveConfigFilePath(filePath?: string): string;
|
|
284
279
|
}
|
|
285
280
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
281
|
+
declare enum OptionGroup {
|
|
282
|
+
CommandLine = 2,
|
|
283
|
+
ConfigFile = 4,
|
|
284
|
+
ResolvedConfig = 6
|
|
290
285
|
}
|
|
291
|
-
|
|
286
|
+
|
|
292
287
|
interface BaseOptionDefinition {
|
|
293
288
|
brand: OptionBrand;
|
|
294
289
|
description: string;
|
|
@@ -298,13 +293,21 @@ interface BaseOptionDefinition {
|
|
|
298
293
|
interface PrimitiveTypeOptionDefinition extends BaseOptionDefinition {
|
|
299
294
|
brand: OptionBrand.String | OptionBrand.Number | OptionBrand.Boolean | OptionBrand.BareTrue;
|
|
300
295
|
}
|
|
296
|
+
interface ItemDefinition {
|
|
297
|
+
brand: OptionBrand.String;
|
|
298
|
+
name: string;
|
|
299
|
+
pattern?: string;
|
|
300
|
+
}
|
|
301
301
|
interface ListTypeOptionDefinition extends BaseOptionDefinition {
|
|
302
302
|
brand: OptionBrand.List;
|
|
303
303
|
items: ItemDefinition;
|
|
304
304
|
}
|
|
305
|
+
type OptionDefinition = PrimitiveTypeOptionDefinition | ListTypeOptionDefinition;
|
|
305
306
|
declare class Options {
|
|
306
307
|
#private;
|
|
307
308
|
static for(optionGroup: OptionGroup): Map<string, OptionDefinition>;
|
|
309
|
+
static resolve(optionName: string, optionValue: string, rootPath?: string): string;
|
|
310
|
+
static validate(optionName: string, optionValue: string, optionBrand: OptionBrand, onDiagnostics: DiagnosticsHandler, origin?: DiagnosticOrigin): Promise<void>;
|
|
308
311
|
}
|
|
309
312
|
|
|
310
313
|
declare const defaultOptions: Required<ConfigFileOptions>;
|
|
@@ -335,9 +338,9 @@ interface EnvironmentOptions {
|
|
|
335
338
|
*/
|
|
336
339
|
timeout: number;
|
|
337
340
|
/**
|
|
338
|
-
* The
|
|
341
|
+
* The specifier of the TypeScript module.
|
|
339
342
|
*/
|
|
340
|
-
|
|
343
|
+
typescriptModule: string | undefined;
|
|
341
344
|
}
|
|
342
345
|
|
|
343
346
|
declare const environmentOptions: EnvironmentOptions;
|
|
@@ -549,8 +552,6 @@ declare class EventEmitter {
|
|
|
549
552
|
removeReporters(): void;
|
|
550
553
|
}
|
|
551
554
|
|
|
552
|
-
type ArgumentNode = ts.Expression | ts.TypeNode;
|
|
553
|
-
type DiagnosticsHandler = (diagnostics: Diagnostic | Array<Diagnostic>) => void;
|
|
554
555
|
interface MatchResult {
|
|
555
556
|
explain: () => Array<Diagnostic>;
|
|
556
557
|
isMatch: boolean;
|
|
@@ -565,136 +566,29 @@ interface TypeChecker extends ts.TypeChecker {
|
|
|
565
566
|
};
|
|
566
567
|
}
|
|
567
568
|
|
|
568
|
-
declare class MatchWorker {
|
|
569
|
-
#private;
|
|
570
|
-
assertion: Assertion;
|
|
571
|
-
constructor(compiler: typeof ts, typeChecker: TypeChecker, assertion: Assertion);
|
|
572
|
-
checkIsAssignableTo(sourceNode: ArgumentNode, targetNode: ArgumentNode): boolean;
|
|
573
|
-
checkIsAssignableWith(sourceNode: ArgumentNode, targetNode: ArgumentNode): boolean;
|
|
574
|
-
checkIsIdenticalTo(sourceNode: ArgumentNode, targetNode: ArgumentNode): boolean;
|
|
575
|
-
checkIsSubtype(sourceNode: ArgumentNode, targetNode: ArgumentNode): boolean;
|
|
576
|
-
extendsObjectType(type: ts.Type): boolean;
|
|
577
|
-
getParameterType(signature: ts.Signature, index: number): ts.Type | undefined;
|
|
578
|
-
getSignatures(node: ArgumentNode): Array<ts.Signature>;
|
|
579
|
-
getTypeText(node: ArgumentNode): string;
|
|
580
|
-
getType(node: ArgumentNode): ts.Type;
|
|
581
|
-
isAnyOrNeverType(type: ts.Type): type is ts.StringLiteralType | ts.NumberLiteralType;
|
|
582
|
-
isStringOrNumberLiteralType(type: ts.Type): type is ts.StringLiteralType | ts.NumberLiteralType;
|
|
583
|
-
isObjectType(type: ts.Type): type is ts.ObjectType;
|
|
584
|
-
isUnionType(type: ts.Type): type is ts.UnionType;
|
|
585
|
-
isUniqueSymbolType(type: ts.Type): type is ts.UniqueESSymbolType;
|
|
586
|
-
resolveDiagnosticOrigin(symbol: ts.Symbol, enclosingNode: ts.Node): DiagnosticOrigin;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
declare class PrimitiveTypeMatcher {
|
|
590
|
-
#private;
|
|
591
|
-
constructor(targetTypeFlag: ts.TypeFlags);
|
|
592
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode): MatchResult;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
declare class ToAcceptProps {
|
|
596
|
-
#private;
|
|
597
|
-
constructor(compiler: typeof ts, typeChecker: TypeChecker);
|
|
598
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode, onDiagnostics: DiagnosticsHandler): MatchResult | undefined;
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
declare class ExpectDiagnosticText {
|
|
602
|
-
static argumentOrTypeArgumentMustBeProvided(argumentNameText: string, typeArgumentNameText: string): string;
|
|
603
|
-
static argumentMustBe(argumentNameText: string, expectedText: string): string;
|
|
604
|
-
static argumentMustBeProvided(argumentNameText: string): string;
|
|
605
|
-
static componentAcceptsProps(isTypeNode: boolean): string;
|
|
606
|
-
static componentDoesNotAcceptProps(isTypeNode: boolean): string;
|
|
607
|
-
static matcherIsDeprecated(matcherNameText: string): Array<string>;
|
|
608
|
-
static matcherIsNotSupported(matcherNameText: string): string;
|
|
609
|
-
static overloadGaveTheFollowingError(index: number, count: number, signatureText: string): string;
|
|
610
|
-
static raisedTypeError(count?: number): string;
|
|
611
|
-
static typeArgumentMustBe(argumentNameText: string, expectedText: string): string;
|
|
612
|
-
static typeDidNotRaiseError(isTypeNode: boolean): string;
|
|
613
|
-
static typeDidNotRaiseMatchingError(isTypeNode: boolean): string;
|
|
614
|
-
static typeDoesNotHaveProperty(typeText: string, propertyNameText: string): string;
|
|
615
|
-
static typeDoesMatch(sourceTypeText: string, targetTypeText: string): string;
|
|
616
|
-
static typeDoesNotMatch(sourceTypeText: string, targetTypeText: string): string;
|
|
617
|
-
static typeHasProperty(typeText: string, propertyNameText: string): string;
|
|
618
|
-
static typeIs(typeText: string): string;
|
|
619
|
-
static typeIsAssignableTo(sourceTypeText: string, targetTypeText: string): string;
|
|
620
|
-
static typeIsAssignableWith(sourceTypeText: string, targetTypeText: string): string;
|
|
621
|
-
static typeIsIdenticalTo(sourceTypeText: string, targetTypeText: string): string;
|
|
622
|
-
static typeIsNotAssignableTo(sourceTypeText: string, targetTypeText: string): string;
|
|
623
|
-
static typeIsNotAssignableWith(sourceTypeText: string, targetTypeText: string): string;
|
|
624
|
-
static typeIsNotCompatibleWith(sourceTypeText: string, targetTypeText: string): string;
|
|
625
|
-
static typeIsNotIdenticalTo(sourceTypeText: string, targetTypeText: string): string;
|
|
626
|
-
static typeRaisedError(isTypeNode: boolean, count: number, targetCount: number): string;
|
|
627
|
-
static typeRaisedMatchingError(isTypeNode: boolean): string;
|
|
628
|
-
static typeRequiresProperty(typeText: string, propertyNameText: string): string;
|
|
629
|
-
static typesOfPropertyAreNotCompatible(propertyNameText: string): string;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
declare abstract class RelationMatcherBase {
|
|
633
|
-
abstract explainText(sourceTypeText: string, targetTypeText: string): string;
|
|
634
|
-
abstract explainNotText(sourceTypeText: string, targetTypeText: string): string;
|
|
635
|
-
protected explain(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode): Diagnostic[];
|
|
636
|
-
abstract match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode): MatchResult;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
declare class ToBe extends RelationMatcherBase {
|
|
640
|
-
explainText: typeof ExpectDiagnosticText.typeIsIdenticalTo;
|
|
641
|
-
explainNotText: typeof ExpectDiagnosticText.typeIsNotIdenticalTo;
|
|
642
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode): MatchResult;
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
declare class ToBeAssignableTo extends RelationMatcherBase {
|
|
646
|
-
explainText: typeof ExpectDiagnosticText.typeIsAssignableTo;
|
|
647
|
-
explainNotText: typeof ExpectDiagnosticText.typeIsNotAssignableTo;
|
|
648
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode): MatchResult;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
declare class ToBeAssignableWith extends RelationMatcherBase {
|
|
652
|
-
explainText: typeof ExpectDiagnosticText.typeIsAssignableWith;
|
|
653
|
-
explainNotText: typeof ExpectDiagnosticText.typeIsNotAssignableWith;
|
|
654
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode): MatchResult;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
declare class ToHaveProperty {
|
|
658
|
-
#private;
|
|
659
|
-
constructor(compiler: typeof ts);
|
|
660
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode, onDiagnostics: DiagnosticsHandler): MatchResult | undefined;
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
declare class ToMatch extends RelationMatcherBase {
|
|
664
|
-
explainText: typeof ExpectDiagnosticText.typeDoesMatch;
|
|
665
|
-
explainNotText: typeof ExpectDiagnosticText.typeDoesNotMatch;
|
|
666
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNode: ArgumentNode): MatchResult;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
declare class ToRaiseError {
|
|
670
|
-
#private;
|
|
671
|
-
constructor(compiler: typeof ts);
|
|
672
|
-
match(matchWorker: MatchWorker, sourceNode: ArgumentNode, targetNodes: Array<ArgumentNode>, onDiagnostics: DiagnosticsHandler): MatchResult | undefined;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
569
|
declare class ExpectService {
|
|
676
570
|
#private;
|
|
677
|
-
toAcceptProps
|
|
678
|
-
toBe
|
|
679
|
-
toBeAny
|
|
680
|
-
toBeAssignableTo
|
|
681
|
-
toBeAssignableWith
|
|
682
|
-
toBeBigInt
|
|
683
|
-
toBeBoolean
|
|
684
|
-
toBeNever
|
|
685
|
-
toBeNull
|
|
686
|
-
toBeNumber
|
|
687
|
-
toBeString
|
|
688
|
-
toBeSymbol
|
|
689
|
-
toBeUndefined
|
|
690
|
-
toBeUniqueSymbol
|
|
691
|
-
toBeUnknown
|
|
692
|
-
toBeVoid
|
|
693
|
-
toHaveProperty
|
|
694
|
-
toMatch
|
|
695
|
-
toRaiseError
|
|
571
|
+
private toAcceptProps;
|
|
572
|
+
private toBe;
|
|
573
|
+
private toBeAny;
|
|
574
|
+
private toBeAssignableTo;
|
|
575
|
+
private toBeAssignableWith;
|
|
576
|
+
private toBeBigInt;
|
|
577
|
+
private toBeBoolean;
|
|
578
|
+
private toBeNever;
|
|
579
|
+
private toBeNull;
|
|
580
|
+
private toBeNumber;
|
|
581
|
+
private toBeString;
|
|
582
|
+
private toBeSymbol;
|
|
583
|
+
private toBeUndefined;
|
|
584
|
+
private toBeUniqueSymbol;
|
|
585
|
+
private toBeUnknown;
|
|
586
|
+
private toBeVoid;
|
|
587
|
+
private toHaveProperty;
|
|
588
|
+
private toMatch;
|
|
589
|
+
private toRaiseError;
|
|
696
590
|
constructor(compiler: typeof ts, typeChecker: TypeChecker);
|
|
697
|
-
match(assertion: Assertion, onDiagnostics: DiagnosticsHandler): MatchResult | undefined;
|
|
591
|
+
match(assertion: Assertion, onDiagnostics: DiagnosticsHandler<Diagnostic | Array<Diagnostic>>): MatchResult | undefined;
|
|
698
592
|
}
|
|
699
593
|
|
|
700
594
|
declare class CancellationHandler implements EventHandler {
|
|
@@ -714,25 +608,6 @@ declare class ResultHandler implements EventHandler {
|
|
|
714
608
|
on([event, payload]: Event): void;
|
|
715
609
|
}
|
|
716
610
|
|
|
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
611
|
type InputHandler = (chunk: string) => void;
|
|
737
612
|
declare class InputService {
|
|
738
613
|
#private;
|
|
@@ -849,6 +724,32 @@ declare class Path {
|
|
|
849
724
|
static resolve(...filePaths: Array<string>): string;
|
|
850
725
|
}
|
|
851
726
|
|
|
727
|
+
interface SelectHookContext {
|
|
728
|
+
resolvedConfig: ResolvedConfig;
|
|
729
|
+
}
|
|
730
|
+
interface Plugin {
|
|
731
|
+
/**
|
|
732
|
+
* The name of this plugin.
|
|
733
|
+
*/
|
|
734
|
+
name: string;
|
|
735
|
+
/**
|
|
736
|
+
* Is called after configuration is resolved and allows to modify it.
|
|
737
|
+
*/
|
|
738
|
+
config?: (resolvedConfig: ResolvedConfig) => ResolvedConfig | Promise<ResolvedConfig>;
|
|
739
|
+
/**
|
|
740
|
+
* Is called after test files are selected and allows to modify the list.
|
|
741
|
+
*/
|
|
742
|
+
select?: (this: SelectHookContext, testFiles: Array<string>) => Array<string | URL> | Promise<Array<string | URL>>;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
type Hooks = Required<Omit<Plugin, "name">>;
|
|
746
|
+
declare class PluginService {
|
|
747
|
+
#private;
|
|
748
|
+
static addHandler(plugin: Plugin): void;
|
|
749
|
+
static call<T extends keyof Hooks>(hook: T, argument: Parameters<Hooks[T]>[0], context: ThisParameterType<Hooks[T]>): Promise<Awaited<ReturnType<Hooks[T]>>>;
|
|
750
|
+
static removeHandlers(): void;
|
|
751
|
+
}
|
|
752
|
+
|
|
852
753
|
declare class ProjectService {
|
|
853
754
|
#private;
|
|
854
755
|
constructor(resolvedConfig: ResolvedConfig, compiler: typeof ts);
|
|
@@ -917,4 +818,4 @@ declare class WatchService {
|
|
|
917
818
|
watch(cancellationToken: CancellationToken): AsyncIterable<Array<Task>>;
|
|
918
819
|
}
|
|
919
820
|
|
|
920
|
-
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, type CommandLineOptions, Config, ConfigDiagnosticText, type ConfigFileOptions, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, type DiagnosticsHandler
|
|
821
|
+
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, type CommandLineOptions, Config, ConfigDiagnosticText, type ConfigFileOptions, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, type 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,65 +1,13 @@
|
|
|
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';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
4
|
import vm from 'node:vm';
|
|
7
5
|
import os from 'node:os';
|
|
8
6
|
import process from 'node:process';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { writeFileSync, rmSync, existsSync, watch } from 'node:fs';
|
|
9
9
|
import streamConsumers from 'node:stream/consumers';
|
|
10
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
|
-
}
|
|
62
|
-
|
|
63
11
|
class DiagnosticOrigin {
|
|
64
12
|
assertion;
|
|
65
13
|
end;
|
|
@@ -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 {
|
|
@@ -249,7 +154,7 @@ class Environment {
|
|
|
249
154
|
npmRegistry: Environment.#resolveNpmRegistry(),
|
|
250
155
|
storePath: Environment.#resolveStorePath(),
|
|
251
156
|
timeout: Environment.#resolveTimeout(),
|
|
252
|
-
|
|
157
|
+
typescriptModule: Environment.#resolveTypeScriptModule(),
|
|
253
158
|
};
|
|
254
159
|
}
|
|
255
160
|
static #resolveIsCi() {
|
|
@@ -300,23 +205,66 @@ class Environment {
|
|
|
300
205
|
}
|
|
301
206
|
return 30;
|
|
302
207
|
}
|
|
303
|
-
static #
|
|
208
|
+
static #resolveTypeScriptModule() {
|
|
304
209
|
let specifier = "typescript";
|
|
305
|
-
if (process.env["
|
|
306
|
-
specifier = process.env["
|
|
210
|
+
if (process.env["TSTYCHE_TYPESCRIPT_MODULE"] != null) {
|
|
211
|
+
specifier = process.env["TSTYCHE_TYPESCRIPT_MODULE"];
|
|
307
212
|
}
|
|
308
|
-
let
|
|
213
|
+
let resolvedModule;
|
|
309
214
|
try {
|
|
310
|
-
|
|
215
|
+
resolvedModule = import.meta.resolve(specifier);
|
|
311
216
|
}
|
|
312
217
|
catch {
|
|
313
218
|
}
|
|
314
|
-
return
|
|
219
|
+
return resolvedModule;
|
|
315
220
|
}
|
|
316
221
|
}
|
|
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);
|
|
@@ -724,8 +672,8 @@ class Store {
|
|
|
724
672
|
return compilerInstance;
|
|
725
673
|
}
|
|
726
674
|
let modulePath;
|
|
727
|
-
if (tag === "current" && environmentOptions.
|
|
728
|
-
modulePath = environmentOptions.
|
|
675
|
+
if (tag === "current" && environmentOptions.typescriptModule != null) {
|
|
676
|
+
modulePath = fileURLToPath(environmentOptions.typescriptModule);
|
|
729
677
|
}
|
|
730
678
|
else {
|
|
731
679
|
await Store.open();
|
|
@@ -793,7 +741,7 @@ class Store {
|
|
|
793
741
|
}
|
|
794
742
|
static async validateTag(tag) {
|
|
795
743
|
if (tag === "current") {
|
|
796
|
-
return environmentOptions.
|
|
744
|
+
return environmentOptions.typescriptModule != null;
|
|
797
745
|
}
|
|
798
746
|
await Store.open();
|
|
799
747
|
if (Store.#manifest?.isOutdated({ ageTolerance: 60 }) &&
|
|
@@ -809,90 +757,64 @@ class Store {
|
|
|
809
757
|
}
|
|
810
758
|
}
|
|
811
759
|
|
|
812
|
-
class
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
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) {
|
|
768
|
+
return `Option '${optionName}' expects a value.`;
|
|
769
|
+
}
|
|
770
|
+
static fileDoesNotExist(filePath) {
|
|
771
|
+
return `The specified path '${filePath}' does not exist.`;
|
|
772
|
+
}
|
|
773
|
+
static moduleWasNotFound(specifier) {
|
|
774
|
+
return `The specified module '${specifier}' was not found.`;
|
|
775
|
+
}
|
|
776
|
+
static seen(element) {
|
|
777
|
+
return `The ${element} was seen here.`;
|
|
778
|
+
}
|
|
779
|
+
static testFileMatchCannotStartWith(segment) {
|
|
780
|
+
return [
|
|
781
|
+
`A test file match pattern cannot start with '${segment}'.`,
|
|
782
|
+
"The test files are only collected within the 'rootPath' directory.",
|
|
783
|
+
];
|
|
784
|
+
}
|
|
785
|
+
static requiresValueType(optionName, optionBrand) {
|
|
786
|
+
return `Option '${optionName}' requires a value of type ${optionBrand}.`;
|
|
787
|
+
}
|
|
788
|
+
static unknownOption(optionName) {
|
|
789
|
+
return `Unknown option '${optionName}'.`;
|
|
790
|
+
}
|
|
791
|
+
static async usage(optionName, optionBrand) {
|
|
792
|
+
switch (optionName.startsWith("--") ? optionName.slice(2) : optionName) {
|
|
820
793
|
case "target": {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
break;
|
|
794
|
+
const text = [];
|
|
795
|
+
if (optionName.startsWith("--")) {
|
|
796
|
+
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'.");
|
|
797
|
+
}
|
|
798
|
+
else {
|
|
799
|
+
text.push("Item of the 'target' list must be a supported version tag.");
|
|
828
800
|
}
|
|
829
801
|
const supportedTags = await Store.getSupportedTags();
|
|
830
802
|
if (supportedTags != null) {
|
|
831
|
-
|
|
803
|
+
text.push(`Supported tags: ${["'", supportedTags.join("', '"), "'"].join("")}.`);
|
|
832
804
|
}
|
|
833
|
-
|
|
805
|
+
return text;
|
|
834
806
|
}
|
|
835
|
-
default:
|
|
836
|
-
usageText.push(ConfigDiagnosticText.requiresValueType(optionName, optionBrand, this.#optionGroup));
|
|
837
807
|
}
|
|
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);
|
|
808
|
+
return [ConfigDiagnosticText.requiresValueType(optionName, optionBrand)];
|
|
850
809
|
}
|
|
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;
|
|
810
|
+
static versionIsNotSupported(value) {
|
|
811
|
+
if (value === "current") {
|
|
812
|
+
return "Cannot use 'current' as a target. Failed to resolve the installed TypeScript module.";
|
|
895
813
|
}
|
|
814
|
+
return `TypeScript version '${value}' is not supported.`;
|
|
815
|
+
}
|
|
816
|
+
static watchCannotBeEnabled() {
|
|
817
|
+
return "Watch mode cannot be enabled in continuous integration environment.";
|
|
896
818
|
}
|
|
897
819
|
}
|
|
898
820
|
|
|
@@ -1039,29 +961,98 @@ class Options {
|
|
|
1039
961
|
}
|
|
1040
962
|
return definitionMap;
|
|
1041
963
|
}
|
|
964
|
+
static resolve(optionName, optionValue, rootPath = ".") {
|
|
965
|
+
switch (optionName.startsWith("--") ? optionName.slice(2) : optionName) {
|
|
966
|
+
case "config":
|
|
967
|
+
case "rootPath":
|
|
968
|
+
case "tsconfig":
|
|
969
|
+
if (optionName.endsWith("tsconfig") && ["findup", "ignore"].includes(optionValue)) {
|
|
970
|
+
break;
|
|
971
|
+
}
|
|
972
|
+
optionValue = Path.resolve(rootPath, optionValue);
|
|
973
|
+
break;
|
|
974
|
+
case "plugins":
|
|
975
|
+
case "reporters":
|
|
976
|
+
if (optionName.endsWith("reporters") && ["list", "summary"].includes(optionValue)) {
|
|
977
|
+
break;
|
|
978
|
+
}
|
|
979
|
+
try {
|
|
980
|
+
if (optionValue.startsWith(".")) {
|
|
981
|
+
optionValue = pathToFileURL(Path.relative(".", Path.resolve(rootPath, optionValue))).toString();
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
optionValue = import.meta.resolve(optionValue);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
catch {
|
|
988
|
+
}
|
|
989
|
+
break;
|
|
990
|
+
}
|
|
991
|
+
return optionValue;
|
|
992
|
+
}
|
|
993
|
+
static async validate(optionName, optionValue, optionBrand, onDiagnostics, origin) {
|
|
994
|
+
switch (optionName.startsWith("--") ? optionName.slice(2) : optionName) {
|
|
995
|
+
case "config":
|
|
996
|
+
case "rootPath":
|
|
997
|
+
case "tsconfig":
|
|
998
|
+
if (optionName.endsWith("tsconfig") && ["findup", "ignore"].includes(optionValue)) {
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
if (existsSync(optionValue)) {
|
|
1002
|
+
break;
|
|
1003
|
+
}
|
|
1004
|
+
onDiagnostics(Diagnostic.error(ConfigDiagnosticText.fileDoesNotExist(optionValue), origin));
|
|
1005
|
+
break;
|
|
1006
|
+
case "plugins":
|
|
1007
|
+
case "reporters":
|
|
1008
|
+
if (optionName.endsWith("reporters") && ["list", "summary"].includes(optionValue)) {
|
|
1009
|
+
break;
|
|
1010
|
+
}
|
|
1011
|
+
if (optionValue.startsWith("file:") && existsSync(new URL(optionValue))) {
|
|
1012
|
+
break;
|
|
1013
|
+
}
|
|
1014
|
+
onDiagnostics(Diagnostic.error(ConfigDiagnosticText.moduleWasNotFound(optionValue), origin));
|
|
1015
|
+
break;
|
|
1016
|
+
case "target":
|
|
1017
|
+
if ((await Store.validateTag(optionValue)) === false) {
|
|
1018
|
+
onDiagnostics(Diagnostic.error([
|
|
1019
|
+
ConfigDiagnosticText.versionIsNotSupported(optionValue),
|
|
1020
|
+
await ConfigDiagnosticText.usage(optionName, optionBrand),
|
|
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
|
-
async #onExpectsValue(
|
|
1051
|
+
async #onExpectsValue(optionName, optionBrand) {
|
|
1061
1052
|
const text = [
|
|
1062
|
-
ConfigDiagnosticText.expectsValue(
|
|
1063
|
-
|
|
1064
|
-
];
|
|
1053
|
+
ConfigDiagnosticText.expectsValue(optionName),
|
|
1054
|
+
await ConfigDiagnosticText.usage(optionName, optionBrand),
|
|
1055
|
+
].flat();
|
|
1065
1056
|
this.#onDiagnostics(Diagnostic.error(text));
|
|
1066
1057
|
}
|
|
1067
1058
|
async parse(commandLineArgs) {
|
|
@@ -1070,10 +1061,9 @@ class CommandLineParser {
|
|
|
1070
1061
|
while (arg != null) {
|
|
1071
1062
|
index++;
|
|
1072
1063
|
if (arg.startsWith("--")) {
|
|
1073
|
-
const
|
|
1074
|
-
const optionDefinition = this.#options.get(optionName);
|
|
1064
|
+
const optionDefinition = this.#options.get(arg.slice(2));
|
|
1075
1065
|
if (optionDefinition) {
|
|
1076
|
-
index = await this.#parseOptionValue(commandLineArgs, index, optionDefinition);
|
|
1066
|
+
index = await this.#parseOptionValue(commandLineArgs, index, arg, optionDefinition);
|
|
1077
1067
|
}
|
|
1078
1068
|
else {
|
|
1079
1069
|
this.#onDiagnostics(Diagnostic.error(ConfigDiagnosticText.unknownOption(arg)));
|
|
@@ -1088,15 +1078,15 @@ class CommandLineParser {
|
|
|
1088
1078
|
arg = commandLineArgs[index];
|
|
1089
1079
|
}
|
|
1090
1080
|
}
|
|
1091
|
-
async #parseOptionValue(commandLineArgs, index, optionDefinition) {
|
|
1081
|
+
async #parseOptionValue(commandLineArgs, index, optionName, optionDefinition) {
|
|
1092
1082
|
let optionValue = this.#resolveOptionValue(commandLineArgs[index]);
|
|
1093
1083
|
switch (optionDefinition.brand) {
|
|
1094
1084
|
case "bareTrue":
|
|
1095
|
-
await
|
|
1085
|
+
await Options.validate(optionName, optionValue, optionDefinition.brand, this.#onDiagnostics);
|
|
1096
1086
|
this.#commandLineOptions[optionDefinition.name] = true;
|
|
1097
1087
|
break;
|
|
1098
1088
|
case "boolean":
|
|
1099
|
-
await
|
|
1089
|
+
await Options.validate(optionName, optionValue, optionDefinition.brand, this.#onDiagnostics);
|
|
1100
1090
|
this.#commandLineOptions[optionDefinition.name] = optionValue !== "false";
|
|
1101
1091
|
if (optionValue === "false" || optionValue === "true") {
|
|
1102
1092
|
index++;
|
|
@@ -1104,39 +1094,29 @@ class CommandLineParser {
|
|
|
1104
1094
|
break;
|
|
1105
1095
|
case "list":
|
|
1106
1096
|
if (optionValue !== "") {
|
|
1107
|
-
|
|
1097
|
+
const optionValues = optionValue
|
|
1108
1098
|
.split(",")
|
|
1109
1099
|
.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
|
-
}
|
|
1100
|
+
.filter((value) => value !== "")
|
|
1101
|
+
.map((value) => Options.resolve(optionName, value));
|
|
1119
1102
|
for (const optionValue of optionValues) {
|
|
1120
|
-
await
|
|
1103
|
+
await Options.validate(optionName, optionValue, optionDefinition.brand, this.#onDiagnostics);
|
|
1121
1104
|
}
|
|
1122
1105
|
this.#commandLineOptions[optionDefinition.name] = optionValues;
|
|
1123
1106
|
index++;
|
|
1124
1107
|
break;
|
|
1125
1108
|
}
|
|
1126
|
-
await this.#onExpectsValue(optionDefinition);
|
|
1109
|
+
await this.#onExpectsValue(optionName, optionDefinition.brand);
|
|
1127
1110
|
break;
|
|
1128
1111
|
case "string":
|
|
1129
1112
|
if (optionValue !== "") {
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
optionValue = Path.resolve(optionValue);
|
|
1133
|
-
}
|
|
1134
|
-
await this.#optionValidator.check(optionDefinition.name, optionValue, optionDefinition.brand);
|
|
1113
|
+
optionValue = Options.resolve(optionName, optionValue);
|
|
1114
|
+
await Options.validate(optionName, optionValue, optionDefinition.brand, this.#onDiagnostics);
|
|
1135
1115
|
this.#commandLineOptions[optionDefinition.name] = optionValue;
|
|
1136
1116
|
index++;
|
|
1137
1117
|
break;
|
|
1138
1118
|
}
|
|
1139
|
-
await this.#onExpectsValue(optionDefinition);
|
|
1119
|
+
await this.#onExpectsValue(optionName, optionDefinition.brand);
|
|
1140
1120
|
break;
|
|
1141
1121
|
}
|
|
1142
1122
|
return index;
|
|
@@ -1279,21 +1259,18 @@ class ConfigFileParser {
|
|
|
1279
1259
|
#jsonScanner;
|
|
1280
1260
|
#onDiagnostics;
|
|
1281
1261
|
#options;
|
|
1282
|
-
#optionGroup = 4;
|
|
1283
|
-
#optionValidator;
|
|
1284
1262
|
#sourceFile;
|
|
1285
1263
|
constructor(configFileOptions, sourceFile, onDiagnostics) {
|
|
1286
1264
|
this.#configFileOptions = configFileOptions;
|
|
1287
1265
|
this.#sourceFile = sourceFile;
|
|
1288
1266
|
this.#onDiagnostics = onDiagnostics;
|
|
1289
|
-
this.#options = Options.for(
|
|
1267
|
+
this.#options = Options.for(4);
|
|
1290
1268
|
this.#jsonScanner = new JsonScanner(this.#sourceFile);
|
|
1291
|
-
this.#optionValidator = new OptionValidator(this.#optionGroup, this.#onDiagnostics);
|
|
1292
1269
|
}
|
|
1293
1270
|
#onRequiresValue(optionDefinition, jsonNode, isListItem) {
|
|
1294
1271
|
const text = isListItem
|
|
1295
1272
|
? ConfigDiagnosticText.expectsListItemType(optionDefinition.name, optionDefinition.brand)
|
|
1296
|
-
: ConfigDiagnosticText.requiresValueType(optionDefinition.name, optionDefinition.brand
|
|
1273
|
+
: ConfigDiagnosticText.requiresValueType(optionDefinition.name, optionDefinition.brand);
|
|
1297
1274
|
this.#onDiagnostics(Diagnostic.error(text, jsonNode.origin));
|
|
1298
1275
|
}
|
|
1299
1276
|
async #parseValue(optionDefinition, isListItem = false) {
|
|
@@ -1316,17 +1293,9 @@ class ConfigFileParser {
|
|
|
1316
1293
|
this.#onRequiresValue(optionDefinition, jsonNode, isListItem);
|
|
1317
1294
|
break;
|
|
1318
1295
|
}
|
|
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);
|
|
1296
|
+
const rootPath = Path.dirname(this.#sourceFile.fileName);
|
|
1297
|
+
optionValue = Options.resolve(optionDefinition.name, optionValue, rootPath);
|
|
1298
|
+
await Options.validate(optionDefinition.name, optionValue, optionDefinition.brand, this.#onDiagnostics, jsonNode.origin);
|
|
1330
1299
|
break;
|
|
1331
1300
|
}
|
|
1332
1301
|
case "list": {
|
|
@@ -1430,14 +1399,14 @@ const defaultOptions = {
|
|
|
1430
1399
|
plugins: [],
|
|
1431
1400
|
reporters: ["list", "summary"],
|
|
1432
1401
|
rootPath: Path.resolve("./"),
|
|
1433
|
-
target: environmentOptions.
|
|
1402
|
+
target: environmentOptions.typescriptModule != null ? ["current"] : ["latest"],
|
|
1434
1403
|
testFileMatch: ["**/*.tst.*", "**/__typetests__/*.test.*", "**/typetests/*.test.*"],
|
|
1435
1404
|
tsconfig: "findup",
|
|
1436
1405
|
};
|
|
1437
1406
|
|
|
1438
1407
|
class Config {
|
|
1439
|
-
static #onDiagnostics(
|
|
1440
|
-
EventEmitter.dispatch(["config:error", { diagnostics: [
|
|
1408
|
+
static #onDiagnostics(diagnostic) {
|
|
1409
|
+
EventEmitter.dispatch(["config:error", { diagnostics: [diagnostic] }]);
|
|
1441
1410
|
}
|
|
1442
1411
|
static async parseCommandLine(commandLine) {
|
|
1443
1412
|
const commandLineOptions = {};
|
|
@@ -1492,6 +1461,7 @@ var OptionGroup;
|
|
|
1492
1461
|
(function (OptionGroup) {
|
|
1493
1462
|
OptionGroup[OptionGroup["CommandLine"] = 2] = "CommandLine";
|
|
1494
1463
|
OptionGroup[OptionGroup["ConfigFile"] = 4] = "ConfigFile";
|
|
1464
|
+
OptionGroup[OptionGroup["ResolvedConfig"] = 6] = "ResolvedConfig";
|
|
1495
1465
|
})(OptionGroup || (OptionGroup = {}));
|
|
1496
1466
|
|
|
1497
1467
|
class CancellationHandler {
|
|
@@ -1837,25 +1807,6 @@ class ResultHandler {
|
|
|
1837
1807
|
}
|
|
1838
1808
|
}
|
|
1839
1809
|
|
|
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
1810
|
function jsx(type, props) {
|
|
1860
1811
|
return { props, type };
|
|
1861
1812
|
}
|
|
@@ -2237,6 +2188,25 @@ function watchUsageText() {
|
|
|
2237
2188
|
return jsx(Text, { children: usageText });
|
|
2238
2189
|
}
|
|
2239
2190
|
|
|
2191
|
+
class PluginService {
|
|
2192
|
+
static #handlers = new Map();
|
|
2193
|
+
static addHandler(plugin) {
|
|
2194
|
+
PluginService.#handlers.set(plugin.name, plugin);
|
|
2195
|
+
}
|
|
2196
|
+
static async call(hook, argument, context) {
|
|
2197
|
+
let result = argument;
|
|
2198
|
+
for (const [, plugin] of PluginService.#handlers) {
|
|
2199
|
+
if (hook in plugin) {
|
|
2200
|
+
result = await plugin[hook].call(context, result);
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
return result;
|
|
2204
|
+
}
|
|
2205
|
+
static removeHandlers() {
|
|
2206
|
+
PluginService.#handlers.clear();
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2240
2210
|
class BaseReporter {
|
|
2241
2211
|
resolvedConfig;
|
|
2242
2212
|
constructor(resolvedConfig) {
|
|
@@ -3781,7 +3751,7 @@ class ToRaiseError {
|
|
|
3781
3751
|
if (this.#compiler.isStringLiteralLike(targetNode)) {
|
|
3782
3752
|
return this.#compiler.flattenDiagnosticMessageText(diagnostic.messageText, " ", 0).includes(targetNode.text);
|
|
3783
3753
|
}
|
|
3784
|
-
return Number.parseInt(targetNode.text) === diagnostic.code;
|
|
3754
|
+
return Number.parseInt(targetNode.text, 10) === diagnostic.code;
|
|
3785
3755
|
}
|
|
3786
3756
|
}
|
|
3787
3757
|
|
|
@@ -4126,7 +4096,7 @@ class TaskRunner {
|
|
|
4126
4096
|
class Runner {
|
|
4127
4097
|
#eventEmitter = new EventEmitter();
|
|
4128
4098
|
#resolvedConfig;
|
|
4129
|
-
static version = "3.0.0-
|
|
4099
|
+
static version = "3.0.0-rc.0";
|
|
4130
4100
|
constructor(resolvedConfig) {
|
|
4131
4101
|
this.#resolvedConfig = resolvedConfig;
|
|
4132
4102
|
}
|
|
@@ -4250,11 +4220,11 @@ class Cli {
|
|
|
4250
4220
|
}
|
|
4251
4221
|
continue;
|
|
4252
4222
|
}
|
|
4253
|
-
for (const
|
|
4254
|
-
const
|
|
4255
|
-
|
|
4223
|
+
for (const pluginSpecifier of resolvedConfig.plugins) {
|
|
4224
|
+
const plugin = (await import(pluginSpecifier)).default;
|
|
4225
|
+
PluginService.addHandler(plugin);
|
|
4256
4226
|
}
|
|
4257
|
-
resolvedConfig = await
|
|
4227
|
+
resolvedConfig = await PluginService.call("config", resolvedConfig, {});
|
|
4258
4228
|
if (commandLine.includes("--showConfig")) {
|
|
4259
4229
|
OutputService.writeMessage(formattedText({ ...resolvedConfig, ...environmentOptions }));
|
|
4260
4230
|
continue;
|
|
@@ -4275,7 +4245,7 @@ class Cli {
|
|
|
4275
4245
|
continue;
|
|
4276
4246
|
}
|
|
4277
4247
|
}
|
|
4278
|
-
testFiles = await
|
|
4248
|
+
testFiles = await PluginService.call("select", testFiles, { resolvedConfig });
|
|
4279
4249
|
if (commandLine.includes("--listFiles")) {
|
|
4280
4250
|
OutputService.writeMessage(formattedText(testFiles.map((testFile) => testFile.toString())));
|
|
4281
4251
|
continue;
|
|
@@ -4284,7 +4254,7 @@ class Cli {
|
|
|
4284
4254
|
this.#eventEmitter.removeReporter(setupReporter);
|
|
4285
4255
|
const runner = new Runner(resolvedConfig);
|
|
4286
4256
|
await runner.run(testFiles, cancellationToken);
|
|
4287
|
-
|
|
4257
|
+
PluginService.removeHandlers();
|
|
4288
4258
|
} while (cancellationToken.reason === "configChange");
|
|
4289
4259
|
this.#eventEmitter.removeHandlers();
|
|
4290
4260
|
}
|
|
@@ -4316,4 +4286,4 @@ class Cli {
|
|
|
4316
4286
|
}
|
|
4317
4287
|
}
|
|
4318
4288
|
|
|
4319
|
-
export { Assertion, BaseReporter, CancellationHandler, CancellationReason, CancellationToken, Cli, CollectService, Color, Config, ConfigDiagnosticText, DescribeResult, Diagnostic, DiagnosticCategory, DiagnosticOrigin, EventEmitter, ExitCodeHandler, ExpectResult, ExpectService, FileWatcher,
|
|
4289
|
+
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-
|
|
3
|
+
"version": "3.0.0-rc.0",
|
|
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": "
|
|
67
|
-
"@types/react": "18.3.
|
|
66
|
+
"@types/node": "22.8.4",
|
|
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.3",
|
|
74
74
|
"rollup-plugin-dts": "6.1.1",
|
|
75
75
|
"tslib": "2.8.0",
|
|
76
76
|
"typescript": "5.6.3"
|
|
@@ -85,6 +85,6 @@
|
|
|
85
85
|
},
|
|
86
86
|
"packageManager": "yarn@4.5.1",
|
|
87
87
|
"engines": {
|
|
88
|
-
"node": ">=18.
|
|
88
|
+
"node": ">=18.19"
|
|
89
89
|
}
|
|
90
90
|
}
|