@esportsplus/typescript 0.28.5 → 0.29.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/cli/tsc.js CHANGED
@@ -22,7 +22,7 @@ async function build(config, tsconfig, pluginConfigs) {
22
22
  if (!sourceFile) {
23
23
  continue;
24
24
  }
25
- let result = coordinator.transform(plugins, sourceFile.getFullText(), sourceFile, program, shared);
25
+ let result = coordinator.transform(plugins, sourceFile.getFullText(), sourceFile, program, root, shared);
26
26
  if (result.changed) {
27
27
  transformedFiles.set(normalizePath(fileName), result.code);
28
28
  }
@@ -6,8 +6,7 @@ type CoordinatorResult = {
6
6
  sourceFile: ts.SourceFile;
7
7
  };
8
8
  declare const _default: {
9
- createPatchedProgram: (baseProgram: ts.Program, fileName: string, newContent: string) => ts.Program;
10
- transform: (plugins: Plugin[], code: string, file: ts.SourceFile, program: ts.Program, shared: SharedContext) => {
9
+ transform: (plugins: Plugin[], code: string, file: ts.SourceFile, program: ts.Program, root: string, shared: SharedContext) => {
11
10
  changed: boolean;
12
11
  code: string;
13
12
  sourceFile: ts.SourceFile;
@@ -1,5 +1,6 @@
1
1
  import { ts } from '../index.js';
2
2
  import imports from './imports.js';
3
+ import languageService from './language-service.js';
3
4
  function applyImports(code, file, intents) {
4
5
  for (let i = 0, n = intents.length; i < n; i++) {
5
6
  let intent = intents[i];
@@ -111,25 +112,11 @@ function replaceReverse(code, replacements) {
111
112
  }
112
113
  return result;
113
114
  }
114
- const createPatchedProgram = (baseProgram, fileName, newContent) => {
115
- let baseHost = ts.createCompilerHost(baseProgram.getCompilerOptions()), options = baseProgram.getCompilerOptions();
116
- return ts.createProgram(baseProgram.getRootFileNames(), options, {
117
- ...baseHost,
118
- getSourceFile: (name, languageVersion) => {
119
- if (name === fileName || name === fileName.replace(/\\/g, '/')) {
120
- return ts.createSourceFile(name, newContent, languageVersion, true);
121
- }
122
- return baseProgram.getSourceFile(name) ?? baseHost.getSourceFile(name, languageVersion);
123
- },
124
- fileExists: (name) => baseHost.fileExists(name),
125
- readFile: (name) => name === fileName ? newContent : baseHost.readFile(name)
126
- }, baseProgram);
127
- };
128
- const transform = (plugins, code, file, program, shared) => {
115
+ const transform = (plugins, code, file, program, root, shared) => {
129
116
  if (plugins.length === 0) {
130
117
  return { changed: false, code, sourceFile: file };
131
118
  }
132
- let changed = false, currentCode = code, currentFile = file, currentProgram = program, fileName = file.fileName;
119
+ let changed = false, currentCode = code, currentFile = file, currentProgram = program, fileName = file.fileName, last = plugins.length - 1;
133
120
  for (let i = 0, n = plugins.length; i < n; i++) {
134
121
  let plugin = plugins[i];
135
122
  if (plugin.patterns && !hasPattern(currentCode, plugin.patterns)) {
@@ -156,8 +143,8 @@ const transform = (plugins, code, file, program, shared) => {
156
143
  }
157
144
  if (pluginChanged) {
158
145
  changed = true;
159
- if (i < n - 1) {
160
- currentProgram = createPatchedProgram(program, fileName, currentCode);
146
+ if (i < last) {
147
+ currentProgram = languageService.update(root, fileName, currentCode);
161
148
  currentFile = currentProgram.getSourceFile(fileName) ||
162
149
  ts.createSourceFile(fileName, currentCode, file.languageVersion, true);
163
150
  }
@@ -168,4 +155,4 @@ const transform = (plugins, code, file, program, shared) => {
168
155
  }
169
156
  return { changed, code: currentCode, sourceFile: currentFile };
170
157
  };
171
- export default { createPatchedProgram, transform };
158
+ export default { transform };
@@ -0,0 +1,12 @@
1
+ import ts from 'typescript';
2
+ declare const get: (root: string) => ts.Program;
3
+ declare const invalidate: (root: string, fileName: string) => void;
4
+ declare const update: (root: string, fileName: string, content: string) => ts.Program;
5
+ declare const _default: {
6
+ delete: (root: string) => void;
7
+ get: (root: string) => ts.Program;
8
+ invalidate: (root: string, fileName: string) => void;
9
+ update: (root: string, fileName: string, content: string) => ts.Program;
10
+ };
11
+ export default _default;
12
+ export { get, invalidate, update };
@@ -0,0 +1,83 @@
1
+ import path from 'path';
2
+ import ts from 'typescript';
3
+ import { PACKAGE_NAME } from '../constants.js';
4
+ let cache = new Map();
5
+ function create(root) {
6
+ let tsconfig = ts.findConfigFile(root, ts.sys.fileExists, 'tsconfig.json');
7
+ if (!tsconfig) {
8
+ throw new Error(`${PACKAGE_NAME}: tsconfig.json not found`);
9
+ }
10
+ let file = ts.readConfigFile(tsconfig, ts.sys.readFile);
11
+ if (file.error) {
12
+ throw new Error(`${PACKAGE_NAME}: error reading tsconfig.json ${file.error.messageText}`);
13
+ }
14
+ let parsed = ts.parseJsonConfigFileContent(file.config, ts.sys, path.dirname(tsconfig));
15
+ if (parsed.errors.length > 0) {
16
+ throw new Error(`${PACKAGE_NAME}: error parsing tsconfig.json ${parsed.errors[0].messageText}`);
17
+ }
18
+ let contents = new Map(), rootFiles = new Set(parsed.fileNames.map(f => f.replace(/\\/g, '/'))), versions = new Map();
19
+ for (let fileName of rootFiles) {
20
+ versions.set(fileName, 0);
21
+ }
22
+ let host = {
23
+ fileExists: ts.sys.fileExists,
24
+ getCompilationSettings: () => parsed.options,
25
+ getCurrentDirectory: () => root,
26
+ getDefaultLibFileName: ts.getDefaultLibFilePath,
27
+ getScriptFileNames: () => [...rootFiles],
28
+ getScriptSnapshot: (fileName) => {
29
+ let content = contents.get(fileName);
30
+ if (content !== undefined) {
31
+ return ts.ScriptSnapshot.fromString(content);
32
+ }
33
+ if (!ts.sys.fileExists(fileName)) {
34
+ return undefined;
35
+ }
36
+ return ts.ScriptSnapshot.fromString(ts.sys.readFile(fileName) || '');
37
+ },
38
+ getScriptVersion: (fileName) => String(versions.get(fileName) || 0),
39
+ readFile: ts.sys.readFile
40
+ };
41
+ return { contents, host, rootFiles, service: ts.createLanguageService(host), versions };
42
+ }
43
+ function getEntry(root) {
44
+ let entry = cache.get(root);
45
+ if (!entry) {
46
+ entry = create(root);
47
+ cache.set(root, entry);
48
+ }
49
+ return entry;
50
+ }
51
+ const del = (root) => {
52
+ cache.delete(root);
53
+ };
54
+ const get = (root) => {
55
+ let entry = getEntry(root), program = entry.service.getProgram();
56
+ if (!program) {
57
+ throw new Error(`${PACKAGE_NAME}: failed to get program from language service`);
58
+ }
59
+ return program;
60
+ };
61
+ const invalidate = (root, fileName) => {
62
+ let entry = cache.get(root);
63
+ if (entry) {
64
+ let normalized = fileName.replace(/\\/g, '/');
65
+ entry.contents.delete(normalized);
66
+ entry.versions.set(normalized, (entry.versions.get(normalized) || 0) + 1);
67
+ }
68
+ };
69
+ const update = (root, fileName, content) => {
70
+ let entry = getEntry(root), normalized = fileName.replace(/\\/g, '/');
71
+ if (!entry.rootFiles.has(normalized)) {
72
+ entry.rootFiles.add(normalized);
73
+ }
74
+ entry.contents.set(normalized, content);
75
+ entry.versions.set(normalized, (entry.versions.get(normalized) || 0) + 1);
76
+ let program = entry.service.getProgram();
77
+ if (!program) {
78
+ throw new Error(`${PACKAGE_NAME}: failed to get program from language service`);
79
+ }
80
+ return program;
81
+ };
82
+ export default { delete: del, get, invalidate, update };
83
+ export { get, invalidate, update };
@@ -1,9 +1,8 @@
1
1
  import { ts } from '../../index.js';
2
2
  import coordinator from '../coordinator.js';
3
- import program from '../program.js';
4
- const FILE_REGEX = /\.[tj]sx?$/;
3
+ import languageService from '../language-service.js';
5
4
  const DIRECTORY_SEPARATOR_REGEX = /\\/g;
6
- const LINE_ENDINGS_REGEX = /\r\n/g;
5
+ const FILE_REGEX = /\.[tj]sx?$/;
7
6
  let contexts = new Map();
8
7
  export default ({ name, onWatchChange, plugins }) => {
9
8
  return ({ root } = {}) => {
@@ -18,15 +17,11 @@ export default ({ name, onWatchChange, plugins }) => {
18
17
  return null;
19
18
  }
20
19
  try {
21
- let normalizedId = id.replace(DIRECTORY_SEPARATOR_REGEX, '/'), prog = program.get(root || ''), sourceFile = prog.getSourceFile(normalizedId) || prog.getSourceFile(id);
22
- if (sourceFile && sourceFile.getText().replace(LINE_ENDINGS_REGEX, '\n') !== code.replace(LINE_ENDINGS_REGEX, '\n')) {
23
- sourceFile = undefined;
24
- }
20
+ let normalizedId = id.replace(DIRECTORY_SEPARATOR_REGEX, '/'), prog = languageService.update(root || '', normalizedId, code), sourceFile = prog.getSourceFile(normalizedId);
25
21
  if (!sourceFile) {
26
- prog = coordinator.createPatchedProgram(prog, normalizedId, code);
27
- sourceFile = prog.getSourceFile(normalizedId) || ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true);
22
+ sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true);
28
23
  }
29
- let result = coordinator.transform(plugins, code, sourceFile, prog, contexts.get(root || '') ?? contexts.set(root || '', new Map()).get(root || ''));
24
+ let result = coordinator.transform(plugins, code, sourceFile, prog, root || '', contexts.get(root || '') ?? contexts.set(root || '', new Map()).get(root || ''));
30
25
  if (!result.changed) {
31
26
  return null;
32
27
  }
@@ -41,7 +36,7 @@ export default ({ name, onWatchChange, plugins }) => {
41
36
  if (FILE_REGEX.test(id)) {
42
37
  onWatchChange?.();
43
38
  contexts.delete(root || '');
44
- program.delete(root || '');
39
+ languageService.invalidate(root || '', id);
45
40
  }
46
41
  }
47
42
  };
package/package.json CHANGED
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "type": "module",
41
41
  "types": "build/index.d.ts",
42
- "version": "0.28.5",
42
+ "version": "0.29.0",
43
43
  "scripts": {
44
44
  "build": "tsc && tsc-alias",
45
45
  "-": "-"
package/src/cli/tsc.ts CHANGED
@@ -54,6 +54,7 @@ async function build(config: object, tsconfig: string, pluginConfigs: PluginConf
54
54
  sourceFile.getFullText(),
55
55
  sourceFile,
56
56
  program,
57
+ root,
57
58
  shared
58
59
  );
59
60
 
@@ -1,6 +1,7 @@
1
1
  import type { ImportIntent, Plugin, Replacement, ReplacementIntent, SharedContext } from './types';
2
2
  import { ts } from '~/index';
3
3
  import imports, { ModifyOptions } from './imports';
4
+ import languageService from './language-service';
4
5
 
5
6
 
6
7
  type CoordinatorResult = {
@@ -169,33 +170,12 @@ function replaceReverse(code: string, replacements: Replacement[]): string {
169
170
  }
170
171
 
171
172
 
172
- const createPatchedProgram = (baseProgram: ts.Program, fileName: string, newContent: string) => {
173
- let baseHost = ts.createCompilerHost(baseProgram.getCompilerOptions()),
174
- options = baseProgram.getCompilerOptions();
175
-
176
- return ts.createProgram(
177
- baseProgram.getRootFileNames(),
178
- options,
179
- {
180
- ...baseHost,
181
- getSourceFile: (name, languageVersion) => {
182
- if (name === fileName || name === fileName.replace(/\\/g, '/')) {
183
- return ts.createSourceFile(name, newContent, languageVersion, true);
184
- }
185
- return baseProgram.getSourceFile(name) ?? baseHost.getSourceFile(name, languageVersion);
186
- },
187
- fileExists: (name) => baseHost.fileExists(name),
188
- readFile: (name) => name === fileName ? newContent : baseHost.readFile(name)
189
- },
190
- baseProgram
191
- );
192
- };
193
-
194
173
  const transform = (
195
174
  plugins: Plugin[],
196
175
  code: string,
197
176
  file: ts.SourceFile,
198
177
  program: ts.Program,
178
+ root: string,
199
179
  shared: SharedContext
200
180
  ) => {
201
181
  if (plugins.length === 0) {
@@ -206,7 +186,8 @@ const transform = (
206
186
  currentCode = code,
207
187
  currentFile = file,
208
188
  currentProgram = program,
209
- fileName = file.fileName;
189
+ fileName = file.fileName,
190
+ last = plugins.length - 1;
210
191
 
211
192
  for (let i = 0, n = plugins.length; i < n; i++) {
212
193
  let plugin = plugins[i];
@@ -241,9 +222,9 @@ const transform = (
241
222
 
242
223
  if (pluginChanged) {
243
224
  changed = true;
244
- // Create patched program for next plugin
245
- if (i < n - 1) {
246
- currentProgram = createPatchedProgram(program, fileName, currentCode);
225
+
226
+ if (i < last) {
227
+ currentProgram = languageService.update(root, fileName, currentCode);
247
228
  currentFile = currentProgram.getSourceFile(fileName) ||
248
229
  ts.createSourceFile(fileName, currentCode, file.languageVersion, true);
249
230
  }
@@ -257,5 +238,5 @@ const transform = (
257
238
  };
258
239
 
259
240
 
260
- export default { createPatchedProgram, transform };
241
+ export default { transform };
261
242
  export type { CoordinatorResult };
@@ -0,0 +1,135 @@
1
+ import path from 'path';
2
+ import ts from 'typescript';
3
+ import { PACKAGE_NAME } from '~/constants';
4
+
5
+
6
+ type LanguageServiceEntry = {
7
+ contents: Map<string, string>;
8
+ host: ts.LanguageServiceHost;
9
+ rootFiles: Set<string>;
10
+ service: ts.LanguageService;
11
+ versions: Map<string, number>;
12
+ };
13
+
14
+
15
+ let cache = new Map<string, LanguageServiceEntry>();
16
+
17
+
18
+ function create(root: string): LanguageServiceEntry {
19
+ let tsconfig = ts.findConfigFile(root, ts.sys.fileExists, 'tsconfig.json');
20
+
21
+ if (!tsconfig) {
22
+ throw new Error(`${PACKAGE_NAME}: tsconfig.json not found`);
23
+ }
24
+
25
+ let file = ts.readConfigFile(tsconfig, ts.sys.readFile);
26
+
27
+ if (file.error) {
28
+ throw new Error(`${PACKAGE_NAME}: error reading tsconfig.json ${file.error.messageText}`);
29
+ }
30
+
31
+ let parsed = ts.parseJsonConfigFileContent(
32
+ file.config,
33
+ ts.sys,
34
+ path.dirname(tsconfig)
35
+ );
36
+
37
+ if (parsed.errors.length > 0) {
38
+ throw new Error(`${PACKAGE_NAME}: error parsing tsconfig.json ${parsed.errors[0].messageText}`);
39
+ }
40
+
41
+ let contents = new Map<string, string>(),
42
+ rootFiles = new Set(parsed.fileNames.map(f => f.replace(/\\/g, '/'))),
43
+ versions = new Map<string, number>();
44
+
45
+ for (let fileName of rootFiles) {
46
+ versions.set(fileName, 0);
47
+ }
48
+
49
+ let host: ts.LanguageServiceHost = {
50
+ fileExists: ts.sys.fileExists,
51
+ getCompilationSettings: () => parsed.options,
52
+ getCurrentDirectory: () => root,
53
+ getDefaultLibFileName: ts.getDefaultLibFilePath,
54
+ getScriptFileNames: () => [...rootFiles],
55
+ getScriptSnapshot: (fileName: string) => {
56
+ let content = contents.get(fileName);
57
+
58
+ if (content !== undefined) {
59
+ return ts.ScriptSnapshot.fromString(content);
60
+ }
61
+
62
+ if (!ts.sys.fileExists(fileName)) {
63
+ return undefined;
64
+ }
65
+
66
+ return ts.ScriptSnapshot.fromString(ts.sys.readFile(fileName) || '');
67
+ },
68
+ getScriptVersion: (fileName: string) => String(versions.get(fileName) || 0),
69
+ readFile: ts.sys.readFile
70
+ };
71
+
72
+ return { contents, host, rootFiles, service: ts.createLanguageService(host), versions };
73
+ }
74
+
75
+ function getEntry(root: string): LanguageServiceEntry {
76
+ let entry = cache.get(root);
77
+
78
+ if (!entry) {
79
+ entry = create(root);
80
+ cache.set(root, entry);
81
+ }
82
+
83
+ return entry;
84
+ }
85
+
86
+
87
+ const del = (root: string): void => {
88
+ cache.delete(root);
89
+ };
90
+
91
+ const get = (root: string): ts.Program => {
92
+ let entry = getEntry(root),
93
+ program = entry.service.getProgram();
94
+
95
+ if (!program) {
96
+ throw new Error(`${PACKAGE_NAME}: failed to get program from language service`);
97
+ }
98
+
99
+ return program;
100
+ };
101
+
102
+ const invalidate = (root: string, fileName: string): void => {
103
+ let entry = cache.get(root);
104
+
105
+ if (entry) {
106
+ let normalized = fileName.replace(/\\/g, '/');
107
+
108
+ entry.contents.delete(normalized);
109
+ entry.versions.set(normalized, (entry.versions.get(normalized) || 0) + 1);
110
+ }
111
+ };
112
+
113
+ const update = (root: string, fileName: string, content: string): ts.Program => {
114
+ let entry = getEntry(root),
115
+ normalized = fileName.replace(/\\/g, '/');
116
+
117
+ if (!entry.rootFiles.has(normalized)) {
118
+ entry.rootFiles.add(normalized);
119
+ }
120
+
121
+ entry.contents.set(normalized, content);
122
+ entry.versions.set(normalized, (entry.versions.get(normalized) || 0) + 1);
123
+
124
+ let program = entry.service.getProgram();
125
+
126
+ if (!program) {
127
+ throw new Error(`${PACKAGE_NAME}: failed to get program from language service`);
128
+ }
129
+
130
+ return program;
131
+ };
132
+
133
+
134
+ export default { delete: del, get, invalidate, update };
135
+ export { get, invalidate, update };
@@ -2,7 +2,7 @@ import type { ResolvedConfig } from 'vite';
2
2
  import type { Plugin, SharedContext } from '../types';
3
3
  import { ts } from '~/index';
4
4
  import coordinator from '../coordinator';
5
- import program from '../program';
5
+ import languageService from '../language-service';
6
6
 
7
7
 
8
8
  type VitePlugin = {
@@ -20,11 +20,9 @@ type VitePluginOptions = {
20
20
  };
21
21
 
22
22
 
23
- const FILE_REGEX = /\.[tj]sx?$/;
24
-
25
23
  const DIRECTORY_SEPARATOR_REGEX = /\\/g;
26
24
 
27
- const LINE_ENDINGS_REGEX = /\r\n/g;
25
+ const FILE_REGEX = /\.[tj]sx?$/;
28
26
 
29
27
 
30
28
  let contexts = new Map<string, SharedContext>();
@@ -45,17 +43,11 @@ export default ({ name, onWatchChange, plugins }: VitePluginOptions) => {
45
43
 
46
44
  try {
47
45
  let normalizedId = id.replace(DIRECTORY_SEPARATOR_REGEX, '/'),
48
- prog = program.get(root || ''),
49
- sourceFile = prog.getSourceFile(normalizedId) || prog.getSourceFile(id);
50
-
51
- // Check if file content matches (existing file may have changed)
52
- if (sourceFile && sourceFile.getText().replace(LINE_ENDINGS_REGEX, '\n') !== code.replace(LINE_ENDINGS_REGEX, '\n')) {
53
- sourceFile = undefined;
54
- }
46
+ prog = languageService.update(root || '', normalizedId, code),
47
+ sourceFile = prog.getSourceFile(normalizedId);
55
48
 
56
49
  if (!sourceFile) {
57
- prog = coordinator.createPatchedProgram(prog, normalizedId, code);
58
- sourceFile = prog.getSourceFile(normalizedId) || ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true);
50
+ sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true);
59
51
  }
60
52
 
61
53
  let result = coordinator.transform(
@@ -63,6 +55,7 @@ export default ({ name, onWatchChange, plugins }: VitePluginOptions) => {
63
55
  code,
64
56
  sourceFile,
65
57
  prog,
58
+ root || '',
66
59
  contexts.get(root || '') ?? contexts.set(root || '', new Map()).get(root || '')!
67
60
  );
68
61
 
@@ -81,7 +74,7 @@ export default ({ name, onWatchChange, plugins }: VitePluginOptions) => {
81
74
  if (FILE_REGEX.test(id)) {
82
75
  onWatchChange?.();
83
76
  contexts.delete(root || '');
84
- program.delete(root || '');
77
+ languageService.invalidate(root || '', id);
85
78
  }
86
79
  }
87
80
  };
@@ -1,6 +0,0 @@
1
- import ts from 'typescript';
2
- declare const _default: {
3
- get: (root: string) => ts.Program;
4
- delete: (root: string) => void;
5
- };
6
- export default _default;
@@ -1,34 +0,0 @@
1
- import path from 'path';
2
- import ts from 'typescript';
3
- import { PACKAGE_NAME } from '../constants.js';
4
- let cache = new Map();
5
- function create(root) {
6
- let tsconfig = ts.findConfigFile(root, ts.sys.fileExists, 'tsconfig.json');
7
- if (!tsconfig) {
8
- throw new Error('tsconfig.json not found');
9
- }
10
- let file = ts.readConfigFile(tsconfig, ts.sys.readFile);
11
- if (file.error) {
12
- throw new Error(`${PACKAGE_NAME}: error reading tsconfig.json ${file.error.messageText}`);
13
- }
14
- let parsed = ts.parseJsonConfigFileContent(file.config, ts.sys, path.dirname(tsconfig));
15
- if (parsed.errors.length > 0) {
16
- throw new Error(`${PACKAGE_NAME}: error parsing tsconfig.json ${parsed.errors[0].messageText}`);
17
- }
18
- return ts.createProgram({
19
- options: parsed.options,
20
- rootNames: parsed.fileNames
21
- });
22
- }
23
- const get = (root) => {
24
- let program = cache.get(root);
25
- if (!program) {
26
- program = create(root);
27
- cache.set(root, program);
28
- }
29
- return program;
30
- };
31
- const del = (root) => {
32
- cache.delete(root);
33
- };
34
- export default { get, delete: del };
@@ -1,55 +0,0 @@
1
- import path from 'path';
2
- import ts from 'typescript';
3
- import { PACKAGE_NAME } from '~/constants';
4
-
5
-
6
- let cache = new Map<string, ts.Program>();
7
-
8
-
9
- function create(root: string): ts.Program {
10
- let tsconfig = ts.findConfigFile(root, ts.sys.fileExists, 'tsconfig.json');
11
-
12
- if (!tsconfig) {
13
- throw new Error('tsconfig.json not found');
14
- }
15
-
16
- let file = ts.readConfigFile(tsconfig, ts.sys.readFile);
17
-
18
- if (file.error) {
19
- throw new Error(`${PACKAGE_NAME}: error reading tsconfig.json ${file.error.messageText}`);
20
- }
21
-
22
- let parsed = ts.parseJsonConfigFileContent(
23
- file.config,
24
- ts.sys,
25
- path.dirname(tsconfig)
26
- );
27
-
28
- if (parsed.errors.length > 0) {
29
- throw new Error(`${PACKAGE_NAME}: error parsing tsconfig.json ${parsed.errors[0].messageText}`);
30
- }
31
-
32
- return ts.createProgram({
33
- options: parsed.options,
34
- rootNames: parsed.fileNames
35
- });
36
- }
37
-
38
-
39
- const get = (root: string): ts.Program => {
40
- let program = cache.get(root);
41
-
42
- if (!program) {
43
- program = create(root);
44
- cache.set(root, program);
45
- }
46
-
47
- return program;
48
- }
49
-
50
- const del = (root: string): void => {
51
- cache.delete(root);
52
- }
53
-
54
-
55
- export default { get, delete: del };