@esportsplus/typescript 0.29.6 → 0.31.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.
Files changed (70) hide show
  1. package/README.md +11 -3
  2. package/bin/tsc-alias +1 -1
  3. package/build/cli/diagnostics.d.ts +4 -0
  4. package/build/cli/diagnostics.js +90 -0
  5. package/build/cli/tsc.d.ts +10 -2
  6. package/build/cli/tsc.js +352 -51
  7. package/build/compiler/ast.d.ts +7 -5
  8. package/build/compiler/ast.js +6 -6
  9. package/build/compiler/code.d.ts +5 -4
  10. package/build/compiler/code.js +12 -1
  11. package/build/compiler/coordinator.d.ts +17 -7
  12. package/build/compiler/coordinator.js +54 -31
  13. package/build/compiler/imports.d.ts +6 -3
  14. package/build/compiler/imports.js +26 -23
  15. package/build/compiler/index.d.ts +3 -0
  16. package/build/compiler/index.js +1 -0
  17. package/build/compiler/language-service.d.ts +24 -5
  18. package/build/compiler/language-service.js +215 -53
  19. package/build/compiler/plugins/index.d.ts +4 -2
  20. package/build/compiler/plugins/tsc.d.ts +1 -1
  21. package/build/compiler/plugins/vite.d.ts +6 -3
  22. package/build/compiler/plugins/vite.js +12 -7
  23. package/build/compiler/sourcemap.d.ts +50 -0
  24. package/build/compiler/sourcemap.js +247 -0
  25. package/build/compiler/types.d.ts +7 -6
  26. package/build/compiler/uid.d.ts +5 -2
  27. package/build/compiler/uid.js +33 -4
  28. package/build/index.d.ts +1 -1
  29. package/build/index.js +1 -1
  30. package/build/ts.d.ts +3 -0
  31. package/build/ts.js +3 -0
  32. package/package.json +22 -8
  33. package/tsconfig.dev.json +13 -0
  34. package/tsconfig.package.json +4 -1
  35. package/.claude/skills/code-audit/registry-typescript.json +0 -326
  36. package/.editorconfig +0 -9
  37. package/.gitattributes +0 -2
  38. package/.github/dependabot.yml +0 -25
  39. package/.github/workflows/bump.yml +0 -27
  40. package/.github/workflows/dependabot.yml +0 -58
  41. package/.github/workflows/publish.yml +0 -42
  42. package/.github/workflows/templates/bump.yml +0 -9
  43. package/.github/workflows/templates/dependabot.yml +0 -12
  44. package/.github/workflows/templates/publish.yml +0 -16
  45. package/pnpm-workspace.yaml +0 -6
  46. package/src/cli/tsc.ts +0 -235
  47. package/src/compiler/ast.ts +0 -60
  48. package/src/compiler/code.ts +0 -27
  49. package/src/compiler/coordinator.ts +0 -284
  50. package/src/compiler/imports.ts +0 -185
  51. package/src/compiler/index.ts +0 -7
  52. package/src/compiler/language-service.ts +0 -121
  53. package/src/compiler/plugins/index.ts +0 -5
  54. package/src/compiler/plugins/tsc.ts +0 -6
  55. package/src/compiler/plugins/vite.ts +0 -91
  56. package/src/compiler/types.ts +0 -83
  57. package/src/compiler/uid.ts +0 -10
  58. package/src/constants.ts +0 -4
  59. package/src/index.ts +0 -1
  60. package/tests/cli/tsc.test.ts +0 -155
  61. package/tests/compiler/ast.test.ts +0 -131
  62. package/tests/compiler/code.test.ts +0 -73
  63. package/tests/compiler/coordinator.bench.ts +0 -101
  64. package/tests/compiler/coordinator.test.ts +0 -872
  65. package/tests/compiler/imports.test.ts +0 -167
  66. package/tests/compiler/language-service.test.ts +0 -90
  67. package/tests/compiler/plugins.test.ts +0 -172
  68. package/tests/compiler/uid.test.ts +0 -70
  69. package/tsconfig.json +0 -3
  70. package/vitest.config.ts +0 -14
