@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.
- package/index.d.ts +2 -2
- package/index.js +104 -65
- 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
|
|
3
|
-
export =
|
|
2
|
+
declare const plugin: ts.server.PluginModuleFactory;
|
|
3
|
+
export = plugin;
|
package/index.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const
|
|
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
|
|
7
|
+
const plugin = modules => {
|
|
6
8
|
const { typescript: ts } = modules;
|
|
7
9
|
const pluginModule = {
|
|
8
10
|
create(info) {
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
languageServiceDecorators.set(info.project,
|
|
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 =
|
|
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(
|
|
107
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
176
|
-
|
|
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:
|
|
184
|
-
start:
|
|
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 (
|
|
192
|
-
|
|
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
|
-
|
|
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
|
+
"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.
|
|
15
|
+
"@tsslint/core": "1.4.1",
|
|
16
|
+
"source-map-support": "^0.5.21"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
|
-
"@tsslint/config": "1.
|
|
19
|
+
"@tsslint/config": "1.4.1"
|
|
19
20
|
},
|
|
20
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "54f42ec9414029a356fa19a762260f03392563fa"
|
|
21
22
|
}
|