eslint-plugin-ts-type-forge 0.8.7 → 0.8.9
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/dist/rule-types.d.mts +0 -3
- package/dist/rule-types.d.mts.map +1 -1
- package/dist/rule-types.mjs +4 -1
- package/dist/rule-types.mjs.map +1 -1
- package/dist/rules/ast-utils.d.mts +0 -11
- package/dist/rules/ast-utils.d.mts.map +1 -1
- package/dist/rules/ast-utils.mjs +1 -16
- package/dist/rules/ast-utils.mjs.map +1 -1
- package/dist/rules/import-style.d.mts.map +1 -1
- package/dist/rules/import-style.mjs +3 -2
- package/dist/rules/import-style.mjs.map +1 -1
- package/dist/rules/import-utils.d.mts +4 -16
- package/dist/rules/import-utils.d.mts.map +1 -1
- package/dist/rules/import-utils.mjs +1 -21
- package/dist/rules/import-utils.mjs.map +1 -1
- package/dist/rules/prefer-canonical-mutable-record.d.mts.map +1 -1
- package/dist/rules/prefer-canonical-mutable-record.mjs +3 -3
- package/dist/rules/prefer-canonical-mutable-record.mjs.map +1 -1
- package/dist/rules/rewrite-rule-utils.d.mts.map +1 -1
- package/dist/rules/rewrite-rule-utils.mjs +12 -5
- package/dist/rules/rewrite-rule-utils.mjs.map +1 -1
- package/dist/rules/std-type-rule-utils.d.mts.map +1 -1
- package/dist/rules/std-type-rule-utils.mjs +13 -11
- package/dist/rules/std-type-rule-utils.mjs.map +1 -1
- package/package.json +11 -10
- package/src/rule-types.mts +5 -9
- package/src/rules/ast-utils.mts +0 -21
- package/src/rules/import-style.mts +3 -6
- package/src/rules/import-utils.mts +4 -52
- package/src/rules/prefer-canonical-mutable-record.mts +10 -6
- package/src/rules/rewrite-rule-utils.mts +18 -7
- package/src/rules/std-type-rule-utils.mts +23 -21
package/dist/rule-types.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
2
|
import type { Linter } from 'eslint';
|
|
3
|
-
import type { TypeEq } from 'ts-type-forge';
|
|
4
3
|
import type { tsTypeForgeRules } from './rules/index.mjs';
|
|
5
4
|
type SpreadOptionsIfIsArray<T extends readonly [Linter.StringSeverity, unknown]> = T[1] extends readonly unknown[] ? readonly [Linter.StringSeverity, ...T[1]] : T;
|
|
6
5
|
/**
|
|
@@ -189,7 +188,5 @@ export type EslintTsTypeForgeRulesOption = Readonly<{
|
|
|
189
188
|
'ts-type-forge/prefer-readonly-or-mutable-record': PreferReadonlyOrMutableRecord.Options;
|
|
190
189
|
'ts-type-forge/prefer-strict-or-relaxed-utility-type': PreferStrictOrRelaxedUtilityType.Options;
|
|
191
190
|
}>;
|
|
192
|
-
type AssertTrue<B extends true> = B;
|
|
193
|
-
export type RuleNamesAreInSync = AssertTrue<TypeEq<keyof EslintTsTypeForgeRules, `ts-type-forge/${keyof typeof tsTypeForgeRules}`>>;
|
|
194
191
|
export {};
|
|
195
192
|
//# sourceMappingURL=rule-types.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-types.d.mts","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"rule-types.d.mts","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"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"}
|
package/dist/rule-types.mjs
CHANGED
package/dist/rule-types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-types.mjs","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"AAAA,oBAAoB"}
|
|
1
|
+
{"version":3,"file":"rule-types.mjs","sourceRoot":"","sources":["../src/rule-types.mts"],"names":[],"mappings":"AAAA,oBAAoB;AAOpB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAyO3C,8EAA8E;AAC9E,8DAA8D;AAC9D,UAAU,CAGR,GAAG,CAAC,CAAC"}
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';
|
|
2
|
-
/**
|
|
3
|
-
* Whether `name` resolves to a declaration in this file (a type alias, an
|
|
4
|
-
* interface, a class, an import, …) rather than to the ambient standard-library
|
|
5
|
-
* type of the same name.
|
|
6
|
-
*
|
|
7
|
-
* The `defs` check is what separates the two: ESLint materializes an *implicit*
|
|
8
|
-
* global variable for every unresolved reference, so `findVariable` also
|
|
9
|
-
* succeeds for `Exclude` in a file that never declares it. Only a variable with
|
|
10
|
-
* at least one definition was actually written down somewhere in this file.
|
|
11
|
-
*/
|
|
12
|
-
export declare const isLocallyBound: (sourceCode: TSESLint.SourceCode, node: TSESTree.Node, name: string) => boolean;
|
|
13
2
|
export type UniformTupleShape = Readonly<{
|
|
14
3
|
/** The node an autofix must replace: the tuple, or the `readonly` operator. */
|
|
15
4
|
node: TSESTree.Node;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.d.mts","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ast-utils.d.mts","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAKlC,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,+EAA+E;IAC/E,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,mBAAmB,UACvB,QAAQ,CAAC,WAAW,cACf,QAAQ,CAAC,UAAU,KAC9B,iBAAiB,GAAG,SAyEtB,CAAC"}
|
package/dist/rules/ast-utils.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AST_NODE_TYPES,
|
|
1
|
+
import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
|
|
2
2
|
import { Arr, hasKey, isNonNullObject, isRecord } from 'ts-data-forge';
|
|
3
3
|
|
|
4
4
|
|
|
@@ -11,21 +11,6 @@ import { Arr, hasKey, isNonNullObject, isRecord } from 'ts-data-forge';
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
export const isLocallyBound = (sourceCode, node, name) => {
|
|
15
|
-
const variable = ASTUtils.findVariable(sourceCode.getScope(node), name);
|
|
16
|
-
return variable !== null && Arr.isNonEmpty(variable.defs);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
14
|
|
|
30
15
|
|
|
31
16
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.mjs","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,
|
|
1
|
+
{"version":3,"file":"ast-utils.mjs","sourceRoot":"","sources":["../../src/rules/ast-utils.mts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-style.d.mts","sourceRoot":"","sources":["../../src/rules/import-style.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"import-style.d.mts","sourceRoot":"","sources":["../../src/rules/import-style.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAOnE,mEAAmE;AACnE,KAAK,UAAU,GAAG,OAAO,CACvB,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EACjE,SAAS,OAAO,EAAE,CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE7C,eAAO,MAAM,oBAAoB,EAAE,WAAqB,CAAC;AAEzD,eAAO,MAAM,4BAA4B,EAAE,UAW1C,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,YACjB,QAAQ,CAAC,OAAO,iBACV,MAAM,eACR,WAAW,KACvB,QAAQ,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,SAW1D,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { getImportDeclarations, getImportedLocalName } from 'eslint-rule-forge';
|
|
1
2
|
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
2
|
-
import {
|
|
3
|
+
import { hasConflictingDeclaration } from './import-utils.mjs';
|
|
3
4
|
export const DEFAULT_IMPORT_STYLE = 'named';
|
|
4
5
|
export const IMPORT_STYLE_SCHEMA_PROPERTY = {
|
|
5
6
|
type: 'string',
|
|
@@ -23,7 +24,7 @@ export const IMPORT_STYLE_SCHEMA_PROPERTY = {
|
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
export const resolveTypeName = (program, canonicalName, importStyle) => {
|
|
26
|
-
const importedLocalName = getImportedLocalName(
|
|
27
|
+
const importedLocalName = getImportedLocalName(getImportDeclarations(program, TS_TYPE_FORGE_MODULE), canonicalName);
|
|
27
28
|
return importedLocalName !== undefined
|
|
28
29
|
? { localName: importedLocalName, needsImport: false }
|
|
29
30
|
: hasConflictingDeclaration(program, canonicalName)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-style.mjs","sourceRoot":"","sources":["../../src/rules/import-style.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"import-style.mjs","sourceRoot":"","sources":["../../src/rules/import-style.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAY/D,MAAM,CAAC,MAAM,oBAAoB,GAAgB,OAAO,CAAC;AAEzD,MAAM,CAAC,MAAM,4BAA4B,GAAe;IACtD,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE;QACX,mDAAmD;QACnD,2DAA2D;QAC3D,6BAA6B,oBAAoB,MAAM;QACvD,yDAAyD;QACzD,6DAA6D;QAC7D,UAAU;KACX,CAAC,IAAI,CAAC,GAAG,CAAC;CACZ,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,OAAyB,EACzB,aAAqB,EACrB,WAAwB,EAC2C,EAAE;IACrE,MAAM,iBAAiB,GAAG,oBAAoB,CAC5C,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,CAAC,EACpD,aAAa,CACd,CAAC;IAEF,OAAO,iBAAiB,KAAK,SAAS;QACpC,CAAC,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,KAAK,EAAE;QACtD,CAAC,CAAC,yBAAyB,CAAC,OAAO,EAAE,aAAa,CAAC;YACjD,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,KAAK,OAAO,EAAE,CAAC;AAC3E,CAAC,CAAC"}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
/** Every `import ... from 'ts-type-forge'` declaration in the file. */
|
|
3
|
-
export declare const getTsTypeForgeImports: (program: TSESTree.Program) => readonly TSESTree.ImportDeclaration[];
|
|
4
|
-
/**
|
|
5
|
-
* Returns the in-scope local name a given ts-type-forge export is imported as
|
|
6
|
-
* (handling aliases such as `import type { NonEmptyArray as NEA }` → `'NEA'`),
|
|
7
|
-
* or `undefined` when it is not imported. Used so autofixes reference the
|
|
8
|
-
* binding that actually exists rather than the canonical name.
|
|
9
|
-
*/
|
|
10
|
-
export declare const getImportedLocalName: (importDeclarations: readonly TSESTree.ImportDeclaration[], importedName: string) => string | undefined;
|
|
1
|
+
import { type TSESTree } from '@typescript-eslint/utils';
|
|
11
2
|
/**
|
|
12
3
|
* Whether the file already binds `name` to something that is not the
|
|
13
4
|
* ts-type-forge export of the same name — a local type alias / interface /
|
|
@@ -15,12 +6,9 @@ export declare const getImportedLocalName: (importDeclarations: readonly TSESTre
|
|
|
15
6
|
* `name` must bail out in that case, because the rewritten type would resolve
|
|
16
7
|
* to the wrong declaration. (ts-type-forge's own sources, which declare
|
|
17
8
|
* `NonEmptyArray` themselves, are the motivating example.)
|
|
9
|
+
*
|
|
10
|
+
* Not `hasForeignBinding` from eslint-rule-forge: `resolveTypeName` decides
|
|
11
|
+
* once per file, with no node to read a scope at.
|
|
18
12
|
*/
|
|
19
13
|
export declare const hasConflictingDeclaration: (program: TSESTree.Program, name: string) => boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Inserts `import { type <name> } from 'ts-type-forge';` at the top of the
|
|
22
|
-
* file. Placement is deliberately naive: prettier-plugin-organize-imports (or
|
|
23
|
-
* any equivalent) merges and sorts it afterwards.
|
|
24
|
-
*/
|
|
25
|
-
export declare const buildTypeImportFix: (fixer: TSESLint.RuleFixer, program: TSESTree.Program, name: string) => readonly TSESLint.RuleFix[];
|
|
26
14
|
//# sourceMappingURL=import-utils.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-utils.d.mts","sourceRoot":"","sources":["../../src/rules/import-utils.mts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"import-utils.d.mts","sourceRoot":"","sources":["../../src/rules/import-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAKzE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,YAC3B,QAAQ,CAAC,OAAO,QACnB,MAAM,KACX,OAgBC,CAAC"}
|
|
@@ -1,25 +1,13 @@
|
|
|
1
|
-
import { AST_NODE_TYPES
|
|
1
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
2
|
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
export const getTsTypeForgeImports = (program) => program.body.filter((node) => node.type === AST_NODE_TYPES.ImportDeclaration &&
|
|
6
|
-
node.source.value === TS_TYPE_FORGE_MODULE);
|
|
7
5
|
|
|
8
6
|
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
|
|
13
|
-
export const getImportedLocalName = (importDeclarations, importedName) => importDeclarations
|
|
14
|
-
.flatMap((declaration) => declaration.specifiers)
|
|
15
|
-
.find((specifier) => specifier.type === AST_NODE_TYPES.ImportSpecifier &&
|
|
16
|
-
(specifier.imported.type === AST_NODE_TYPES.Identifier
|
|
17
|
-
? specifier.imported.name
|
|
18
|
-
: specifier.imported.value) === importedName)?.local.name;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
11
|
|
|
24
12
|
|
|
25
13
|
|
|
@@ -34,14 +22,6 @@ export const hasConflictingDeclaration = (program, name) => program.body.some((n
|
|
|
34
22
|
? node.declaration
|
|
35
23
|
: node, name);
|
|
36
24
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export const buildTypeImportFix = (fixer, program, name) => [
|
|
43
|
-
fixer.insertTextBefore(program, `import { type ${name} } from '${TS_TYPE_FORGE_MODULE}';\n`),
|
|
44
|
-
];
|
|
45
25
|
const declaresName = (node, name) => {
|
|
46
26
|
if (node === null || node === undefined) {
|
|
47
27
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-utils.mjs","sourceRoot":"","sources":["../../src/rules/import-utils.mts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"import-utils.mjs","sourceRoot":"","sources":["../../src/rules/import-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,uEAAuE;AAEvE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,OAAyB,EACzB,IAAY,EACH,EAAE,CACX,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACzB,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB,EAAE,CAAC;QACnD,OAAO,CACL,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,oBAAoB;YAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CACnE,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CACjB,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB;QACjD,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,wBAAwB;QACrD,CAAC,CAAC,IAAI,CAAC,WAAW;QAClB,CAAC,CAAC,IAAI,EACR,IAAI,CACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL,MAAM,YAAY,GAAG,CACnB,IAAsC,EACtC,IAAY,EACH,EAAE;IACX,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IACE,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB;QACnD,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB;QACnD,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB,EAC9C,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;IAC/B,CAAC;IAED,OAAO,CACL,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,KAAK,IAAI,CACxE,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-canonical-mutable-record.d.mts","sourceRoot":"","sources":["../../src/rules/prefer-canonical-mutable-record.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"prefer-canonical-mutable-record.d.mts","sourceRoot":"","sources":["../../src/rules/prefer-canonical-mutable-record.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAEd,MAAM,0BAA0B,CAAC;AAclC,KAAK,OAAO,GAAG,SAAS;IACtB,QAAQ,CAAC;QACP,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;KAClC,CAAC,CAAC;CACJ,CAAC;AAEF,KAAK,UAAU,GAAG,kBAAkB,CAAC;AAiBrC,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,UAAU,CAC5D,UAAU,EACV,OAAO,CAmHC,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
|
|
2
|
+
import { getImportDeclarations, getImportedLocalName, isLocallyBound, } from 'eslint-rule-forge';
|
|
2
3
|
import { Arr } from 'ts-data-forge';
|
|
3
|
-
import {
|
|
4
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
4
5
|
import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY, } from './import-style.mjs';
|
|
5
|
-
import { getImportedLocalName, getTsTypeForgeImports, } from './import-utils.mjs';
|
|
6
6
|
import { reportTypeRewrites } from './rewrite-rule-utils.mjs';
|
|
7
7
|
|
|
8
8
|
|
|
@@ -39,7 +39,7 @@ export const preferCanonicalMutableRecord = {
|
|
|
39
39
|
create: (context) => {
|
|
40
40
|
const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;
|
|
41
41
|
const sourceCode = context.sourceCode;
|
|
42
|
-
const tsTypeForgeImports =
|
|
42
|
+
const tsTypeForgeImports = getImportDeclarations(sourceCode.ast, TS_TYPE_FORGE_MODULE);
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-canonical-mutable-record.mjs","sourceRoot":"","sources":["../../src/rules/prefer-canonical-mutable-record.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,0BAA0B,CAAC;AAClC,OAAO,
|
|
1
|
+
{"version":3,"file":"prefer-canonical-mutable-record.mjs","sourceRoot":"","sources":["../../src/rules/prefer-canonical-mutable-record.mts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewrite-rule-utils.d.mts","sourceRoot":"","sources":["../../src/rules/rewrite-rule-utils.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"rewrite-rule-utils.d.mts","sourceRoot":"","sources":["../../src/rules/rewrite-rule-utils.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAInE,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIvE,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,SAAS,MAAM,WACjD,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC,YACnD,SAAS,WAAW,EAAE,aACrB,UAAU,eACR,WAAW,KACvB,IA+CF,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { buildNamedImportFix } from 'eslint-rule-forge';
|
|
1
2
|
import { Arr } from 'ts-data-forge';
|
|
3
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
2
4
|
import { resolveTypeName } from './import-style.mjs';
|
|
3
|
-
import { buildTypeImportFix } from './import-utils.mjs';
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
|
|
@@ -13,11 +14,15 @@ import { buildTypeImportFix } from './import-utils.mjs';
|
|
|
13
14
|
export const reportTypeRewrites = (context, rewrites, messageId, importStyle) => {
|
|
14
15
|
const sourceCode = context.sourceCode;
|
|
15
16
|
const program = sourceCode.ast;
|
|
16
|
-
const resolved =
|
|
17
|
-
|
|
17
|
+
const resolved = Arr.generate(function* () {
|
|
18
|
+
for (const rewrite of rewrites) {
|
|
19
|
+
const target = resolveTypeName(program, rewrite.canonicalName, importStyle);
|
|
18
20
|
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
if (target !== undefined) {
|
|
23
|
+
yield { rewrite, target };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
21
26
|
});
|
|
22
27
|
const importNames = Arr.uniq(resolved
|
|
23
28
|
.filter(({ target }) => target.needsImport)
|
|
@@ -29,7 +34,9 @@ export const reportTypeRewrites = (context, rewrites, messageId, importStyle) =>
|
|
|
29
34
|
messageId,
|
|
30
35
|
data: { original: sourceCode.getText(rewrite.node), replacement },
|
|
31
36
|
fix: (fixer) => Arr.toPushed(index === 0
|
|
32
|
-
? importNames.flatMap((name) =>
|
|
37
|
+
? importNames.flatMap((name) => buildNamedImportFix(fixer, program, TS_TYPE_FORGE_MODULE, [
|
|
38
|
+
`type ${name}`,
|
|
39
|
+
]))
|
|
33
40
|
: [], fixer.replaceText(rewrite.node, replacement)),
|
|
34
41
|
});
|
|
35
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewrite-rule-utils.mjs","sourceRoot":"","sources":["../../src/rules/rewrite-rule-utils.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"rewrite-rule-utils.mjs","sourceRoot":"","sources":["../../src/rules/rewrite-rule-utils.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AAYvE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,OAA6D,EAC7D,QAAgC,EAChC,SAAqB,EACrB,WAAwB,EAClB,EAAE;IACR,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAEtC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC;IAE/B,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACrC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,eAAe,CAC5B,OAAO,EACP,OAAO,CAAC,aAAa,EACrB,WAAW,CACZ,CAAC;YAEF,2EAA2E;YAC3E,0CAA0C;YAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAC1B,QAAQ;SACL,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;SAC1C,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,CAC/C,CAAC;IAEF,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9D,MAAM,WAAW,GAAG,GAAG,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC;QAE/D,OAAO,CAAC,MAAM,CAAC;YACb,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,SAAS;YACT,IAAI,EAAE,EAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE;YACjE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CACb,GAAG,CAAC,QAAQ,CACV,KAAK,KAAK,CAAC;gBACT,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3B,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE;oBACxD,QAAQ,IAAI,EAAE;iBACf,CAAC,CACH;gBACH,CAAC,CAAC,EAAE,EACN,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAC7C;SACJ,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-type-rule-utils.d.mts","sourceRoot":"","sources":["../../src/rules/std-type-rule-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"std-type-rule-utils.d.mts","sourceRoot":"","sources":["../../src/rules/std-type-rule-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIvE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;AAEzE;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,GAAI,UAAU,SAAS,MAAM,WACrD,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,SAAS,OAAO,EAAE,CAAC,QACvD,QAAQ,CAAC,eAAe,gBAChB,mBAAmB,cACrB,QAAQ,CAAC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAAC,eACvD,WAAW,KACvB,IAoDF,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
|
|
2
|
+
import { buildNamedImportFix, isLocallyBound } from 'eslint-rule-forge';
|
|
2
3
|
import { Arr } from 'ts-data-forge';
|
|
3
|
-
import {
|
|
4
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
4
5
|
import { resolveTypeName } from './import-style.mjs';
|
|
5
|
-
import { buildTypeImportFix } from './import-utils.mjs';
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
@@ -34,21 +34,23 @@ export const reportStdTypeReference = (context, node, alternatives, messageIds,
|
|
|
34
34
|
node: typeName,
|
|
35
35
|
messageId: messageIds.report,
|
|
36
36
|
data: { name: stdName, alternatives: formatAlternatives(candidates) },
|
|
37
|
-
suggest:
|
|
38
|
-
|
|
37
|
+
suggest: Arr.generate(function* () {
|
|
38
|
+
for (const candidate of candidates) {
|
|
39
|
+
const target = resolveTypeName(program, candidate, importStyle);
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
: [
|
|
44
|
-
{
|
|
42
|
+
if (target !== undefined) {
|
|
43
|
+
yield {
|
|
45
44
|
messageId: messageIds.suggestion,
|
|
46
45
|
data: { name: stdName, replacement: target.localName },
|
|
47
46
|
fix: (fixer) => Arr.toPushed(target.needsImport
|
|
48
|
-
?
|
|
47
|
+
? buildNamedImportFix(fixer, program, TS_TYPE_FORGE_MODULE, [
|
|
48
|
+
`type ${candidate}`,
|
|
49
|
+
])
|
|
49
50
|
: [], fixer.replaceText(typeName, target.localName)),
|
|
50
|
-
}
|
|
51
|
-
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
52
54
|
}),
|
|
53
55
|
});
|
|
54
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-type-rule-utils.mjs","sourceRoot":"","sources":["../../src/rules/std-type-rule-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"std-type-rule-utils.mjs","sourceRoot":"","sources":["../../src/rules/std-type-rule-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AAUvE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAA6D,EAC7D,IAA8B,EAC9B,YAAiC,EACjC,UAAoE,EACpE,WAAwB,EAClB,EAAE;IACR,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAE/B,yEAAyE;IACzE,IAAI,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU,EAAE,CAAC;QAChD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC;IAE9B,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAE7C,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,uEAAuE;IACvE,sDAAsD;IACtD,IAAI,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;QACtD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;IAEvC,OAAO,CAAC,MAAM,CAAC;QACb,IAAI,EAAE,QAAQ;QACd,SAAS,EAAE,UAAU,CAAC,MAAM;QAC5B,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,kBAAkB,CAAC,UAAU,CAAC,EAAE;QACrE,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC7B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;gBAEhE,wEAAwE;gBACxE,6DAA6D;gBAC7D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBACzB,MAAM;wBACJ,SAAS,EAAE,UAAU,CAAC,UAAU;wBAChC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE;wBACtD,GAAG,EAAE,CAAC,KAAyB,EAA+B,EAAE,CAC9D,GAAG,CAAC,QAAQ,CACV,MAAM,CAAC,WAAW;4BAChB,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE;gCACxD,QAAQ,SAAS,EAAE;6BACpB,CAAC;4BACJ,CAAC,CAAC,EAAE,EACN,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAC9C;qBACJ,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC,CAAC;KACH,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,+EAA+E;AAC/E,MAAM,kBAAkB,GAAG,CAAC,UAA6B,EAAU,EAAE,CACnE,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-ts-type-forge",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "ESLint rules that steer type declarations toward ts-type-forge idioms.",
|
|
6
6
|
"keywords": [
|
|
@@ -36,16 +36,17 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@typescript-eslint/utils": "~8.71.1",
|
|
39
|
-
"
|
|
39
|
+
"eslint-rule-forge": "^0.2.0",
|
|
40
|
+
"ts-data-forge": "~14.8.0",
|
|
40
41
|
"ts-type-forge": "9.2.2"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@typescript-eslint/parser": "8.71.1",
|
|
44
45
|
"@typescript-eslint/rule-tester": "8.71.1",
|
|
45
46
|
"dedent": "1.7.2",
|
|
46
|
-
"eslint-config-typed": "5.
|
|
47
|
-
"eslint-plugin-ts-data-forge": "0.
|
|
48
|
-
"eslint-plugin-ts-fortress": "1.3.
|
|
47
|
+
"eslint-config-typed": "5.19.0",
|
|
48
|
+
"eslint-plugin-ts-data-forge": "0.9.0",
|
|
49
|
+
"eslint-plugin-ts-fortress": "1.3.4",
|
|
49
50
|
"prettier": "3.9.9",
|
|
50
51
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
51
52
|
"prettier-plugin-packagejson": "3.0.2",
|
|
@@ -66,15 +67,15 @@
|
|
|
66
67
|
"scripts": {
|
|
67
68
|
"build": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ./scripts/cmd/build.mts",
|
|
68
69
|
"check:ext": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ./scripts/cmd/check-ext.mts",
|
|
69
|
-
"check:lint": "oxlint . && eslint .",
|
|
70
|
-
"check:test": "pnpm run z:vitest run",
|
|
71
|
-
"check:test:cov": "pnpm run z:vitest run --coverage",
|
|
72
|
-
"check:types": "node ../../node_modules/typescript-native/bin/tsc --noEmit",
|
|
70
|
+
"check:lint": "node ../../tools/scripts/cmd/assert-deps-built.mts && oxlint . && eslint .",
|
|
71
|
+
"check:test": "node ../../tools/scripts/cmd/assert-deps-built.mts && pnpm run z:vitest run",
|
|
72
|
+
"check:test:cov": "node ../../tools/scripts/cmd/assert-deps-built.mts && pnpm run z:vitest run --coverage",
|
|
73
|
+
"check:types": "node ../../tools/scripts/cmd/assert-deps-built.mts && node ../../node_modules/typescript-native/bin/tsc --noEmit",
|
|
73
74
|
"doc": "pnpm run gen:readme",
|
|
74
75
|
"fix:fmt": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ../../libs/ts-repo-utils/src/cmd/format-uncommitted.mts --cwd .",
|
|
75
76
|
"fix:fmt:diff": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ../../libs/ts-repo-utils/src/cmd/format-diff-from.mts origin/main --cwd .",
|
|
76
77
|
"fix:fmt:full": "pnpm run z:prettier .",
|
|
77
|
-
"fix:lint": "oxlint . --fix && eslint . --fix",
|
|
78
|
+
"fix:lint": "node ../../tools/scripts/cmd/assert-deps-built.mts && oxlint . --fix && eslint . --fix",
|
|
78
79
|
"fmt": "pnpm run fix:fmt",
|
|
79
80
|
"gen": "run-s gen:rule-types gen:readme",
|
|
80
81
|
"gen:readme": "tsx --tsconfig ../../tools/configs/tsconfig.tsx.json ./scripts/cmd/embed-examples.mts",
|
package/src/rule-types.mts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import type { TSESLint } from '@typescript-eslint/utils';
|
|
7
7
|
import type { Linter } from 'eslint';
|
|
8
|
-
import
|
|
8
|
+
import { expectType } from 'ts-data-forge';
|
|
9
9
|
import type { tsTypeForgeRules } from './rules/index.mjs';
|
|
10
10
|
|
|
11
11
|
type SpreadOptionsIfIsArray<
|
|
@@ -240,11 +240,7 @@ export type EslintTsTypeForgeRulesOption = Readonly<{
|
|
|
240
240
|
|
|
241
241
|
// If this assertion fails to type-check, this generated file has drifted from
|
|
242
242
|
// the actual plugin rules — re-run `pnpm run gen:rule-types`.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
keyof EslintTsTypeForgeRules,
|
|
248
|
-
`ts-type-forge/${keyof typeof tsTypeForgeRules}`
|
|
249
|
-
>
|
|
250
|
-
>;
|
|
243
|
+
expectType<
|
|
244
|
+
keyof EslintTsTypeForgeRules,
|
|
245
|
+
`ts-type-forge/${keyof typeof tsTypeForgeRules}`
|
|
246
|
+
>('=');
|
package/src/rules/ast-utils.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AST_NODE_TYPES,
|
|
3
|
-
ASTUtils,
|
|
4
3
|
type TSESLint,
|
|
5
4
|
type TSESTree,
|
|
6
5
|
} from '@typescript-eslint/utils';
|
|
@@ -8,26 +7,6 @@ import { Arr, hasKey, isNonNullObject, isRecord } from 'ts-data-forge';
|
|
|
8
7
|
|
|
9
8
|
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
10
9
|
|
|
11
|
-
/**
|
|
12
|
-
* Whether `name` resolves to a declaration in this file (a type alias, an
|
|
13
|
-
* interface, a class, an import, …) rather than to the ambient standard-library
|
|
14
|
-
* type of the same name.
|
|
15
|
-
*
|
|
16
|
-
* The `defs` check is what separates the two: ESLint materializes an *implicit*
|
|
17
|
-
* global variable for every unresolved reference, so `findVariable` also
|
|
18
|
-
* succeeds for `Exclude` in a file that never declares it. Only a variable with
|
|
19
|
-
* at least one definition was actually written down somewhere in this file.
|
|
20
|
-
*/
|
|
21
|
-
export const isLocallyBound = (
|
|
22
|
-
sourceCode: TSESLint.SourceCode,
|
|
23
|
-
node: TSESTree.Node,
|
|
24
|
-
name: string,
|
|
25
|
-
): boolean => {
|
|
26
|
-
const variable = ASTUtils.findVariable(sourceCode.getScope(node), name);
|
|
27
|
-
|
|
28
|
-
return variable !== null && Arr.isNonEmpty(variable.defs);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
10
|
export type UniformTupleShape = Readonly<{
|
|
32
11
|
/** The node an autofix must replace: the tuple, or the `readonly` operator. */
|
|
33
12
|
node: TSESTree.Node;
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
import { getImportDeclarations, getImportedLocalName } from 'eslint-rule-forge';
|
|
2
3
|
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
3
|
-
import {
|
|
4
|
-
getImportedLocalName,
|
|
5
|
-
getTsTypeForgeImports,
|
|
6
|
-
hasConflictingDeclaration,
|
|
7
|
-
} from './import-utils.mjs';
|
|
4
|
+
import { hasConflictingDeclaration } from './import-utils.mjs';
|
|
8
5
|
|
|
9
6
|
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
10
7
|
|
|
@@ -46,7 +43,7 @@ export const resolveTypeName = (
|
|
|
46
43
|
importStyle: ImportStyle,
|
|
47
44
|
): Readonly<{ localName: string; needsImport: boolean }> | undefined => {
|
|
48
45
|
const importedLocalName = getImportedLocalName(
|
|
49
|
-
|
|
46
|
+
getImportDeclarations(program, TS_TYPE_FORGE_MODULE),
|
|
50
47
|
canonicalName,
|
|
51
48
|
);
|
|
52
49
|
|
|
@@ -1,42 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AST_NODE_TYPES,
|
|
3
|
-
type TSESLint,
|
|
4
|
-
type TSESTree,
|
|
5
|
-
} from '@typescript-eslint/utils';
|
|
1
|
+
import { AST_NODE_TYPES, type TSESTree } from '@typescript-eslint/utils';
|
|
6
2
|
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
7
3
|
|
|
8
4
|
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
9
5
|
|
|
10
|
-
/** Every `import ... from 'ts-type-forge'` declaration in the file. */
|
|
11
|
-
export const getTsTypeForgeImports = (
|
|
12
|
-
program: TSESTree.Program,
|
|
13
|
-
): readonly TSESTree.ImportDeclaration[] =>
|
|
14
|
-
program.body.filter(
|
|
15
|
-
(node): node is TSESTree.ImportDeclaration =>
|
|
16
|
-
node.type === AST_NODE_TYPES.ImportDeclaration &&
|
|
17
|
-
node.source.value === TS_TYPE_FORGE_MODULE,
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Returns the in-scope local name a given ts-type-forge export is imported as
|
|
22
|
-
* (handling aliases such as `import type { NonEmptyArray as NEA }` → `'NEA'`),
|
|
23
|
-
* or `undefined` when it is not imported. Used so autofixes reference the
|
|
24
|
-
* binding that actually exists rather than the canonical name.
|
|
25
|
-
*/
|
|
26
|
-
export const getImportedLocalName = (
|
|
27
|
-
importDeclarations: readonly TSESTree.ImportDeclaration[],
|
|
28
|
-
importedName: string,
|
|
29
|
-
): string | undefined =>
|
|
30
|
-
importDeclarations
|
|
31
|
-
.flatMap((declaration) => declaration.specifiers)
|
|
32
|
-
.find(
|
|
33
|
-
(specifier) =>
|
|
34
|
-
specifier.type === AST_NODE_TYPES.ImportSpecifier &&
|
|
35
|
-
(specifier.imported.type === AST_NODE_TYPES.Identifier
|
|
36
|
-
? specifier.imported.name
|
|
37
|
-
: specifier.imported.value) === importedName,
|
|
38
|
-
)?.local.name;
|
|
39
|
-
|
|
40
6
|
/**
|
|
41
7
|
* Whether the file already binds `name` to something that is not the
|
|
42
8
|
* ts-type-forge export of the same name — a local type alias / interface /
|
|
@@ -44,6 +10,9 @@ export const getImportedLocalName = (
|
|
|
44
10
|
* `name` must bail out in that case, because the rewritten type would resolve
|
|
45
11
|
* to the wrong declaration. (ts-type-forge's own sources, which declare
|
|
46
12
|
* `NonEmptyArray` themselves, are the motivating example.)
|
|
13
|
+
*
|
|
14
|
+
* Not `hasForeignBinding` from eslint-rule-forge: `resolveTypeName` decides
|
|
15
|
+
* once per file, with no node to read a scope at.
|
|
47
16
|
*/
|
|
48
17
|
export const hasConflictingDeclaration = (
|
|
49
18
|
program: TSESTree.Program,
|
|
@@ -66,23 +35,6 @@ export const hasConflictingDeclaration = (
|
|
|
66
35
|
);
|
|
67
36
|
});
|
|
68
37
|
|
|
69
|
-
/**
|
|
70
|
-
* Inserts `import { type <name> } from 'ts-type-forge';` at the top of the
|
|
71
|
-
* file. Placement is deliberately naive: prettier-plugin-organize-imports (or
|
|
72
|
-
* any equivalent) merges and sorts it afterwards.
|
|
73
|
-
*/
|
|
74
|
-
export const buildTypeImportFix = (
|
|
75
|
-
fixer: TSESLint.RuleFixer,
|
|
76
|
-
program: TSESTree.Program,
|
|
77
|
-
name: string,
|
|
78
|
-
): readonly TSESLint.RuleFix[] =>
|
|
79
|
-
[
|
|
80
|
-
fixer.insertTextBefore(
|
|
81
|
-
program,
|
|
82
|
-
`import { type ${name} } from '${TS_TYPE_FORGE_MODULE}';\n`,
|
|
83
|
-
),
|
|
84
|
-
] as const;
|
|
85
|
-
|
|
86
38
|
const declaresName = (
|
|
87
39
|
node: TSESTree.Node | null | undefined,
|
|
88
40
|
name: string,
|
|
@@ -3,16 +3,17 @@ import {
|
|
|
3
3
|
type TSESLint,
|
|
4
4
|
type TSESTree,
|
|
5
5
|
} from '@typescript-eslint/utils';
|
|
6
|
+
import {
|
|
7
|
+
getImportDeclarations,
|
|
8
|
+
getImportedLocalName,
|
|
9
|
+
isLocallyBound,
|
|
10
|
+
} from 'eslint-rule-forge';
|
|
6
11
|
import { Arr } from 'ts-data-forge';
|
|
7
|
-
import {
|
|
12
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
8
13
|
import {
|
|
9
14
|
DEFAULT_IMPORT_STYLE,
|
|
10
15
|
IMPORT_STYLE_SCHEMA_PROPERTY,
|
|
11
16
|
} from './import-style.mjs';
|
|
12
|
-
import {
|
|
13
|
-
getImportedLocalName,
|
|
14
|
-
getTsTypeForgeImports,
|
|
15
|
-
} from './import-utils.mjs';
|
|
16
17
|
import { reportTypeRewrites, type TypeRewrite } from './rewrite-rule-utils.mjs';
|
|
17
18
|
|
|
18
19
|
type Options = readonly [
|
|
@@ -69,7 +70,10 @@ export const preferCanonicalMutableRecord: TSESLint.RuleModule<
|
|
|
69
70
|
|
|
70
71
|
const sourceCode = context.sourceCode;
|
|
71
72
|
|
|
72
|
-
const tsTypeForgeImports =
|
|
73
|
+
const tsTypeForgeImports = getImportDeclarations(
|
|
74
|
+
sourceCode.ast,
|
|
75
|
+
TS_TYPE_FORGE_MODULE,
|
|
76
|
+
);
|
|
73
77
|
|
|
74
78
|
/**
|
|
75
79
|
* Whether this reference denotes the ts-type-forge type `canonicalName` —
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
import { buildNamedImportFix } from 'eslint-rule-forge';
|
|
2
3
|
import { Arr } from 'ts-data-forge';
|
|
4
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
3
5
|
import { resolveTypeName, type ImportStyle } from './import-style.mjs';
|
|
4
|
-
import { buildTypeImportFix } from './import-utils.mjs';
|
|
5
6
|
|
|
6
7
|
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
7
8
|
|
|
@@ -32,12 +33,20 @@ export const reportTypeRewrites = <MessageIds extends string>(
|
|
|
32
33
|
|
|
33
34
|
const program = sourceCode.ast;
|
|
34
35
|
|
|
35
|
-
const resolved =
|
|
36
|
-
|
|
36
|
+
const resolved = Arr.generate(function* () {
|
|
37
|
+
for (const rewrite of rewrites) {
|
|
38
|
+
const target = resolveTypeName(
|
|
39
|
+
program,
|
|
40
|
+
rewrite.canonicalName,
|
|
41
|
+
importStyle,
|
|
42
|
+
);
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
// The name is already bound to something else in this file, so the rewrite
|
|
45
|
+
// would resolve to the wrong declaration.
|
|
46
|
+
if (target !== undefined) {
|
|
47
|
+
yield { rewrite, target };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
41
50
|
});
|
|
42
51
|
|
|
43
52
|
const importNames = Arr.uniq(
|
|
@@ -57,7 +66,9 @@ export const reportTypeRewrites = <MessageIds extends string>(
|
|
|
57
66
|
Arr.toPushed(
|
|
58
67
|
index === 0
|
|
59
68
|
? importNames.flatMap((name) =>
|
|
60
|
-
|
|
69
|
+
buildNamedImportFix(fixer, program, TS_TYPE_FORGE_MODULE, [
|
|
70
|
+
`type ${name}`,
|
|
71
|
+
]),
|
|
61
72
|
)
|
|
62
73
|
: [],
|
|
63
74
|
fixer.replaceText(rewrite.node, replacement),
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
type TSESLint,
|
|
4
4
|
type TSESTree,
|
|
5
5
|
} from '@typescript-eslint/utils';
|
|
6
|
+
import { buildNamedImportFix, isLocallyBound } from 'eslint-rule-forge';
|
|
6
7
|
import { Arr } from 'ts-data-forge';
|
|
7
|
-
import {
|
|
8
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
8
9
|
import { resolveTypeName, type ImportStyle } from './import-style.mjs';
|
|
9
|
-
import { buildTypeImportFix } from './import-utils.mjs';
|
|
10
10
|
|
|
11
11
|
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
12
12
|
|
|
@@ -60,26 +60,28 @@ export const reportStdTypeReference = <MessageIds extends string>(
|
|
|
60
60
|
node: typeName,
|
|
61
61
|
messageId: messageIds.report,
|
|
62
62
|
data: { name: stdName, alternatives: formatAlternatives(candidates) },
|
|
63
|
-
suggest:
|
|
64
|
-
|
|
63
|
+
suggest: Arr.generate(function* () {
|
|
64
|
+
for (const candidate of candidates) {
|
|
65
|
+
const target = resolveTypeName(program, candidate, importStyle);
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
// The replacement name is already bound to something else in this file,
|
|
68
|
+
// so rewriting to it would resolve to the wrong declaration.
|
|
69
|
+
if (target !== undefined) {
|
|
70
|
+
yield {
|
|
71
|
+
messageId: messageIds.suggestion,
|
|
72
|
+
data: { name: stdName, replacement: target.localName },
|
|
73
|
+
fix: (fixer: TSESLint.RuleFixer): readonly TSESLint.RuleFix[] =>
|
|
74
|
+
Arr.toPushed(
|
|
75
|
+
target.needsImport
|
|
76
|
+
? buildNamedImportFix(fixer, program, TS_TYPE_FORGE_MODULE, [
|
|
77
|
+
`type ${candidate}`,
|
|
78
|
+
])
|
|
79
|
+
: [],
|
|
80
|
+
fixer.replaceText(typeName, target.localName),
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
83
85
|
}),
|
|
84
86
|
});
|
|
85
87
|
};
|