@tsslint/typescript-plugin 1.3.6 → 1.4.1

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 (3) hide show
  1. package/index.d.ts +2 -2
  2. package/index.js +104 -65
  3. package/package.json +5 -4
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import type * as ts from 'typescript';
2
- declare const init: ts.server.PluginModuleFactory;
3
- export = init;
2
+ declare const plugin: ts.server.PluginModuleFactory;
3
+ export = plugin;
package/index.js CHANGED
@@ -1,20 +1,22 @@
1
1
  "use strict";
2
- const core_1 = require("@tsslint/core");
2
+ const core = require("@tsslint/core");
3
3
  const path = require("path");
4
+ const url = require("url");
5
+ const fs = require("fs");
4
6
  const languageServiceDecorators = new WeakMap();
5
- const init = modules => {
7
+ const plugin = modules => {
6
8
  const { typescript: ts } = modules;
7
9
  const pluginModule = {
8
10
  create(info) {
9
- if (!languageServiceDecorators.has(info.project)) {
10
- const tsconfig = info.project.projectKind === ts.server.ProjectKind.Configured
11
- ? info.project.getProjectName()
12
- : undefined;
13
- if (tsconfig) {
14
- languageServiceDecorators.set(info.project, decorateLanguageService(ts, tsconfig, info));
11
+ if (info.project.projectKind === ts.server.ProjectKind.Configured) {
12
+ let decorator = languageServiceDecorators.get(info.project);
13
+ if (!decorator) {
14
+ const tsconfig = info.project.getProjectName();
15
+ decorator = decorateLanguageService(ts, tsconfig, info);
16
+ languageServiceDecorators.set(info.project, decorator);
15
17
  }
18
+ decorator.update();
16
19
  }
17
- languageServiceDecorators.get(info.project)?.update(info.config);
18
20
  return info.languageService;
19
21
  },
20
22
  };
@@ -38,6 +40,7 @@ function decorateLanguageService(ts, tsconfig, info) {
38
40
  if (sourceFile) {
39
41
  result = result.concat(configFileDiagnostics.map(diagnostic => ({
40
42
  ...diagnostic,
43
+ source: 'tsslint',
41
44
  file: sourceFile,
42
45
  start: 0,
43
46
  length: 0,
@@ -57,8 +60,8 @@ function decorateLanguageService(ts, tsconfig, info) {
57
60
  };
58
61
  info.languageService.getCombinedCodeFix = (scope, fixId, formatOptions, preferences) => {
59
62
  if (fixId === 'tsslint' && linter) {
60
- const fixes = linter.getCodeFixes(scope.fileName, 0, Number.MAX_VALUE);
61
- const changes = (0, core_1.combineCodeFixes)(scope.fileName, fixes);
63
+ const fixes = linter.getCodeFixes(scope.fileName, 0, Number.MAX_VALUE).filter(fix => fix.fixId === 'tsslint');
64
+ const changes = core.combineCodeFixes(scope.fileName, fixes);
62
65
  return {
63
66
  changes: [{
64
67
  fileName: scope.fileName,
@@ -103,42 +106,14 @@ function decorateLanguageService(ts, tsconfig, info) {
103
106
  function getFileKey(fileName) {
104
107
  return info.languageServiceHost.useCaseSensitiveFileNames?.() ? fileName : fileName.toLowerCase();
105
108
  }
106
- async function update(pluginConfig) {
107
- let configOptionSpan = { start: 0, length: 0 };
108
- let newConfigFile;
109
- let configResolveError;
110
- const jsonConfigFile = ts.readJsonConfigFile(tsconfig, ts.sys.readFile);
111
- if (pluginConfig?.configFile) {
112
- configOptionSpan = {
113
- start: jsonConfigFile.text.indexOf(pluginConfig.configFile) - 1,
114
- length: pluginConfig.configFile.length + 2,
115
- };
116
- try {
117
- newConfigFile = require.resolve(pluginConfig.configFile, { paths: [path.dirname(tsconfig)] });
118
- }
119
- catch (err) {
120
- configResolveError = err;
121
- }
122
- }
123
- else {
124
- newConfigFile = ts.findConfigFile(path.dirname(tsconfig), ts.sys.fileExists, 'tsslint.config.ts');
125
- }
109
+ async function update() {
110
+ const newConfigFile = ts.findConfigFile(path.dirname(tsconfig), ts.sys.fileExists, 'tsslint.config.ts');
126
111
  if (newConfigFile !== configFile) {
127
112
  configFile = newConfigFile;
128
113
  config = undefined;
129
114
  linter = undefined;
130
115
  configFileBuildContext?.dispose();
131
116
  configFileDiagnostics = [];
132
- if (configResolveError) {
133
- configFileDiagnostics.push({
134
- category: ts.DiagnosticCategory.Error,
135
- code: 0,
136
- messageText: String(configResolveError),
137
- file: jsonConfigFile,
138
- start: configOptionSpan.start,
139
- length: configOptionSpan.length,
140
- });
141
- }
142
117
  if (!configFile) {
143
118
  return;
144
119
  }
@@ -150,46 +125,69 @@ function decorateLanguageService(ts, tsconfig, info) {
150
125
  tsconfig: ts.server.toNormalizedPath(tsconfig),
151
126
  };
152
127
  try {
153
- configFileBuildContext = await (0, core_1.watchConfigFile)(configFile, (_config, { errors, warnings }) => {
154
- config = _config;
128
+ configFileBuildContext = await core.watchConfig(configFile, async (builtConfig, { errors, warnings }) => {
155
129
  configFileDiagnostics = [
156
130
  ...errors.map(error => [error, ts.DiagnosticCategory.Error]),
157
131
  ...warnings.map(error => [error, ts.DiagnosticCategory.Warning]),
158
132
  ].map(([error, category]) => {
159
133
  const diag = {
160
134
  category,
161
- source: 'tsslint',
162
- code: error.id ?? 0,
135
+ code: error.id,
163
136
  messageText: error.text,
164
- file: jsonConfigFile,
165
- start: configOptionSpan.start,
166
- length: configOptionSpan.length,
167
137
  };
168
138
  if (error.location) {
169
139
  const fileName = path.resolve(error.location.file).replace('http-url:', '');
170
- const fileText = ts.sys.readFile(error.location.file);
171
- if (fileText !== undefined) {
172
- if (error.id === 'config-import-error') {
173
- diag.messageText = `Error importing config file.`;
140
+ let relatedFile = info.languageService.getCurrentProgram()?.getSourceFile(fileName);
141
+ if (!relatedFile) {
142
+ const fileText = ts.sys.readFile(error.location.file);
143
+ if (fileText !== undefined) {
144
+ relatedFile = ts.createSourceFile(fileName, fileText, ts.ScriptTarget.Latest, true);
174
145
  }
175
- else {
176
- diag.messageText = `Error building config file.`;
177
- }
178
- const sourceFile = ts.createSourceFile(fileName, fileText, ts.ScriptTarget.Latest, true);
146
+ }
147
+ if (relatedFile) {
148
+ diag.messageText = `Error building config file.`;
179
149
  diag.relatedInformation = [{
180
150
  category,
181
151
  code: error.id,
182
152
  messageText: error.text,
183
- file: sourceFile,
184
- start: sourceFile.getPositionOfLineAndCharacter(error.location.line - 1, error.location.column),
153
+ file: relatedFile,
154
+ start: relatedFile.getPositionOfLineAndCharacter(error.location.line - 1, error.location.column),
185
155
  length: error.location.lineText.length,
186
156
  }];
187
157
  }
188
158
  }
189
159
  return diag;
190
160
  });
191
- if (config) {
192
- linter = (0, core_1.createLinter)(projectContext, config, 'typescript-plugin');
161
+ if (builtConfig) {
162
+ try {
163
+ initSourceMapSupport();
164
+ const mtime = ts.sys.getModifiedTime?.(builtConfig)?.getTime() ?? Date.now();
165
+ config = (await import(url.pathToFileURL(builtConfig).toString() + '?tsslint_time=' + mtime)).default;
166
+ linter = core.createLinter(projectContext, config, 'typescript-plugin');
167
+ }
168
+ catch (err) {
169
+ config = undefined;
170
+ linter = undefined;
171
+ const prevLength = configFileDiagnostics.length;
172
+ if (err instanceof Error) {
173
+ const relatedInfo = core.createRelatedInformation(ts, err, 0);
174
+ if (relatedInfo) {
175
+ configFileDiagnostics.push({
176
+ category: ts.DiagnosticCategory.Error,
177
+ code: 0,
178
+ messageText: err.message,
179
+ relatedInformation: [relatedInfo],
180
+ });
181
+ }
182
+ }
183
+ if (prevLength === configFileDiagnostics.length) {
184
+ configFileDiagnostics.push({
185
+ category: ts.DiagnosticCategory.Error,
186
+ code: 0,
187
+ messageText: String(err),
188
+ });
189
+ }
190
+ }
193
191
  }
194
192
  info.project.refreshDiagnostics();
195
193
  }, true, ts.sys.createHash);
@@ -197,16 +195,57 @@ function decorateLanguageService(ts, tsconfig, info) {
197
195
  catch (err) {
198
196
  configFileDiagnostics.push({
199
197
  category: ts.DiagnosticCategory.Error,
200
- source: 'tsslint',
201
198
  code: 'config-build-error',
202
199
  messageText: String(err),
203
- file: jsonConfigFile,
204
- start: configOptionSpan.start,
205
- length: configOptionSpan.length,
206
200
  });
207
201
  }
208
202
  }
209
203
  }
210
204
  }
211
- module.exports = init;
205
+ function initSourceMapSupport() {
206
+ delete require.cache[require.resolve('source-map-support')];
207
+ require('source-map-support').install({
208
+ retrieveFile(pathOrUrl) {
209
+ if (pathOrUrl.includes('?tsslint_time=')) {
210
+ pathOrUrl = pathOrUrl.replace(/\?tsslint_time=\d*/, '');
211
+ if (pathOrUrl.includes('://')) {
212
+ pathOrUrl = url.fileURLToPath(pathOrUrl);
213
+ }
214
+ return fs.readFileSync(pathOrUrl, 'utf8');
215
+ }
216
+ },
217
+ });
218
+ require('source-map-support').install({
219
+ retrieveFile(pathOrUrl) {
220
+ if (pathOrUrl.endsWith('.map')) {
221
+ try {
222
+ if (pathOrUrl.includes('://')) {
223
+ pathOrUrl = url.fileURLToPath(pathOrUrl);
224
+ }
225
+ const contents = fs.readFileSync(pathOrUrl, 'utf8');
226
+ const map = JSON.parse(contents);
227
+ for (let source of map.sources) {
228
+ if (!source.startsWith('./') && !source.startsWith('../')) {
229
+ source = './' + source;
230
+ }
231
+ source = path.resolve(path.dirname(pathOrUrl), source);
232
+ if (!fs.existsSync(source)) {
233
+ // Fixes https://github.com/typescript-eslint/typescript-eslint/issues/9352
234
+ return JSON.stringify({
235
+ version: 3,
236
+ sources: [],
237
+ sourcesContent: [],
238
+ mappings: '',
239
+ names: [],
240
+ });
241
+ }
242
+ }
243
+ return contents;
244
+ }
245
+ catch { }
246
+ }
247
+ },
248
+ });
249
+ }
250
+ module.exports = plugin;
212
251
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsslint/typescript-plugin",
3
- "version": "1.3.6",
3
+ "version": "1.4.1",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "**/*.js",
@@ -12,10 +12,11 @@
12
12
  "directory": "packages/typescript-plugin"
13
13
  },
14
14
  "dependencies": {
15
- "@tsslint/core": "1.3.6"
15
+ "@tsslint/core": "1.4.1",
16
+ "source-map-support": "^0.5.21"
16
17
  },
17
18
  "devDependencies": {
18
- "@tsslint/config": "1.3.6"
19
+ "@tsslint/config": "1.4.1"
19
20
  },
20
- "gitHead": "d153aa87c92803b4c20fef1f5cf2799f1a599099"
21
+ "gitHead": "54f42ec9414029a356fa19a762260f03392563fa"
21
22
  }