@@ -1,185 +0,0 @@
1
- import { ts } from '~/index';
2
-
3
-
4
- type ImportInfo = {
5
- end: number;
6
- specifiers: Map<string, string>;
7
- // propertyName keys that were imported type-only, whether via a type-only clause
8
- // (`import type { A }`) or an inline specifier (`import { type A }`). Preserved so a rewrite
9
- // re-emits them as type imports instead of runtime imports.
10
- typeOnly: Set<string>;
11
- start: number;
12
- };
13
-
14
- type ModifyOptions = {
15
- add?: Iterable<string>;
16
- namespace?: string;
17
- remove?: Iterable<string>;
18
- };
19
-
20
-
21
- let cache = new WeakMap<ts.SourceFile, Map<string, Set<string>>>();
22
-
23
-
24
- function fileNameMatchesPackage(fileName: string, pkg: string): boolean {
25
- let normalized = fileName.replace(/\\/g, '/'),
26
- marker = `/node_modules/${pkg}/`;
27
-
28
- return normalized.includes(marker);
29
- }
30
-
31
-
32
- // Find all named imports from a specific package
33
- const all = (file: ts.SourceFile, pkg: string): ImportInfo[] => {
34
- let imports: ImportInfo[] = [];
35
-
36
- for (let i = 0, n = file.statements.length; i < n; i++) {
37
- let stmt = file.statements[i];
38
-
39
- if (!ts.isImportDeclaration(stmt)) {
40
- continue;
41
- }
42
-
43
- let moduleSpecifier = stmt.moduleSpecifier;
44
-
45
- if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== pkg) {
46
- continue;
47
- }
48
-
49
- let bindings = stmt.importClause?.namedBindings,
50
- declTypeOnly = stmt.importClause?.isTypeOnly ?? false,
51
- specifiers = new Map<string, string>(),
52
- typeOnly = new Set<string>();
53
-
54
- if (bindings && ts.isNamedImports(bindings)) {
55
- for (let j = 0, m = bindings.elements.length; j < m; j++) {
56
- let element = bindings.elements[j],
57
- name = element.name.text,
58
- propertyName = element.propertyName?.text || name;
59
-
60
- specifiers.set(propertyName, name);
61
-
62
- if (declTypeOnly || element.isTypeOnly) {
63
- typeOnly.add(propertyName);
64
- }
65
- }
66
- }
67
-
68
- imports.push({ end: stmt.end, specifiers, start: stmt.getStart(file), typeOnly });
69
- }
70
-
71
- return imports;
72
- };
73
-
74
- // Check if node's symbol originates from a specific package (with optional symbol name validation)
75
- const includes = (checker: ts.TypeChecker, node: ts.Node, pkg: string, symbolName?: string): boolean => {
76
- if (!ts.isIdentifier(node)) {
77
- return false;
78
- }
79
-
80
- if (symbolName && node.text !== symbolName) {
81
- return false;
82
- }
83
-
84
- let file = node.getSourceFile(),
85
- imports = cache.get(file);
86
-
87
- if (!imports) {
88
- imports = new Map();
89
- cache.set(file, imports);
90
- }
91
-
92
- let names = imports.get(pkg);
93
-
94
- if (!names) {
95
- names = new Set();
96
-
97
- let packages = all(file, pkg);
98
-
99
- for (let i = 0, n = packages.length; i < n; i++) {
100
- for (let [, localName] of packages[i].specifiers) {
101
- names.add(localName);
102
- }
103
- }
104
-
105
- imports.set(pkg, names);
106
- }
107
-
108
- // Fast path: direct import from package
109
- if (names.has(node.text)) {
110
- let symbol = checker.getSymbolAtLocation(node);
111
-
112
- if (symbol) {
113
- let declarations = symbol.getDeclarations();
114
-
115
- if (declarations && declarations.length > 0) {
116
- for (let i = 0, n = declarations.length; i < n; i++) {
117
- let decl = declarations[i];
118
-
119
- if (ts.isImportSpecifier(decl)) {
120
- let importDecl = decl.parent?.parent?.parent;
121
-
122
- if (importDecl && ts.isImportDeclaration(importDecl) && ts.isStringLiteral(importDecl.moduleSpecifier)) {
123
- if (importDecl.moduleSpecifier.text === pkg) {
124
- return true;
125
- }
126
- }
127
- }
128
-
129
- if (fileNameMatchesPackage(decl.getSourceFile().fileName, pkg)) {
130
- return true;
131
- }
132
- }
133
- }
134
- }
135
-
136
- // If checker failed but name matches direct import, trust it
137
- return true;
138
- }
139
-
140
- // Slow path: check for re-exports via aliased symbol
141
- let symbol = checker.getSymbolAtLocation(node);
142
-
143
- if (!symbol) {
144
- return false;
145
- }
146
-
147
- // Check declarations
148
- let declarations = symbol.getDeclarations();
149
-
150
- if (declarations && declarations.length > 0) {
151
- for (let i = 0, n = declarations.length; i < n; i++) {
152
- let decl = declarations[i];
153
-
154
- if (fileNameMatchesPackage(decl.getSourceFile().fileName, pkg)) {
155
- return true;
156
- }
157
- }
158
- }
159
-
160
- // Check aliased symbol for re-exports
161
- try {
162
- let aliased = checker.getAliasedSymbol(symbol);
163
-
164
- if (aliased && aliased !== symbol) {
165
- let aliasedDecls = aliased.getDeclarations();
166
-
167
- if (aliasedDecls) {
168
- for (let i = 0, n = aliasedDecls.length; i < n; i++) {
169
- if (fileNameMatchesPackage(aliasedDecls[i].getSourceFile().fileName, pkg)) {
170
- return true;
171
- }
172
- }
173
- }
174
- }
175
- }
176
- catch {
177
- // getAliasedSymbol can throw for non-alias symbols
178
- }
179
-
180
- return false;
181
- };
182
-
183
-
184
- export default { all, includes };
185
- export type { ImportInfo, ModifyOptions };
@@ -1,7 +0,0 @@
1
- export { default as ast } from './ast';
2
- export { default as code } from './code';
3
- export { default as coordinator } from './coordinator';
4
- export { default as imports } from './imports';
5
- export { default as plugin } from './plugins';
6
- export { default as uid } from './uid';
7
- export type * from './types';
@@ -1,121 +0,0 @@
1
- import { PACKAGE_NAME } from '~/constants';
2
- import { ts } from '~/index';
3
-
4
- import path from 'path';
5
-
6
-
7
- type LanguageServiceEntry = {
8
- contents: Map<string, string>;
9
- host: ts.LanguageServiceHost;
10
- rootFiles: Set<string>;
11
- service: ts.LanguageService;
12
- versions: Map<string, number>;
13
- };
14
-
15
-
16
- let cache = new Map<string, LanguageServiceEntry>();
17
-
18
-
19
- function create(root: string): LanguageServiceEntry {
20
- let tsconfig = ts.findConfigFile(root, ts.sys.fileExists, 'tsconfig.json');
21
-
22
- if (!tsconfig) {
23
- throw new Error(`${PACKAGE_NAME}: tsconfig.json not found`);
24
- }
25
-
26
- let file = ts.readConfigFile(tsconfig, ts.sys.readFile);
27
-
28
- if (file.error) {
29
- throw new Error(`${PACKAGE_NAME}: error reading tsconfig.json ${file.error.messageText}`);
30
- }
31
-
32
- let parsed = ts.parseJsonConfigFileContent(
33
- file.config,
34
- ts.sys,
35
- path.dirname(tsconfig)
36
- );
37
-
38
- if (parsed.errors.length > 0) {
39
- throw new Error(`${PACKAGE_NAME}: error parsing tsconfig.json ${parsed.errors[0].messageText}`);
40
- }
41
-
42
- let contents = new Map<string, string>(),
43
- rootFiles = new Set(parsed.fileNames.map(f => f.replace(/\\/g, '/'))),
44
- versions = new Map<string, number>();
45
-
46
- for (let fileName of rootFiles) {
47
- versions.set(fileName, 0);
48
- }
49
-
50
- let host: ts.LanguageServiceHost = {
51
- fileExists: ts.sys.fileExists,
52
- getCompilationSettings: () => parsed.options,
53
- getCurrentDirectory: () => root,
54
- getDefaultLibFileName: ts.getDefaultLibFilePath,
55
- getScriptFileNames: () => [...rootFiles],
56
- getScriptSnapshot: (fileName: string) => {
57
- let content = contents.get(fileName);
58
-
59
- if (content !== undefined) {
60
- return ts.ScriptSnapshot.fromString(content);
61
- }
62
-
63
- if (!ts.sys.fileExists(fileName)) {
64
- return undefined;
65
- }
66
-
67
- return ts.ScriptSnapshot.fromString(ts.sys.readFile(fileName) || '');
68
- },
69
- getScriptVersion: (fileName: string) => String(versions.get(fileName) || 0),
70
- readFile: ts.sys.readFile
71
- };
72
-
73
- return { contents, host, rootFiles, service: ts.createLanguageService(host), versions };
74
- }
75
-
76
- function getEntry(root: string): LanguageServiceEntry {
77
- let entry = cache.get(root);
78
-
79
- if (!entry) {
80
- entry = create(root);
81
- cache.set(root, entry);
82
- }
83
-
84
- return entry;
85
- }
86
-
87
-
88
- const invalidate = (root: string, fileName: string): void => {
89
- let entry = cache.get(root);
90
-
91
- if (entry) {
92
- let normalized = fileName.replace(/\\/g, '/');
93
-
94
- entry.contents.delete(normalized);
95
- entry.versions.set(normalized, (entry.versions.get(normalized) || 0) + 1);
96
- }
97
- };
98
-
99
- const update = (root: string, fileName: string, content: string): ts.Program => {
100
- let entry = getEntry(root),
101
- normalized = fileName.replace(/\\/g, '/');
102
-
103
- if (!entry.rootFiles.has(normalized)) {
104
- entry.rootFiles.add(normalized);
105
- }
106
-
107
- entry.contents.set(normalized, content);
108
- entry.versions.set(normalized, (entry.versions.get(normalized) || 0) + 1);
109
-
110
- let program = entry.service.getProgram();
111
-
112
- if (!program) {
113
- throw new Error(`${PACKAGE_NAME}: failed to get program from language service`);
114
- }
115
-
116
- return program;
117
- };
118
-
119
-
120
- export default { invalidate, update };
121
- export { invalidate, update };
@@ -1,5 +0,0 @@
1
- import tsc from './tsc';
2
- import vite from './vite';
3
-
4
-
5
- export default { tsc, vite };
@@ -1,6 +0,0 @@
1
- import type { Plugin } from '../types';
2
-
3
-
4
- export default (plugins: Plugin[]) => {
5
- return () => plugins;
6
- };
@@ -1,91 +0,0 @@
1
- import type { Plugin, SharedContext } from '../types';
2
- import type { ResolvedConfig } from 'vite';
3
- import { ts } from '~/index';
4
-
5
- import coordinator from '../coordinator';
6
- import languageService from '../language-service';
7
-
8
-
9
- type VitePlugin = {
10
- configResolved: (config: unknown) => void;
11
- enforce: 'pre';
12
- name: string;
13
- transform: (code: string, id: string) => { code: string; map: null } | null;
14
- watchChange: (id: string) => void;
15
- };
16
-
17
- type VitePluginOptions = {
18
- name: string;
19
- onWatchChange?: () => void;
20
- plugins: Plugin[];
21
- };
22
-
23
-
24
- const DIRECTORY_SEPARATOR_REGEX = /\\/g;
25
-
26
- const FILE_REGEX = /\.[tj]sx?$/;
27
-
28
-
29
- let contexts = new Map<string, SharedContext>();
30
-
31
-
32
- export default ({ name, onWatchChange, plugins }: VitePluginOptions) => {
33
- return ({ root }: { root?: string } = {}): VitePlugin => {
34
- return {
35
- configResolved(config: unknown) {
36
- root ??= (config as ResolvedConfig).root;
37
- },
38
- enforce: 'pre',
39
- name: `${name}/compiler/vite`,
40
- transform(code: string, id: string) {
41
- if (!FILE_REGEX.test(id) || id.includes('node_modules')) {
42
- return null;
43
- }
44
-
45
- try {
46
- let normalizedId = id.replace(DIRECTORY_SEPARATOR_REGEX, '/'),
47
- prog = languageService.update(root || '', normalizedId, code),
48
- sourceFile = prog.getSourceFile(normalizedId);
49
-
50
- if (!sourceFile) {
51
- sourceFile = ts.createSourceFile(normalizedId, code, ts.ScriptTarget.Latest, true);
52
- }
53
-
54
- let key = root || '',
55
- ctx = contexts.get(key);
56
-
57
- if (!ctx) {
58
- ctx = new Map();
59
- contexts.set(key, ctx);
60
- }
61
-
62
- let result = coordinator.transform(
63
- plugins,
64
- code,
65
- sourceFile,
66
- prog,
67
- key,
68
- ctx
69
- );
70
-
71
- if (!result.changed) {
72
- return null;
73
- }
74
-
75
- return { code: result.code, map: null };
76
- }
77
- catch (error) {
78
- console.error(`${name}: error transforming ${id}:`, error);
79
- return null;
80
- }
81
- },
82
- watchChange(id: string) {
83
- if (FILE_REGEX.test(id)) {
84
- onWatchChange?.();
85
- contexts.delete(root || '');
86
- languageService.invalidate(root || '', id);
87
- }
88
- }
89
- };
90
- };
91
- };
@@ -1,83 +0,0 @@
1
- import type ts from 'typescript';
2
-
3
-
4
- type ImportIntent = {
5
- add?: string[];
6
- namespace?: string;
7
- package: string;
8
- remove?: string[];
9
- };
10
-
11
- type Plugin = {
12
- /**
13
- * Optional patterns for quick-check optimization.
14
- * If provided, transform() is only called when source contains at least one pattern.
15
- */
16
- patterns?: string[];
17
-
18
- /**
19
- * Transform a source file, returning replacement intents.
20
- * Called with fresh AST - positions are always accurate.
21
- */
22
- transform: (ctx: TransformContext) => TransformResult;
23
- };
24
-
25
- type PluginFactory = (options?: Record<string, unknown>) => Plugin;
26
-
27
- type Range = {
28
- end: number;
29
- start: number;
30
- };
31
-
32
- type Replacement = Range & {
33
- newText: string;
34
- };
35
-
36
- type ReplacementIntent = {
37
- /**
38
- * Generator function that produces the replacement text.
39
- * Called at apply-time with current sourceFile for accurate positions.
40
- */
41
- generate: (sourceFile: ts.SourceFile) => string;
42
-
43
- /**
44
- * AST node to replace. Position resolved at apply-time.
45
- */
46
- node: ts.Node;
47
- };
48
-
49
- type SharedContext = Map<string, unknown>;
50
-
51
- type TransformContext = {
52
- checker: ts.TypeChecker;
53
- code: string;
54
- program: ts.Program;
55
- shared: SharedContext;
56
- sourceFile: ts.SourceFile;
57
- };
58
-
59
- type TransformResult = {
60
- /**
61
- * Import modifications to apply after replacements.
62
- */
63
- imports?: ImportIntent[];
64
-
65
- /**
66
- * Code to prepend after imports (e.g., generated classes, template factories).
67
- */
68
- prepend?: string[];
69
-
70
- /**
71
- * Replacement intents - node references with generator functions.
72
- */
73
- replacements?: ReplacementIntent[];
74
- };
75
-
76
-
77
- export type {
78
- ImportIntent,
79
- Plugin, PluginFactory,
80
- Range, Replacement, ReplacementIntent,
81
- SharedContext,
82
- TransformContext, TransformResult
83
- };
@@ -1,10 +0,0 @@
1
- import { uuid } from '@esportsplus/utilities';
2
-
3
-
4
- let i = 0,
5
- namespace = uuid().replace(/[^A-Za-z0-9]/g, '');
6
-
7
-
8
- export default (name: string): string => {
9
- return name + '_' + namespace + (i++).toString(36);
10
- };
package/src/constants.ts DELETED
@@ -1,4 +0,0 @@
1
- const PACKAGE_NAME = '@esportsplus/typescript';
2
-
3
-
4
- export { PACKAGE_NAME };
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default as ts } from 'typescript';
@@ -1,155 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import fs from 'fs';
3
- import os from 'os';
4
- import path from 'path';
5
-
6
- import { isPlugin, loadPlugins, normalizePath, runTscAlias } from '~/cli/tsc';
7
-
8
-
9
- describe('isPlugin', () => {
10
- it('returns true for valid plugin', () => {
11
- expect(isPlugin({ transform: () => {} })).toBe(true);
12
- });
13
-
14
- it('returns false for null', () => {
15
- expect(isPlugin(null)).toBe(false);
16
- });
17
-
18
- it('returns false for empty object', () => {
19
- expect(isPlugin({})).toBe(false);
20
- });
21
-
22
- it('returns false when transform is not a function', () => {
23
- expect(isPlugin({ transform: 'not-fn' })).toBe(false);
24
- });
25
-
26
- it('returns false for primitives', () => {
27
- expect(isPlugin(42)).toBe(false);
28
- expect(isPlugin('str')).toBe(false);
29
- expect(isPlugin(undefined)).toBe(false);
30
- });
31
- });
32
-
33
-
34
- describe('normalizePath', () => {
35
- it('converts backslashes to forward slashes', () => {
36
- let result = normalizePath('C:\\foo\\bar.ts');
37
-
38
- expect(result).not.toContain('\\');
39
- expect(result).toContain('/foo/bar');
40
- });
41
-
42
- it('resolves to absolute path', () => {
43
- let result = normalizePath('relative/file.ts');
44
-
45
- expect(path.isAbsolute(result)).toBe(true);
46
- });
47
- });
48
-
49
-
50
- describe('loadPlugins', () => {
51
- let tmpDir: string;
52
-
53
- beforeEach(() => {
54
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tsc-test-'));
55
- });
56
-
57
- afterEach(() => {
58
- fs.rmSync(tmpDir, { recursive: true, force: true });
59
- });
60
-
61
- it('loads a valid plugin with transform export', async () => {
62
- let pluginFile = 'plugin.mjs';
63
-
64
- fs.writeFileSync(path.join(tmpDir, pluginFile), 'export default { transform: () => ({}) };');
65
-
66
- let plugins = await loadPlugins([{ transform: './' + pluginFile }], tmpDir);
67
-
68
- expect(plugins).toHaveLength(1);
69
- expect(typeof plugins[0].transform).toBe('function');
70
- });
71
-
72
- it('loads a factory function that returns a plugin', async () => {
73
- let pluginFile = 'factory.mjs';
74
-
75
- fs.writeFileSync(path.join(tmpDir, pluginFile), 'export default function() { return { transform: () => ({}) }; };');
76
-
77
- let plugins = await loadPlugins([{ transform: './' + pluginFile }], tmpDir);
78
-
79
- expect(plugins).toHaveLength(1);
80
- expect(typeof plugins[0].transform).toBe('function');
81
- });
82
-
83
- it('loads array of plugins', async () => {
84
- let pluginFile = 'array.mjs';
85
-
86
- fs.writeFileSync(path.join(tmpDir, pluginFile), 'export default [{ transform: () => ({}) }, { transform: () => ({}) }];');
87
-
88
- let plugins = await loadPlugins([{ transform: './' + pluginFile }], tmpDir);
89
-
90
- expect(plugins).toHaveLength(2);
91
- });
92
-
93
- it('skips invalid plugin format with error', async () => {
94
- let pluginFile = 'invalid.mjs';
95
-
96
- fs.writeFileSync(path.join(tmpDir, pluginFile), 'export default { notTransform: true };');
97
-
98
- let spy = vi.spyOn(console, 'error').mockImplementation(() => {});
99
- let plugins = await loadPlugins([{ transform: './' + pluginFile }], tmpDir);
100
-
101
- expect(plugins).toHaveLength(0);
102
- expect(spy).toHaveBeenCalled();
103
- spy.mockRestore();
104
- });
105
-
106
- it('skips invalid array element with error', async () => {
107
- let pluginFile = 'mixed.mjs';
108
-
109
- fs.writeFileSync(path.join(tmpDir, pluginFile), 'export default [{ transform: () => ({}) }, { bad: true }];');
110
-
111
- let spy = vi.spyOn(console, 'error').mockImplementation(() => {});
112
- let plugins = await loadPlugins([{ transform: './' + pluginFile }], tmpDir);
113
-
114
- expect(plugins).toHaveLength(1);
115
- expect(spy).toHaveBeenCalled();
116
- spy.mockRestore();
117
- });
118
-
119
- it('resolves relative paths from root', async () => {
120
- let pluginFile = 'relative.mjs';
121
-
122
- fs.writeFileSync(path.join(tmpDir, pluginFile), 'export default { transform: () => ({}) };');
123
-
124
- let plugins = await loadPlugins([{ transform: './' + pluginFile }], tmpDir);
125
-
126
- expect(plugins).toHaveLength(1);
127
- });
128
- });
129
-
130
-
131
- describe('runTscAlias', () => {
132
- it('returns 0 for --noEmit flag', async () => {
133
- let code = await runTscAlias(['--noEmit']);
134
-
135
- expect(code).toBe(0);
136
- });
137
-
138
- it('returns 0 for --help flag', async () => {
139
- let code = await runTscAlias(['--help']);
140
-
141
- expect(code).toBe(0);
142
- });
143
-
144
- it('returns 0 for --version flag', async () => {
145
- let code = await runTscAlias(['--version']);
146
-
147
- expect(code).toBe(0);
148
- });
149
-
150
- it('returns 0 for -v flag', async () => {
151
- let code = await runTscAlias(['-v']);
152
-
153
- expect(code).toBe(0);
154
- });
155
- });