@tsslint/typescript-plugin 0.0.1 → 0.0.2
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.js +71 -16
- package/lib/builtInPlugins.d.ts +1 -1
- package/lib/builtInPlugins.js +11 -16
- package/lib/watchConfig.d.ts +2 -13
- package/lib/watchConfig.js +71 -36
- package/package.json +5 -4
package/index.js
CHANGED
|
@@ -22,7 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
const watchConfig_1 = require("./lib/watchConfig");
|
|
26
25
|
const builtInPlugins_1 = require("./lib/builtInPlugins");
|
|
27
26
|
const path = __importStar(require("path"));
|
|
28
27
|
const languageServiceDecorators = new WeakMap();
|
|
@@ -49,16 +48,17 @@ function decorateLanguageService(ts, tsconfig, info) {
|
|
|
49
48
|
const getSyntacticDiagnostics = info.languageService.getSyntacticDiagnostics;
|
|
50
49
|
const getApplicableRefactors = info.languageService.getApplicableRefactors;
|
|
51
50
|
const getEditsForRefactor = info.languageService.getEditsForRefactor;
|
|
52
|
-
let compilerOptionsDiagnostics = [];
|
|
53
51
|
let configFile;
|
|
54
52
|
let configFileBuildContext;
|
|
53
|
+
let configFileDiagnostics = [];
|
|
55
54
|
let config;
|
|
56
55
|
let plugins = [];
|
|
57
56
|
info.languageService.getCompilerOptionsDiagnostics = () => {
|
|
58
|
-
return getCompilerOptionsDiagnostics().concat(
|
|
57
|
+
return getCompilerOptionsDiagnostics().concat(configFileDiagnostics);
|
|
59
58
|
};
|
|
60
59
|
info.languageService.getSyntacticDiagnostics = fileName => {
|
|
61
60
|
let errors = getSyntacticDiagnostics(fileName);
|
|
61
|
+
errors = errors.concat(configFileDiagnostics);
|
|
62
62
|
const sourceFile = info.languageService.getProgram()?.getSourceFile(fileName);
|
|
63
63
|
if (!sourceFile) {
|
|
64
64
|
return errors;
|
|
@@ -78,6 +78,22 @@ function decorateLanguageService(ts, tsconfig, info) {
|
|
|
78
78
|
errors = errors.concat(pluginResult);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
+
if (config?.debug) {
|
|
82
|
+
errors.push({
|
|
83
|
+
category: ts.DiagnosticCategory.Message,
|
|
84
|
+
source: 'tsslint',
|
|
85
|
+
code: 'debug-info',
|
|
86
|
+
messageText: JSON.stringify({
|
|
87
|
+
rules: Object.keys(config?.rules ?? {}),
|
|
88
|
+
plugins: plugins.length,
|
|
89
|
+
configFile,
|
|
90
|
+
tsconfig,
|
|
91
|
+
}, null, 2),
|
|
92
|
+
file: sourceFile,
|
|
93
|
+
start: 0,
|
|
94
|
+
length: 0,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
81
97
|
return errors;
|
|
82
98
|
};
|
|
83
99
|
info.languageService.getApplicableRefactors = (fileName, positionOrRange, ...rest) => {
|
|
@@ -110,31 +126,56 @@ function decorateLanguageService(ts, tsconfig, info) {
|
|
|
110
126
|
};
|
|
111
127
|
return { update };
|
|
112
128
|
async function update(pluginConfig) {
|
|
113
|
-
|
|
114
|
-
const start = jsonConfigFile.text.indexOf(pluginConfig.configFile) - 1;
|
|
115
|
-
const length = pluginConfig.configFile.length + 2;
|
|
129
|
+
let configOptionSpan = { start: 0, length: 0 };
|
|
116
130
|
let newConfigFile;
|
|
131
|
+
let configImportPath;
|
|
117
132
|
let configResolveError;
|
|
133
|
+
const jsonConfigFile = ts.readJsonConfigFile(tsconfig, ts.sys.readFile);
|
|
118
134
|
try {
|
|
119
|
-
|
|
135
|
+
configImportPath = require.resolve('@tsslint/config', { paths: [path.dirname(tsconfig)] });
|
|
120
136
|
}
|
|
121
137
|
catch (err) {
|
|
122
138
|
configResolveError = err;
|
|
139
|
+
configFileDiagnostics = [{
|
|
140
|
+
category: ts.DiagnosticCategory.Error,
|
|
141
|
+
code: 0,
|
|
142
|
+
messageText: String(err),
|
|
143
|
+
file: jsonConfigFile,
|
|
144
|
+
start: 0,
|
|
145
|
+
length: 0,
|
|
146
|
+
}];
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const { findConfigFile, watchConfigFile } = require(configImportPath);
|
|
150
|
+
if (pluginConfig?.configFile) {
|
|
151
|
+
configOptionSpan = {
|
|
152
|
+
start: jsonConfigFile.text.indexOf(pluginConfig.configFile) - 1,
|
|
153
|
+
length: pluginConfig.configFile.length + 2,
|
|
154
|
+
};
|
|
155
|
+
try {
|
|
156
|
+
newConfigFile = require.resolve(pluginConfig.configFile, { paths: [path.dirname(tsconfig)] });
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
configResolveError = err;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
newConfigFile = findConfigFile(tsconfig);
|
|
123
164
|
}
|
|
124
165
|
if (newConfigFile !== configFile) {
|
|
125
166
|
configFile = newConfigFile;
|
|
126
167
|
config = undefined;
|
|
127
168
|
plugins = [];
|
|
128
169
|
configFileBuildContext?.dispose();
|
|
129
|
-
|
|
170
|
+
configFileDiagnostics = [];
|
|
130
171
|
if (configResolveError) {
|
|
131
|
-
|
|
172
|
+
configFileDiagnostics.push({
|
|
132
173
|
category: ts.DiagnosticCategory.Error,
|
|
133
174
|
code: 0,
|
|
134
175
|
messageText: String(configResolveError),
|
|
135
176
|
file: jsonConfigFile,
|
|
136
|
-
start: start,
|
|
137
|
-
length: length,
|
|
177
|
+
start: configOptionSpan.start,
|
|
178
|
+
length: configOptionSpan.length,
|
|
138
179
|
});
|
|
139
180
|
}
|
|
140
181
|
if (!configFile) {
|
|
@@ -147,20 +188,34 @@ function decorateLanguageService(ts, tsconfig, info) {
|
|
|
147
188
|
languageService: info.languageService,
|
|
148
189
|
typescript: ts,
|
|
149
190
|
};
|
|
150
|
-
configFileBuildContext = await (
|
|
191
|
+
configFileBuildContext = await watchConfigFile(configFile, async (_config, { errors, warnings }) => {
|
|
151
192
|
config = _config;
|
|
152
|
-
|
|
193
|
+
configFileDiagnostics = [
|
|
153
194
|
...errors.map(error => [error, ts.DiagnosticCategory.Error]),
|
|
154
195
|
...warnings.map(error => [error, ts.DiagnosticCategory.Warning]),
|
|
155
196
|
].map(([error, category]) => {
|
|
156
197
|
const diag = {
|
|
157
198
|
category,
|
|
199
|
+
source: 'tsslint',
|
|
158
200
|
code: 0,
|
|
159
|
-
messageText:
|
|
201
|
+
messageText: 'Failed to build config',
|
|
160
202
|
file: jsonConfigFile,
|
|
161
|
-
start: start,
|
|
162
|
-
length: length,
|
|
203
|
+
start: configOptionSpan.start,
|
|
204
|
+
length: configOptionSpan.length,
|
|
163
205
|
};
|
|
206
|
+
if (error.location) {
|
|
207
|
+
const fileName = path.resolve(error.location.file);
|
|
208
|
+
const fileText = ts.sys.readFile(error.location.file);
|
|
209
|
+
const sourceFile = ts.createSourceFile(fileName, fileText ?? '', ts.ScriptTarget.Latest, true);
|
|
210
|
+
diag.relatedInformation = [{
|
|
211
|
+
category,
|
|
212
|
+
code: error.id,
|
|
213
|
+
messageText: error.text,
|
|
214
|
+
file: sourceFile,
|
|
215
|
+
start: sourceFile.getPositionOfLineAndCharacter(error.location.line - 1, error.location.column),
|
|
216
|
+
length: error.location.lineText.length,
|
|
217
|
+
}];
|
|
218
|
+
}
|
|
164
219
|
return diag;
|
|
165
220
|
});
|
|
166
221
|
if (config) {
|
package/lib/builtInPlugins.d.ts
CHANGED
package/lib/builtInPlugins.js
CHANGED
|
@@ -31,6 +31,7 @@ exports.builtInPlugins = [
|
|
|
31
31
|
const ts = ctx.typescript;
|
|
32
32
|
const fileFixes = new Map();
|
|
33
33
|
const sourceFiles = new Map();
|
|
34
|
+
const configSourceFile = ts.createSourceFile(ctx.configFile, ts.sys.readFile(ctx.configFile) ?? '', ts.ScriptTarget.Latest, true);
|
|
34
35
|
return {
|
|
35
36
|
lint(sourceFile, rules) {
|
|
36
37
|
const rulesContext = {
|
|
@@ -87,27 +88,21 @@ exports.builtInPlugins = [
|
|
|
87
88
|
}
|
|
88
89
|
const stackFile = sourceFiles.get(fileName);
|
|
89
90
|
const pos = stackFile?.getPositionOfLineAndCharacter(stack.lineNumber - 1, stack.columnNumber - 1);
|
|
90
|
-
let reportNode;
|
|
91
|
-
stackFile.forEachChild(function visit(node) {
|
|
92
|
-
if (node.end < pos || reportNode) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
if (node.pos <= pos) {
|
|
96
|
-
if (node.getStart() === pos) {
|
|
97
|
-
reportNode = node;
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
node.forEachChild(visit);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
91
|
error.relatedInformation?.push({
|
|
105
92
|
category: ts.DiagnosticCategory.Message,
|
|
106
93
|
code: 0,
|
|
107
94
|
file: stackFile,
|
|
108
95
|
start: pos,
|
|
109
|
-
length:
|
|
110
|
-
messageText: '
|
|
96
|
+
length: 0,
|
|
97
|
+
messageText: 'Related rule file',
|
|
98
|
+
});
|
|
99
|
+
error.relatedInformation?.push({
|
|
100
|
+
category: ts.DiagnosticCategory.Message,
|
|
101
|
+
code: 0,
|
|
102
|
+
file: configSourceFile,
|
|
103
|
+
start: 0,
|
|
104
|
+
length: 0,
|
|
105
|
+
messageText: 'Related config file',
|
|
111
106
|
});
|
|
112
107
|
}
|
|
113
108
|
}
|
package/lib/watchConfig.d.ts
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
import type { Config } from '@tsslint/config';
|
|
2
|
-
import
|
|
3
|
-
export declare function watchConfig(tsConfigPath: string, onBuild: (config: Config | undefined, result:
|
|
4
|
-
entryPoints: string[];
|
|
5
|
-
bundle: true;
|
|
6
|
-
sourcemap: true;
|
|
7
|
-
outfile: string;
|
|
8
|
-
format: "cjs";
|
|
9
|
-
platform: "node";
|
|
10
|
-
plugins: {
|
|
11
|
-
name: string;
|
|
12
|
-
setup(build: esbuild.PluginBuild): void;
|
|
13
|
-
}[];
|
|
14
|
-
}>>;
|
|
2
|
+
import rollup = require('rollup');
|
|
3
|
+
export declare function watchConfig(tsConfigPath: string, onBuild: (config: Config | undefined, result: Error | undefined) => void): Promise<rollup.RollupBuild>;
|
|
15
4
|
//# sourceMappingURL=watchConfig.d.ts.map
|
package/lib/watchConfig.js
CHANGED
|
@@ -1,53 +1,88 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.watchConfig = void 0;
|
|
4
|
-
const
|
|
4
|
+
const rollup = require("rollup");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
async function watchConfig(tsConfigPath, onBuild) {
|
|
7
|
-
const outDir = path.resolve(
|
|
7
|
+
const outDir = path.resolve(__dirname, '..', '..', '.tsslint');
|
|
8
8
|
const outFileName = btoa(path.relative(outDir, tsConfigPath)) + '.cjs';
|
|
9
9
|
const outFile = path.join(outDir, outFileName);
|
|
10
|
-
const ctx = await esbuild.context({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
// const ctx = await esbuild.context({
|
|
11
|
+
// entryPoints: [tsConfigPath],
|
|
12
|
+
// bundle: true,
|
|
13
|
+
// sourcemap: true,
|
|
14
|
+
// outfile: outFile,
|
|
15
|
+
// format: 'cjs',
|
|
16
|
+
// platform: 'node',
|
|
17
|
+
// plugins: [{
|
|
18
|
+
// name: 'tsslint',
|
|
19
|
+
// setup(build) {
|
|
20
|
+
// build.onResolve({ filter: /.*/ }, args => {
|
|
21
|
+
// if (!args.path.endsWith('.ts')) {
|
|
22
|
+
// try {
|
|
23
|
+
// const jsPath = require.resolve(args.path, { paths: [args.resolveDir] });
|
|
24
|
+
// return {
|
|
25
|
+
// path: jsPath,
|
|
26
|
+
// external: true,
|
|
27
|
+
// };
|
|
28
|
+
// } catch { }
|
|
29
|
+
// }
|
|
30
|
+
// return {};
|
|
31
|
+
// });
|
|
32
|
+
// build.onEnd(result => {
|
|
33
|
+
// let config: Config | undefined;
|
|
34
|
+
// if (!result.errors.length) {
|
|
35
|
+
// try {
|
|
36
|
+
// config = require(outFile).default;
|
|
37
|
+
// delete require.cache[outFile!];
|
|
38
|
+
// } catch (e) {
|
|
39
|
+
// result.errors.push({ text: String(e) } as any);
|
|
40
|
+
// }
|
|
41
|
+
// }
|
|
42
|
+
// onBuild(config, result);
|
|
43
|
+
// });
|
|
44
|
+
// },
|
|
45
|
+
// }],
|
|
46
|
+
// });
|
|
47
|
+
const bundle = await rollup.rollup({
|
|
48
|
+
input: tsConfigPath,
|
|
49
|
+
output: {
|
|
50
|
+
file: outFile,
|
|
51
|
+
format: 'cjs',
|
|
52
|
+
sourcemap: true,
|
|
53
|
+
},
|
|
54
|
+
watch: {},
|
|
55
|
+
external: ['typescript'],
|
|
17
56
|
plugins: [{
|
|
18
57
|
name: 'tsslint',
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
catch { }
|
|
58
|
+
resolveId(id, importer) {
|
|
59
|
+
if (!id.endsWith('.ts') && importer) {
|
|
60
|
+
try {
|
|
61
|
+
const jsPath = require.resolve(id, { paths: [path.dirname(importer)] });
|
|
62
|
+
return {
|
|
63
|
+
id: jsPath,
|
|
64
|
+
external: true,
|
|
65
|
+
};
|
|
30
66
|
}
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
67
|
+
catch { }
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
buildEnd(error) {
|
|
71
|
+
let config;
|
|
72
|
+
if (!error) {
|
|
73
|
+
try {
|
|
74
|
+
config = require(outFile).default;
|
|
75
|
+
delete require.cache[outFile];
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
error = { message: String(e) };
|
|
43
79
|
}
|
|
44
|
-
|
|
45
|
-
|
|
80
|
+
}
|
|
81
|
+
onBuild(config, error);
|
|
46
82
|
},
|
|
47
83
|
}],
|
|
48
84
|
});
|
|
49
|
-
|
|
50
|
-
return ctx;
|
|
85
|
+
return bundle;
|
|
51
86
|
}
|
|
52
87
|
exports.watchConfig = watchConfig;
|
|
53
88
|
//# sourceMappingURL=watchConfig.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsslint/typescript-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
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/config": "0.0.1",
|
|
16
15
|
"error-stack-parser": "^2.1.4",
|
|
17
|
-
"esbuild": "^0.19.9",
|
|
18
16
|
"source-map-support": "^0.5.19"
|
|
19
17
|
},
|
|
20
|
-
"
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@tsslint/config": "0.0.2"
|
|
20
|
+
},
|
|
21
|
+
"gitHead": "bdca2792d8b64a11c7c1632c80a2bf25b4985c15"
|
|
21
22
|
}
|