eslint-plugin-ts-type-forge 0.7.3 → 0.8.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/README.md +31 -8
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/plugin.d.mts +2 -0
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +34 -30
- package/dist/plugin.mjs.map +1 -1
- package/dist/rule-types.d.mts +15 -0
- package/dist/rule-types.d.mts.map +1 -1
- package/dist/rule-types.mjs +2 -1
- package/dist/rule-types.mjs.map +1 -1
- package/dist/rules/ast-utils.mjs +224 -103
- package/dist/rules/ast-utils.mjs.map +1 -1
- package/dist/rules/constants.mjs +14 -11
- package/dist/rules/constants.mjs.map +1 -1
- package/dist/rules/import-style.mjs +31 -26
- package/dist/rules/import-style.mjs.map +1 -1
- package/dist/rules/import-utils.mjs +49 -29
- package/dist/rules/import-utils.mjs.map +1 -1
- package/dist/rules/index.mjs +2 -2
- package/dist/rules/index.mjs.map +1 -1
- package/dist/rules/no-side-effect-import.d.mts +19 -0
- package/dist/rules/no-side-effect-import.d.mts.map +1 -0
- package/dist/rules/no-side-effect-import.mjs +55 -0
- package/dist/rules/no-side-effect-import.mjs.map +1 -0
- package/dist/rules/prefer-canonical-length-constrained-tuple.mjs +93 -73
- package/dist/rules/prefer-canonical-length-constrained-tuple.mjs.map +1 -1
- package/dist/rules/prefer-canonical-mutable-record.mjs +88 -75
- package/dist/rules/prefer-canonical-mutable-record.mjs.map +1 -1
- package/dist/rules/prefer-readonly-or-mutable-record.mjs +41 -45
- package/dist/rules/prefer-readonly-or-mutable-record.mjs.map +1 -1
- package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs +48 -46
- package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs.map +1 -1
- package/dist/rules/rewrite-rule-utils.mjs +31 -28
- package/dist/rules/rewrite-rule-utils.mjs.map +1 -1
- package/dist/rules/rules.d.mts +1 -0
- package/dist/rules/rules.d.mts.map +1 -1
- package/dist/rules/rules.mjs +8 -9
- package/dist/rules/rules.mjs.map +1 -1
- package/dist/rules/std-type-rule-utils.mjs +47 -30
- package/dist/rules/std-type-rule-utils.mjs.map +1 -1
- package/dist/types.mjs +2 -2
- package/dist/types.mjs.map +1 -1
- package/package.json +6 -7
- package/src/plugin.mts +1 -0
- package/src/rule-types.mts +16 -0
- package/src/rules/no-side-effect-import.mts +73 -0
- package/src/rules/no-side-effect-import.test.mts +83 -0
- package/src/rules/rules.mts +2 -0
|
@@ -1,37 +1,54 @@
|
|
|
1
|
-
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
1
|
+
import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
|
|
2
2
|
import { Arr } from 'ts-data-forge';
|
|
3
3
|
import { isLocallyBound } from './ast-utils.mjs';
|
|
4
4
|
import { resolveTypeName } from './import-style.mjs';
|
|
5
5
|
import { buildTypeImportFix } from './import-utils.mjs';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export const reportStdTypeReference = (context, node, alternatives, messageIds, importStyle) => {
|
|
17
|
+
const typeName = node.typeName;
|
|
18
|
+
|
|
19
|
+
if (typeName.type !== AST_NODE_TYPES.Identifier)
|
|
20
|
+
return;
|
|
21
|
+
const stdName = typeName.name;
|
|
22
|
+
const candidates = alternatives.get(stdName);
|
|
23
|
+
if (candidates === undefined)
|
|
24
|
+
return;
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if (isLocallyBound(context.sourceCode, node, stdName))
|
|
28
|
+
return;
|
|
29
|
+
const program = context.sourceCode.ast;
|
|
30
|
+
context.report({
|
|
31
|
+
node: typeName,
|
|
32
|
+
messageId: messageIds.report,
|
|
33
|
+
data: { name: stdName, alternatives: formatAlternatives(candidates) },
|
|
34
|
+
suggest: candidates.flatMap((candidate) => {
|
|
35
|
+
const target = resolveTypeName(program, candidate, importStyle);
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
return target === undefined
|
|
39
|
+
? []
|
|
40
|
+
: [
|
|
41
|
+
{
|
|
42
|
+
messageId: messageIds.suggestion,
|
|
43
|
+
data: { name: stdName, replacement: target.localName },
|
|
44
|
+
fix: (fixer) => Arr.toPushed(target.needsImport
|
|
45
|
+
? buildTypeImportFix(fixer, program, candidate)
|
|
46
|
+
: [], fixer.replaceText(typeName, target.localName)),
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
33
51
|
};
|
|
34
|
-
const formatAlternatives = (candidates) => candidates.map((candidate) => `\`${candidate}\``).join(" or ");
|
|
35
52
|
|
|
36
|
-
|
|
37
|
-
//# sourceMappingURL=std-type-rule-utils.mjs.map
|
|
53
|
+
const formatAlternatives = (candidates) => candidates.map((candidate) => `\`${candidate}\``).join(' or ');
|
|
54
|
+
//# sourceMappingURL=std-type-rule-utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"std-type-rule-utils.mjs","sources":["../../src/rules/std-type-rule-utils.mts"],"
|
|
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,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAUxD;;;;;;;;;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;QAAE,OAAO;IAExD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC;IAE9B,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAE7C,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO;IAErC,uEAAuE;IACvE,sDAAsD;IACtD,IAAI,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC;QAAE,OAAO;IAE9D,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,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YACxC,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YAEhE,wEAAwE;YACxE,6DAA6D;YAC7D,OAAO,MAAM,KAAK,SAAS;gBACzB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE;wBACE,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,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC;4BAC/C,CAAC,CAAC,EAAE,EACN,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,CAC9C;qBACJ;iBACF,CAAC;QACR,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/dist/types.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=types.mjs.map
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=types.mjs.map
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.mts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-ts-type-forge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "ESLint rules that steer type declarations toward ts-type-forge idioms.",
|
|
6
6
|
"keywords": [
|
|
@@ -36,21 +36,20 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@typescript-eslint/utils": "~8.68.0",
|
|
39
|
-
"ts-data-forge": "~14.6.
|
|
39
|
+
"ts-data-forge": "~14.6.3",
|
|
40
40
|
"ts-type-forge": "9.2.2"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@typescript-eslint/parser": "8.68.0",
|
|
44
44
|
"@typescript-eslint/rule-tester": "8.68.0",
|
|
45
45
|
"dedent": "1.7.2",
|
|
46
|
-
"eslint-config-typed": "5.
|
|
47
|
-
"eslint-plugin-ts-data-forge": "0.
|
|
48
|
-
"eslint-plugin-ts-fortress": "1.0
|
|
46
|
+
"eslint-config-typed": "5.11.2",
|
|
47
|
+
"eslint-plugin-ts-data-forge": "0.7.0",
|
|
48
|
+
"eslint-plugin-ts-fortress": "1.2.0",
|
|
49
49
|
"prettier": "3.9.6",
|
|
50
50
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
51
51
|
"prettier-plugin-packagejson": "3.0.2",
|
|
52
|
-
"
|
|
53
|
-
"ts-repo-utils": "10.4.0"
|
|
52
|
+
"ts-repo-utils": "10.6.0"
|
|
54
53
|
},
|
|
55
54
|
"peerDependencies": {
|
|
56
55
|
"eslint": ">=9.0.0",
|
package/src/plugin.mts
CHANGED
|
@@ -8,6 +8,7 @@ import { type ESLintFlatConfig, type ESLintPlugin } from './types.mjs';
|
|
|
8
8
|
* a rule without listing it here fails to type-check.
|
|
9
9
|
*/
|
|
10
10
|
const recommendedRules = {
|
|
11
|
+
'ts-type-forge/no-side-effect-import': 'error',
|
|
11
12
|
'ts-type-forge/prefer-canonical-length-constrained-tuple': 'error',
|
|
12
13
|
'ts-type-forge/prefer-canonical-mutable-record': 'error',
|
|
13
14
|
'ts-type-forge/prefer-readonly-or-mutable-record': 'error',
|
package/src/rule-types.mts
CHANGED
|
@@ -27,6 +27,21 @@ type RuleOptionsOf<Name extends keyof typeof tsTypeForgeRules> =
|
|
|
27
27
|
? Options
|
|
28
28
|
: never;
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @description Remove a side-effect-only `import 'ts-type-forge';`, which binds no name and has no runtime entry point to resolve to. `ts-type-forge/global` is left alone.
|
|
32
|
+
*
|
|
33
|
+
* ```md
|
|
34
|
+
* | key | value |
|
|
35
|
+
* | :--------- | :------ |
|
|
36
|
+
* | type | problem |
|
|
37
|
+
* | deprecated | false |
|
|
38
|
+
* | fixable | code |
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
namespace NoSideEffectImport {
|
|
42
|
+
export type RuleEntry = Linter.StringSeverity;
|
|
43
|
+
}
|
|
44
|
+
|
|
30
45
|
/**
|
|
31
46
|
* @description Replace uniform tuple spellings such as `[V, ...V[]]` / `[V, V, ...V[]]` / `[V, V, V]` with the canonical ts-type-forge tuple type.
|
|
32
47
|
*
|
|
@@ -209,6 +224,7 @@ namespace PreferStrictOrRelaxedUtilityType {
|
|
|
209
224
|
}
|
|
210
225
|
|
|
211
226
|
export type EslintTsTypeForgeRules = Readonly<{
|
|
227
|
+
'ts-type-forge/no-side-effect-import': NoSideEffectImport.RuleEntry;
|
|
212
228
|
'ts-type-forge/prefer-canonical-length-constrained-tuple': PreferCanonicalLengthConstrainedTuple.RuleEntry;
|
|
213
229
|
'ts-type-forge/prefer-canonical-mutable-record': PreferCanonicalMutableRecord.RuleEntry;
|
|
214
230
|
'ts-type-forge/prefer-readonly-or-mutable-record': PreferReadonlyOrMutableRecord.RuleEntry;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
import { Arr } from 'ts-data-forge';
|
|
3
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
4
|
+
|
|
5
|
+
type Options = readonly [];
|
|
6
|
+
|
|
7
|
+
type MessageIds = 'removeSideEffectImport';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `import 'ts-type-forge';` binds nothing, and there is nothing for it to run:
|
|
11
|
+
* the package ships declarations only, and its `exports` map offers no runtime
|
|
12
|
+
* condition at all, so the import fails to resolve the moment the module graph
|
|
13
|
+
* is loaded. TypeScript keeps a side-effect import in the emitted JavaScript —
|
|
14
|
+
* that is the one kind it never elides — so this is a runtime error waiting in
|
|
15
|
+
* a file that type-checks.
|
|
16
|
+
*
|
|
17
|
+
* The ambient globals are a separate entry point, `ts-type-forge/global`,
|
|
18
|
+
* usually brought in through `compilerOptions.types` or a triple-slash
|
|
19
|
+
* reference. This rule matches the bare specifier exactly, so that subpath is
|
|
20
|
+
* left alone.
|
|
21
|
+
*/
|
|
22
|
+
export const noSideEffectImport: TSESLint.RuleModule<MessageIds, Options> = {
|
|
23
|
+
meta: {
|
|
24
|
+
type: 'problem',
|
|
25
|
+
docs: {
|
|
26
|
+
description: `Remove a side-effect-only \`import '${TS_TYPE_FORGE_MODULE}';\`, which binds no name and has no runtime entry point to resolve to. \`${TS_TYPE_FORGE_MODULE}/global\` is left alone.`,
|
|
27
|
+
},
|
|
28
|
+
fixable: 'code',
|
|
29
|
+
schema: [],
|
|
30
|
+
messages: {
|
|
31
|
+
removeSideEffectImport: `\`import '${TS_TYPE_FORGE_MODULE}';\` binds no name, and \`${TS_TYPE_FORGE_MODULE}\` ships types only — it has no runtime entry point, so the import throws when the module is loaded. Remove it; the ambient globals come from \`${TS_TYPE_FORGE_MODULE}/global\`, not from this.`,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
create: (context) => ({
|
|
36
|
+
ImportDeclaration: (node) => {
|
|
37
|
+
if (
|
|
38
|
+
node.source.value !== TS_TYPE_FORGE_MODULE ||
|
|
39
|
+
!Arr.isEmpty(node.specifiers)
|
|
40
|
+
) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
context.report({
|
|
45
|
+
node,
|
|
46
|
+
messageId: 'removeSideEffectImport',
|
|
47
|
+
fix: (fixer) => removeStatement(fixer, context.sourceCode, node),
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
}),
|
|
51
|
+
defaultOptions: [],
|
|
52
|
+
} as const;
|
|
53
|
+
|
|
54
|
+
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Removes a statement along with the rest of its line, so that deleting it does
|
|
58
|
+
* not leave a blank line where it was.
|
|
59
|
+
*/
|
|
60
|
+
const removeStatement = (
|
|
61
|
+
fixer: TSESLint.RuleFixer,
|
|
62
|
+
sourceCode: TSESLint.SourceCode,
|
|
63
|
+
node: TSESTree.Node,
|
|
64
|
+
): TSESLint.RuleFix => {
|
|
65
|
+
const restOfLine = /^[^\S\n]*\n/u.exec(
|
|
66
|
+
sourceCode.getText().slice(node.range[1]),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return fixer.removeRange([
|
|
70
|
+
node.range[0],
|
|
71
|
+
node.range[1] + (restOfLine?.[0].length ?? 0),
|
|
72
|
+
]);
|
|
73
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import parser from '@typescript-eslint/parser';
|
|
2
|
+
import { RuleTester } from '@typescript-eslint/rule-tester';
|
|
3
|
+
import dedent from 'dedent';
|
|
4
|
+
import { noSideEffectImport } from './no-side-effect-import.mjs';
|
|
5
|
+
|
|
6
|
+
const tester = new RuleTester({
|
|
7
|
+
languageOptions: {
|
|
8
|
+
parser,
|
|
9
|
+
parserOptions: { ecmaVersion: 2020, sourceType: 'module' },
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('no-side-effect-import', () => {
|
|
14
|
+
tester.run('no-side-effect-import', noSideEffectImport, {
|
|
15
|
+
valid: [
|
|
16
|
+
{
|
|
17
|
+
name: 'accepts a named import',
|
|
18
|
+
code: dedent`
|
|
19
|
+
import { type NonEmptyArray } from 'ts-type-forge';
|
|
20
|
+
|
|
21
|
+
export type Names = NonEmptyArray<string>;
|
|
22
|
+
`,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'leaves the ambient globals entry point alone',
|
|
26
|
+
code: dedent`
|
|
27
|
+
import 'ts-type-forge/global';
|
|
28
|
+
`,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'leaves other side-effect imports alone',
|
|
32
|
+
code: dedent`
|
|
33
|
+
import './polyfills.mjs';
|
|
34
|
+
import 'ts-type-forge-extras';
|
|
35
|
+
`,
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
invalid: [
|
|
39
|
+
{
|
|
40
|
+
name: 'removes a side-effect-only import',
|
|
41
|
+
code: dedent`
|
|
42
|
+
import 'ts-type-forge';
|
|
43
|
+
`,
|
|
44
|
+
output: '',
|
|
45
|
+
errors: [{ messageId: 'removeSideEffectImport' }],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'removes it along with its line',
|
|
49
|
+
code: dedent`
|
|
50
|
+
import 'ts-type-forge';
|
|
51
|
+
import { type Uint32 } from 'ts-type-forge';
|
|
52
|
+
|
|
53
|
+
export type Size = Uint32;
|
|
54
|
+
`,
|
|
55
|
+
output: dedent`
|
|
56
|
+
import { type Uint32 } from 'ts-type-forge';
|
|
57
|
+
|
|
58
|
+
export type Size = Uint32;
|
|
59
|
+
`,
|
|
60
|
+
errors: [{ messageId: 'removeSideEffectImport' }],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'removes every side-effect-only import',
|
|
64
|
+
code: dedent`
|
|
65
|
+
import 'ts-type-forge';
|
|
66
|
+
import 'ts-type-forge/global';
|
|
67
|
+
import 'ts-type-forge';
|
|
68
|
+
|
|
69
|
+
export type Size = number;
|
|
70
|
+
`,
|
|
71
|
+
output: dedent`
|
|
72
|
+
import 'ts-type-forge/global';
|
|
73
|
+
|
|
74
|
+
export type Size = number;
|
|
75
|
+
`,
|
|
76
|
+
errors: [
|
|
77
|
+
{ messageId: 'removeSideEffectImport' },
|
|
78
|
+
{ messageId: 'removeSideEffectImport' },
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
});
|
package/src/rules/rules.mts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type ESLintPlugin } from '../types.mjs';
|
|
2
|
+
import { noSideEffectImport } from './no-side-effect-import.mjs';
|
|
2
3
|
import { preferCanonicalLengthConstrainedTuple } from './prefer-canonical-length-constrained-tuple.mjs';
|
|
3
4
|
import { preferCanonicalMutableRecord } from './prefer-canonical-mutable-record.mjs';
|
|
4
5
|
import { preferReadonlyOrMutableRecord } from './prefer-readonly-or-mutable-record.mjs';
|
|
5
6
|
import { preferStrictOrRelaxedUtilityType } from './prefer-strict-or-relaxed-utility-type.mjs';
|
|
6
7
|
|
|
7
8
|
export const tsTypeForgeRules = {
|
|
9
|
+
'no-side-effect-import': noSideEffectImport,
|
|
8
10
|
'prefer-canonical-length-constrained-tuple':
|
|
9
11
|
preferCanonicalLengthConstrainedTuple,
|
|
10
12
|
'prefer-canonical-mutable-record': preferCanonicalMutableRecord,
|