@esportsplus/typescript 0.28.2 → 0.28.4

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.
@@ -6,7 +6,11 @@ type CoordinatorResult = {
6
6
  sourceFile: ts.SourceFile;
7
7
  };
8
8
  declare const _default: {
9
- transform: (plugins: Plugin[], code: string, file: ts.SourceFile, program: ts.Program, shared: SharedContext) => CoordinatorResult;
9
+ transform: (plugins: Plugin[], code: string, file: ts.SourceFile, program: ts.Program, shared: SharedContext) => {
10
+ changed: boolean;
11
+ code: string;
12
+ sourceFile: ts.SourceFile;
13
+ };
10
14
  };
11
15
  export default _default;
12
16
  export type { CoordinatorResult };
@@ -43,6 +43,20 @@ function applyPrepend(code, file, prepend) {
43
43
  }
44
44
  return code.slice(0, position) + prepend.join('\n') + code.slice(position);
45
45
  }
46
+ function createPatchedProgram(baseProgram, fileName, newContent) {
47
+ let baseHost = ts.createCompilerHost(baseProgram.getCompilerOptions()), options = baseProgram.getCompilerOptions();
48
+ return ts.createProgram(baseProgram.getRootFileNames(), options, {
49
+ ...baseHost,
50
+ getSourceFile: (name, languageVersion) => {
51
+ if (name === fileName || name === fileName.replace(/\\/g, '/')) {
52
+ return ts.createSourceFile(name, newContent, languageVersion, true);
53
+ }
54
+ return baseProgram.getSourceFile(name) ?? baseHost.getSourceFile(name, languageVersion);
55
+ },
56
+ fileExists: (name) => baseHost.fileExists(name),
57
+ readFile: (name) => name === fileName ? newContent : baseHost.readFile(name)
58
+ }, baseProgram);
59
+ }
46
60
  function hasPattern(code, patterns) {
47
61
  for (let i = 0, n = patterns.length; i < n; i++) {
48
62
  if (code.indexOf(patterns[i]) !== -1) {
@@ -99,7 +113,6 @@ function modify(code, file, pkg, options) {
99
113
  }
100
114
  return replaceReverse(code, replacements);
101
115
  }
102
- ;
103
116
  function replaceReverse(code, replacements) {
104
117
  if (replacements.length === 0) {
105
118
  return code;
@@ -112,41 +125,47 @@ function replaceReverse(code, replacements) {
112
125
  }
113
126
  return result;
114
127
  }
115
- ;
116
128
  const transform = (plugins, code, file, program, shared) => {
117
129
  if (plugins.length === 0) {
118
130
  return { changed: false, code, sourceFile: file };
119
131
  }
120
- let checker = program.getTypeChecker(), currentCode = code, currentFile = file, fileName = file.fileName;
132
+ let changed = false, currentCode = code, currentFile = file, currentProgram = program, fileName = file.fileName;
121
133
  for (let i = 0, n = plugins.length; i < n; i++) {
122
134
  let plugin = plugins[i];
123
135
  if (plugin.patterns && !hasPattern(currentCode, plugin.patterns)) {
124
136
  continue;
125
137
  }
126
138
  let { imports, prepend, replacements } = plugin.transform({
127
- checker,
139
+ checker: currentProgram.getTypeChecker(),
128
140
  code: currentCode,
129
- program,
141
+ program: currentProgram,
130
142
  shared,
131
143
  sourceFile: currentFile
132
- });
144
+ }), pluginChanged = false;
133
145
  if (replacements?.length) {
134
146
  currentCode = applyIntents(currentCode, currentFile, replacements);
135
- currentFile = ts.createSourceFile(fileName, currentCode, currentFile.languageVersion, true);
147
+ pluginChanged = true;
136
148
  }
137
149
  if (prepend?.length) {
138
150
  currentCode = applyPrepend(currentCode, currentFile, prepend);
139
- currentFile = ts.createSourceFile(fileName, currentCode, currentFile.languageVersion, true);
151
+ pluginChanged = true;
140
152
  }
141
153
  if (imports?.length) {
142
154
  currentCode = applyImports(currentCode, currentFile, imports);
143
- currentFile = ts.createSourceFile(fileName, currentCode, currentFile.languageVersion, true);
155
+ pluginChanged = true;
156
+ }
157
+ if (pluginChanged) {
158
+ changed = true;
159
+ if (i < n - 1) {
160
+ currentProgram = createPatchedProgram(program, fileName, currentCode);
161
+ currentFile = currentProgram.getSourceFile(fileName) ||
162
+ ts.createSourceFile(fileName, currentCode, file.languageVersion, true);
163
+ }
164
+ else {
165
+ currentFile = ts.createSourceFile(fileName, currentCode, file.languageVersion, true);
166
+ }
144
167
  }
145
168
  }
146
- return {
147
- changed: currentCode !== code,
148
- code: currentCode,
149
- sourceFile: currentFile
150
- };
169
+ return { changed, code: currentCode, sourceFile: currentFile };
151
170
  };
152
171
  export default { transform };
@@ -3,6 +3,7 @@ import coordinator from '../coordinator.js';
3
3
  import program from '../program.js';
4
4
  const FILE_REGEX = /\.[tj]sx?$/;
5
5
  const DIRECTORY_SEPARATOR_REGEX = /\\/g;
6
+ const LINE_ENDINGS_REGEX = /\r\n/g;
6
7
  let contexts = new Map();
7
8
  export default ({ name, onWatchChange, plugins }) => {
8
9
  return ({ root } = {}) => {
@@ -18,7 +19,8 @@ export default ({ name, onWatchChange, plugins }) => {
18
19
  }
19
20
  try {
20
21
  let prog = program.get(root || ''), sourceFile = prog.getSourceFile(id.replace(DIRECTORY_SEPARATOR_REGEX, '/')) || prog.getSourceFile(id);
21
- if (!sourceFile || sourceFile.getText() !== code) {
22
+ if (!sourceFile ||
23
+ sourceFile.getText().replace(LINE_ENDINGS_REGEX, '\n') !== code.replace(LINE_ENDINGS_REGEX, '\n')) {
22
24
  sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true);
23
25
  }
24
26
  let result = coordinator.transform(plugins, code, sourceFile, prog, contexts.get(root || '') ?? contexts.set(root || '', new Map()).get(root || ''));
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.2",
42
+ "version": "0.28.4",
43
43
  "scripts": {
44
44
  "build": "tsc && tsc-alias",
45
45
  "-": "-"
@@ -73,6 +73,28 @@ function applyPrepend(code: string, file: ts.SourceFile, prepend: string[]): str
73
73
  return code.slice(0, position) + prepend.join('\n') + code.slice(position);
74
74
  }
75
75
 
76
+ function createPatchedProgram(baseProgram: ts.Program, fileName: string, newContent: string) {
77
+ let baseHost = ts.createCompilerHost(baseProgram.getCompilerOptions()),
78
+ options = baseProgram.getCompilerOptions();
79
+
80
+ return ts.createProgram(
81
+ baseProgram.getRootFileNames(),
82
+ options,
83
+ {
84
+ ...baseHost,
85
+ getSourceFile: (name, languageVersion) => {
86
+ if (name === fileName || name === fileName.replace(/\\/g, '/')) {
87
+ return ts.createSourceFile(name, newContent, languageVersion, true);
88
+ }
89
+ return baseProgram.getSourceFile(name) ?? baseHost.getSourceFile(name, languageVersion);
90
+ },
91
+ fileExists: (name) => baseHost.fileExists(name),
92
+ readFile: (name) => name === fileName ? newContent : baseHost.readFile(name)
93
+ },
94
+ baseProgram
95
+ );
96
+ }
97
+
76
98
  function hasPattern(code: string, patterns: string[]): boolean {
77
99
  for (let i = 0, n = patterns.length; i < n; i++) {
78
100
  if (code.indexOf(patterns[i]) !== -1) {
@@ -148,7 +170,7 @@ function modify(code: string, file: ts.SourceFile, pkg: string, options: ModifyO
148
170
  }
149
171
 
150
172
  return replaceReverse(code, replacements);
151
- };
173
+ }
152
174
 
153
175
  function replaceReverse(code: string, replacements: Replacement[]): string {
154
176
  if (replacements.length === 0) {
@@ -166,28 +188,23 @@ function replaceReverse(code: string, replacements: Replacement[]): string {
166
188
  }
167
189
 
168
190
  return result;
169
- };
170
-
191
+ }
171
192
 
172
- /**
173
- * Transform source through all plugins sequentially.
174
- * Each plugin receives fresh AST with accurate positions.
175
- * All plugins share the original program type checker for import resolution.
176
- */
177
193
  const transform = (
178
194
  plugins: Plugin[],
179
195
  code: string,
180
196
  file: ts.SourceFile,
181
197
  program: ts.Program,
182
198
  shared: SharedContext
183
- ): CoordinatorResult => {
199
+ ) => {
184
200
  if (plugins.length === 0) {
185
201
  return { changed: false, code, sourceFile: file };
186
202
  }
187
203
 
188
- let checker = program.getTypeChecker(),
204
+ let changed = false,
189
205
  currentCode = code,
190
206
  currentFile = file,
207
+ currentProgram = program,
191
208
  fileName = file.fileName;
192
209
 
193
210
  for (let i = 0, n = plugins.length; i < n; i++) {
@@ -198,49 +215,44 @@ const transform = (
198
215
  }
199
216
 
200
217
  let { imports, prepend, replacements } = plugin.transform({
201
- checker,
218
+ checker: currentProgram.getTypeChecker(),
202
219
  code: currentCode,
203
- program,
220
+ program: currentProgram,
204
221
  shared,
205
222
  sourceFile: currentFile
206
- });
223
+ }),
224
+ pluginChanged = false;
207
225
 
208
226
  if (replacements?.length) {
209
227
  currentCode = applyIntents(currentCode, currentFile, replacements);
210
- currentFile = ts.createSourceFile(
211
- fileName,
212
- currentCode,
213
- currentFile.languageVersion,
214
- true
215
- );
228
+ pluginChanged = true;
216
229
  }
217
230
 
218
231
  if (prepend?.length) {
219
232
  currentCode = applyPrepend(currentCode, currentFile, prepend);
220
- currentFile = ts.createSourceFile(
221
- fileName,
222
- currentCode,
223
- currentFile.languageVersion,
224
- true
225
- );
233
+ pluginChanged = true;
226
234
  }
227
235
 
228
236
  if (imports?.length) {
229
237
  currentCode = applyImports(currentCode, currentFile, imports);
230
- currentFile = ts.createSourceFile(
231
- fileName,
232
- currentCode,
233
- currentFile.languageVersion,
234
- true
235
- );
238
+ pluginChanged = true;
239
+ }
240
+
241
+ if (pluginChanged) {
242
+ changed = true;
243
+ // Create patched program for next plugin
244
+ if (i < n - 1) {
245
+ currentProgram = createPatchedProgram(program, fileName, currentCode);
246
+ currentFile = currentProgram.getSourceFile(fileName) ||
247
+ ts.createSourceFile(fileName, currentCode, file.languageVersion, true);
248
+ }
249
+ else {
250
+ currentFile = ts.createSourceFile(fileName, currentCode, file.languageVersion, true);
251
+ }
236
252
  }
237
253
  }
238
254
 
239
- return {
240
- changed: currentCode !== code,
241
- code: currentCode,
242
- sourceFile: currentFile
243
- };
255
+ return { changed, code: currentCode, sourceFile: currentFile };
244
256
  };
245
257
 
246
258
 
@@ -24,6 +24,8 @@ const FILE_REGEX = /\.[tj]sx?$/;
24
24
 
25
25
  const DIRECTORY_SEPARATOR_REGEX = /\\/g;
26
26
 
27
+ const LINE_ENDINGS_REGEX = /\r\n/g;
28
+
27
29
 
28
30
  let contexts = new Map<string, SharedContext>();
29
31
 
@@ -45,7 +47,10 @@ export default ({ name, onWatchChange, plugins }: VitePluginOptions) => {
45
47
  let prog = program.get(root || ''),
46
48
  sourceFile = prog.getSourceFile(id.replace(DIRECTORY_SEPARATOR_REGEX, '/')) || prog.getSourceFile(id);
47
49
 
48
- if (!sourceFile || sourceFile.getText() !== code) {
50
+ if (
51
+ !sourceFile ||
52
+ sourceFile.getText().replace(LINE_ENDINGS_REGEX, '\n') !== code.replace(LINE_ENDINGS_REGEX, '\n')
53
+ ) {
49
54
  sourceFile = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true);
50
55
  }
51
56