@tsslint/core 2.0.7 → 3.0.0-alpha.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 CHANGED
@@ -1,5 +1,3 @@
1
- export * from './lib/build';
2
- export * from './lib/watch';
3
1
  import type { Config, LinterContext, Rule, Rules } from '@tsslint/types';
4
2
  import type * as ts from 'typescript';
5
3
  export type FileLintCache = [
@@ -11,7 +9,7 @@ export type FileLintCache = [
11
9
  minimatchResult: Record<string, boolean>
12
10
  ];
13
11
  export type Linter = ReturnType<typeof createLinter>;
14
- export declare function createLinter(ctx: LinterContext, rootDir: string, config: Config | Config[], handleError: (diag: ts.DiagnosticWithLocation, err: Error, stackOffset: number) => void, syntaxOnlyLanguageService?: ts.LanguageService & {
12
+ export declare function createLinter(ctx: LinterContext, rootDir: string, config: Config | Config[], getRelatedInformations: (err: Error, stackIndex: number) => ts.DiagnosticRelatedInformation[], syntaxOnlyLanguageService?: ts.LanguageService & {
15
13
  getNonBoundSourceFile?(fileName: string): ts.SourceFile;
16
14
  }): {
17
15
  lint(fileName: string, cache?: FileLintCache): ts.DiagnosticWithLocation[];
package/index.js CHANGED
@@ -1,27 +1,11 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
3
  exports.createLinter = createLinter;
18
4
  exports.combineCodeFixes = combineCodeFixes;
19
5
  exports.applyTextChanges = applyTextChanges;
20
- __exportStar(require("./lib/build"), exports);
21
- __exportStar(require("./lib/watch"), exports);
22
6
  const path = require("path");
23
7
  const minimatch = require("minimatch");
24
- function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageService) {
8
+ function createLinter(ctx, rootDir, config, getRelatedInformations, syntaxOnlyLanguageService) {
25
9
  const ts = ctx.typescript;
26
10
  const fileRules = new Map();
27
11
  const fileConfigs = new Map();
@@ -51,30 +35,21 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
51
35
  const program = ctx.languageService.getProgram();
52
36
  const file = ctx.languageService.getProgram().getSourceFile(fileName);
53
37
  rulesContext = {
54
- ...ctx,
38
+ typescript: ctx.typescript,
55
39
  file,
56
- sourceFile: file,
57
40
  program,
58
41
  report,
59
- reportError: report,
60
- reportWarning: report,
61
- reportSuggestion: report,
62
42
  };
63
43
  }
64
44
  else {
65
45
  const file = getNonBoundSourceFile(fileName);
66
46
  rulesContext = {
67
- ...ctx,
68
- languageService: syntaxOnlyLanguageService,
47
+ typescript: ctx.typescript,
69
48
  get program() {
70
49
  throw new Error('Not supported');
71
50
  },
72
51
  file,
73
- sourceFile: file,
74
52
  report,
75
- reportError: report,
76
- reportWarning: report,
77
- reportSuggestion: report,
78
53
  };
79
54
  }
80
55
  lintResults.set(fileName, [rulesContext.file, new Map(), []]);
@@ -118,10 +93,10 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
118
93
  shouldRetry = true;
119
94
  }
120
95
  else if (err instanceof Error) {
121
- report(err.stack ?? err.message, 0, 0, ts.DiagnosticCategory.Message, 0, err);
96
+ report(err.stack ?? err.message, 0, 0).at(err, 0);
122
97
  }
123
98
  else {
124
- report(String(err), 0, 0, ts.DiagnosticCategory.Message, Number.MAX_VALUE);
99
+ report(String(err), 0, 0).at(new Error(), Number.MAX_VALUE);
125
100
  }
126
101
  }
127
102
  if (cache && !rule2Mode.get(currentRuleId)) {
@@ -174,29 +149,37 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
174
149
  }
175
150
  lintResult[2] = lintResult[2].filter(refactor => diagnosticSet.has(refactor.diagnostic));
176
151
  return diagnostics;
177
- function report(message, start, end, category = ts.DiagnosticCategory.Message, stackOffset = 1, err) {
152
+ function report(message, start, end) {
178
153
  const error = {
179
- category,
154
+ category: ts.DiagnosticCategory.Message,
180
155
  code: currentRuleId,
181
156
  messageText: message,
182
157
  file: rulesContext.file,
183
158
  start,
184
159
  length: end - start,
185
160
  source: 'tsslint',
186
- relatedInformation: [],
161
+ get relatedInformation() {
162
+ return relatedInformation ??= getRelatedInformations(location[0], location[1]);
163
+ },
164
+ set relatedInformation(value) {
165
+ relatedInformation = value;
166
+ },
187
167
  };
168
+ let location = [new Error(), 1];
169
+ let relatedInformation;
170
+ let cachedObj;
188
171
  if (cache && !rule2Mode.get(currentRuleId)) {
189
- cache[1][currentRuleId] ??= [false, []];
190
- cache[1][currentRuleId][1].push({
172
+ cachedObj = {
191
173
  ...error,
192
174
  file: undefined,
193
175
  relatedInformation: error.relatedInformation?.map(info => ({
194
176
  ...info,
195
177
  file: info.file ? { fileName: info.file.fileName } : undefined,
196
178
  })),
197
- });
179
+ };
180
+ cache[1][currentRuleId] ??= [false, []];
181
+ cache[1][currentRuleId][1].push(cachedObj);
198
182
  }
199
- handleError(error, err ?? new Error(), stackOffset);
200
183
  let lintResult = lintResults.get(fileName);
201
184
  if (!lintResult) {
202
185
  lintResults.set(fileName, lintResult = [rulesContext.file, new Map(), []]);
@@ -206,6 +189,22 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
206
189
  diagnostic2Fixes.set(error, []);
207
190
  const fixes = diagnostic2Fixes.get(error);
208
191
  return {
192
+ at(err, stack) {
193
+ location = [err, stack];
194
+ return this;
195
+ },
196
+ asWarning() {
197
+ error.category = ts.DiagnosticCategory.Warning;
198
+ return this;
199
+ },
200
+ asError() {
201
+ error.category = ts.DiagnosticCategory.Error;
202
+ return this;
203
+ },
204
+ asSuggestion() {
205
+ error.category = ts.DiagnosticCategory.Suggestion;
206
+ return this;
207
+ },
209
208
  withDeprecated() {
210
209
  error.reportsDeprecated = true;
211
210
  return this;
@@ -215,15 +214,27 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
215
214
  return this;
216
215
  },
217
216
  withFix(title, getEdits) {
218
- fixes.push(({ title, getEdits }));
217
+ fixes.push({ title, getEdits });
219
218
  return this;
220
219
  },
221
220
  withRefactor(title, getEdits) {
222
- refactors.push(({
221
+ refactors.push({
223
222
  diagnostic: error,
224
223
  title,
225
224
  getEdits,
226
- }));
225
+ });
226
+ return this;
227
+ },
228
+ withoutCache() {
229
+ if (cachedObj) {
230
+ const ruleCache = cache?.[1][currentRuleId];
231
+ if (ruleCache) {
232
+ const index = ruleCache[1].indexOf(cachedObj);
233
+ if (index >= 0) {
234
+ ruleCache[1].splice(index, 1);
235
+ }
236
+ }
237
+ }
227
238
  return this;
228
239
  },
229
240
  };
@@ -255,10 +266,10 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
255
266
  }
256
267
  const diagStart = diagnostic.start;
257
268
  const diagEnd = diagStart + diagnostic.length;
258
- if ((diagStart >= start && diagStart <= end) ||
259
- (diagEnd >= start && diagEnd <= end) ||
260
- (start >= diagStart && start <= diagEnd) ||
261
- (end >= diagStart && end <= diagEnd)) {
269
+ if ((diagStart >= start && diagStart <= end)
270
+ || (diagEnd >= start && diagEnd <= end)
271
+ || (start >= diagStart && start <= diagEnd)
272
+ || (end >= diagStart && end <= diagEnd)) {
262
273
  let codeFixes = [];
263
274
  for (const action of actions) {
264
275
  codeFixes.push({
@@ -266,7 +277,7 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
266
277
  description: action.title,
267
278
  changes: action.getEdits(),
268
279
  fixId: 'tsslint',
269
- fixAllDescription: 'Fix all TSSLint errors'
280
+ fixAllDescription: 'Fix all TSSLint errors',
270
281
  });
271
282
  }
272
283
  for (const { plugins } of configs) {
@@ -291,10 +302,10 @@ function createLinter(ctx, rootDir, config, handleError, syntaxOnlyLanguageServi
291
302
  const refactor = lintResult[2][i];
292
303
  const diagStart = refactor.diagnostic.start;
293
304
  const diagEnd = diagStart + refactor.diagnostic.length;
294
- if ((diagStart >= start && diagStart <= end) ||
295
- (diagEnd >= start && diagEnd <= end) ||
296
- (start >= diagStart && start <= diagEnd) ||
297
- (end >= diagStart && end <= diagEnd)) {
305
+ if ((diagStart >= start && diagStart <= end)
306
+ || (diagEnd >= start && diagEnd <= end)
307
+ || (start >= diagStart && start <= diagEnd)
308
+ || (end >= diagStart && end <= diagEnd)) {
298
309
  result.push({
299
310
  name: `tsslint:${i}`,
300
311
  description: refactor.title,
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "@tsslint/core",
3
- "version": "2.0.7",
3
+ "version": "3.0.0-alpha.1",
4
4
  "license": "MIT",
5
+ "engines": {
6
+ "node": ">=22.6.0"
7
+ },
5
8
  "files": [
6
9
  "**/*.js",
7
10
  "**/*.d.ts"
@@ -12,15 +15,8 @@
12
15
  "directory": "packages/core"
13
16
  },
14
17
  "dependencies": {
15
- "@tsslint/types": "2.0.7",
16
- "esbuild": ">=0.17.0",
18
+ "@tsslint/types": "3.0.0-alpha.1",
17
19
  "minimatch": "^10.0.1"
18
20
  },
19
- "devDependencies": {
20
- "@clack/prompts": "^0.8.2"
21
- },
22
- "scripts": {
23
- "postinstall": "node scripts/cleanCache.js"
24
- },
25
- "gitHead": "db83a7c7526c3245d2ffa6fe1c9fb04e77387959"
26
- }
21
+ "gitHead": "eacd205927cda18d084e78cc21115578792f3955"
22
+ }
package/lib/build.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function buildConfig(configFilePath: string, createHash?: (path: string) => string, spinner?: ReturnType<typeof import('@clack/prompts').spinner>, stopSnipper?: (message: string, code?: number) => void): Promise<string | undefined>;
package/lib/build.js DELETED
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildConfig = buildConfig;
4
- const watch_1 = require("./watch");
5
- const _path = require("path");
6
- function buildConfig(configFilePath, createHash,
7
- // @ts-expect-error
8
- spinner, stopSnipper) {
9
- const buildStart = Date.now();
10
- const configFileDisplayPath = _path.relative(process.cwd(), configFilePath);
11
- spinner?.message('Building ' + configFileDisplayPath);
12
- return new Promise(async (resolve) => {
13
- try {
14
- await (0, watch_1.watchConfig)(configFilePath, builtConfig => {
15
- if (builtConfig) {
16
- stopSnipper?.('Built ' + configFileDisplayPath + ' in ' + (Date.now() - buildStart) + 'ms');
17
- }
18
- else {
19
- stopSnipper?.('Failed to build ' + configFileDisplayPath + ' in ' + (Date.now() - buildStart) + 'ms', 1);
20
- }
21
- resolve(builtConfig);
22
- }, false, createHash);
23
- }
24
- catch (e) {
25
- stopSnipper?.('Failed to build ' + configFileDisplayPath + ' in ' + (Date.now() - buildStart) + 'ms', 1);
26
- resolve(undefined);
27
- }
28
- });
29
- }
30
- //# sourceMappingURL=build.js.map
package/lib/watch.d.ts DELETED
@@ -1,14 +0,0 @@
1
- import esbuild = require('esbuild');
2
- export declare function watchConfig(configFilePath: string, onBuild: (config: string | undefined, result: esbuild.BuildResult) => void, watch?: boolean, createHash?: (path: string) => string): Promise<esbuild.BuildContext<{
3
- entryPoints: string[];
4
- bundle: true;
5
- sourcemap: true;
6
- outfile: string;
7
- format: "esm";
8
- platform: "node";
9
- plugins: {
10
- name: string;
11
- setup(build: esbuild.PluginBuild): void;
12
- }[];
13
- }>>;
14
- export declare function getDotTsslintPath(configFilePath: string): string;
package/lib/watch.js DELETED
@@ -1,73 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.watchConfig = watchConfig;
4
- exports.getDotTsslintPath = getDotTsslintPath;
5
- const esbuild = require("esbuild");
6
- const _path = require("path");
7
- const fs = require("fs");
8
- const url = require("url");
9
- async function watchConfig(configFilePath, onBuild, watch = true, createHash = btoa) {
10
- const outDir = getDotTsslintPath(configFilePath);
11
- const outFileName = createHash(_path.relative(outDir, configFilePath)) + '.mjs';
12
- const outFile = _path.join(outDir, outFileName);
13
- const resultHandler = (result) => {
14
- if (!result.errors.length) {
15
- onBuild(outFile, result);
16
- }
17
- else {
18
- onBuild(undefined, result);
19
- }
20
- };
21
- const ctx = await esbuild.context({
22
- entryPoints: [configFilePath],
23
- bundle: true,
24
- sourcemap: true,
25
- outfile: outFile,
26
- format: 'esm',
27
- platform: 'node',
28
- plugins: [{
29
- name: 'tsslint',
30
- setup(build) {
31
- build.onResolve({ filter: /.*/ }, ({ path, resolveDir }) => {
32
- if (!isTsFile(path)) {
33
- try {
34
- const maybeJsPath = require.resolve(path, { paths: [resolveDir] });
35
- if (!isTsFile(maybeJsPath) && fs.existsSync(maybeJsPath)) {
36
- return {
37
- path: url.pathToFileURL(maybeJsPath).toString(),
38
- external: true,
39
- };
40
- }
41
- }
42
- catch { }
43
- }
44
- return {};
45
- });
46
- if (watch) {
47
- build.onEnd(resultHandler);
48
- }
49
- },
50
- }],
51
- });
52
- if (watch) {
53
- await ctx.watch();
54
- }
55
- else {
56
- try {
57
- const result = await ctx.rebuild(); // could throw
58
- await ctx.dispose();
59
- resultHandler(result);
60
- }
61
- catch (e) {
62
- throw e;
63
- }
64
- }
65
- return ctx;
66
- }
67
- function isTsFile(path) {
68
- return path.endsWith('.ts') || path.endsWith('.tsx') || path.endsWith('.cts') || path.endsWith('.mts');
69
- }
70
- function getDotTsslintPath(configFilePath) {
71
- return _path.resolve(configFilePath, '..', 'node_modules', '.tsslint');
72
- }
73
- //# sourceMappingURL=watch.js.map
@@ -1,20 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- let dir = __dirname;
5
-
6
- while (true) {
7
- const cachePath = path.join(dir, 'node_modules', '.tsslint');
8
- if (fs.existsSync(cachePath)) {
9
- console.log(`Removing ${cachePath}`);
10
- fs.rmSync(cachePath, { recursive: true });
11
- break;
12
- }
13
-
14
- const parentDir = path.resolve(dir, '..');
15
- if (parentDir === dir) {
16
- break;
17
- }
18
-
19
- dir = parentDir;
20
- }