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.
Files changed (49) hide show
  1. package/README.md +31 -8
  2. package/dist/index.mjs +2 -2
  3. package/dist/index.mjs.map +1 -1
  4. package/dist/plugin.d.mts +2 -0
  5. package/dist/plugin.d.mts.map +1 -1
  6. package/dist/plugin.mjs +34 -30
  7. package/dist/plugin.mjs.map +1 -1
  8. package/dist/rule-types.d.mts +15 -0
  9. package/dist/rule-types.d.mts.map +1 -1
  10. package/dist/rule-types.mjs +2 -1
  11. package/dist/rule-types.mjs.map +1 -1
  12. package/dist/rules/ast-utils.mjs +224 -103
  13. package/dist/rules/ast-utils.mjs.map +1 -1
  14. package/dist/rules/constants.mjs +14 -11
  15. package/dist/rules/constants.mjs.map +1 -1
  16. package/dist/rules/import-style.mjs +31 -26
  17. package/dist/rules/import-style.mjs.map +1 -1
  18. package/dist/rules/import-utils.mjs +49 -29
  19. package/dist/rules/import-utils.mjs.map +1 -1
  20. package/dist/rules/index.mjs +2 -2
  21. package/dist/rules/index.mjs.map +1 -1
  22. package/dist/rules/no-side-effect-import.d.mts +19 -0
  23. package/dist/rules/no-side-effect-import.d.mts.map +1 -0
  24. package/dist/rules/no-side-effect-import.mjs +55 -0
  25. package/dist/rules/no-side-effect-import.mjs.map +1 -0
  26. package/dist/rules/prefer-canonical-length-constrained-tuple.mjs +93 -73
  27. package/dist/rules/prefer-canonical-length-constrained-tuple.mjs.map +1 -1
  28. package/dist/rules/prefer-canonical-mutable-record.mjs +88 -75
  29. package/dist/rules/prefer-canonical-mutable-record.mjs.map +1 -1
  30. package/dist/rules/prefer-readonly-or-mutable-record.mjs +41 -45
  31. package/dist/rules/prefer-readonly-or-mutable-record.mjs.map +1 -1
  32. package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs +48 -46
  33. package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs.map +1 -1
  34. package/dist/rules/rewrite-rule-utils.mjs +31 -28
  35. package/dist/rules/rewrite-rule-utils.mjs.map +1 -1
  36. package/dist/rules/rules.d.mts +1 -0
  37. package/dist/rules/rules.d.mts.map +1 -1
  38. package/dist/rules/rules.mjs +8 -9
  39. package/dist/rules/rules.mjs.map +1 -1
  40. package/dist/rules/std-type-rule-utils.mjs +47 -30
  41. package/dist/rules/std-type-rule-utils.mjs.map +1 -1
  42. package/dist/types.mjs +2 -2
  43. package/dist/types.mjs.map +1 -1
  44. package/package.json +6 -7
  45. package/src/plugin.mts +1 -0
  46. package/src/rule-types.mts +16 -0
  47. package/src/rules/no-side-effect-import.mts +73 -0
  48. package/src/rules/no-side-effect-import.test.mts +83 -0
  49. package/src/rules/rules.mts +2 -0
@@ -1,83 +1,96 @@
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
- import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY } from './import-style.mjs';
5
- import { getTsTypeForgeImports, getImportedLocalName } from './import-utils.mjs';
4
+ 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
+
9
+
10
+
11
+
8
12
  const WRAPPED_RECORD_NAMES = [
9
- "Record",
10
- "ReadonlyRecord",
11
- "MutableRecord"
13
+ 'Record',
14
+ 'ReadonlyRecord',
15
+ 'MutableRecord',
12
16
  ];
13
- const MUTABLE_TYPE_NAME = "Mutable";
14
- const MUTABLE_RECORD_TYPE_NAME = "MutableRecord";
15
- const preferCanonicalMutableRecord = {
16
- meta: {
17
- type: "suggestion",
18
- docs: {
19
- description: "Replace `Mutable<Record<K, V>>` (and `Mutable` applied to `ReadonlyRecord` / `MutableRecord`) with the canonical ts-type-forge `MutableRecord<K, V>`."
20
- },
21
- fixable: "code",
22
- schema: [
23
- {
24
- type: "object",
25
- properties: {
26
- importStyle: IMPORT_STYLE_SCHEMA_PROPERTY
17
+ const MUTABLE_TYPE_NAME = 'Mutable';
18
+ const MUTABLE_RECORD_TYPE_NAME = 'MutableRecord';
19
+ export const preferCanonicalMutableRecord = {
20
+ meta: {
21
+ type: 'suggestion',
22
+ docs: {
23
+ description: 'Replace `Mutable<Record<K, V>>` (and `Mutable` applied to `ReadonlyRecord` / `MutableRecord`) with the canonical ts-type-forge `MutableRecord<K, V>`.',
27
24
  },
28
- additionalProperties: false
29
- }
30
- ],
31
- messages: {
32
- useMutableRecord: "Replace `{{original}}` with `{{replacement}}` from ts-type-forge."
33
- }
34
- },
35
- create: (context) => {
36
- const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;
37
- const sourceCode = context.sourceCode;
38
- const tsTypeForgeImports = getTsTypeForgeImports(sourceCode.ast);
39
- const referencesTsTypeForgeType = (node, canonicalName) => {
40
- const typeName = node.typeName;
41
- if (typeName.type !== AST_NODE_TYPES.Identifier) return false;
42
- return typeName.name === getImportedLocalName(tsTypeForgeImports, canonicalName) || typeName.name === canonicalName && !isLocallyBound(sourceCode, node, canonicalName);
43
- };
44
- const mut_rewrites = [];
45
- return {
46
- TSTypeReference: (node) => {
47
- if (!referencesTsTypeForgeType(node, MUTABLE_TYPE_NAME)) return;
48
- const wrapped = node.typeArguments?.params;
49
- if (wrapped === void 0 || !Arr.isFixedLengthArray(1, wrapped)) {
50
- return;
51
- }
52
- const record = wrapped[0];
53
- if (record.type !== AST_NODE_TYPES.TSTypeReference || WRAPPED_RECORD_NAMES.every(
54
- (name) => !referencesTsTypeForgeType(record, name)
55
- )) {
56
- return;
57
- }
58
- const recordTypeArgs = record.typeArguments?.params;
59
- if (recordTypeArgs === void 0 || !Arr.isFixedLengthArray(2, recordTypeArgs)) {
60
- return;
61
- }
62
- const [K, V] = recordTypeArgs;
63
- mut_rewrites.push({
64
- node,
65
- canonicalName: MUTABLE_RECORD_TYPE_NAME,
66
- typeArgs: `${sourceCode.getText(K)}, ${sourceCode.getText(V)}`
67
- });
68
- },
69
- "Program:exit": () => {
70
- reportTypeRewrites(
71
- context,
72
- mut_rewrites,
73
- "useMutableRecord",
74
- importStyle
75
- );
76
- }
77
- };
78
- },
79
- defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }]
80
- };
25
+ fixable: 'code',
26
+ schema: [
27
+ {
28
+ type: 'object',
29
+ properties: {
30
+ importStyle: IMPORT_STYLE_SCHEMA_PROPERTY,
31
+ },
32
+ additionalProperties: false,
33
+ },
34
+ ],
35
+ messages: {
36
+ useMutableRecord: 'Replace `{{original}}` with `{{replacement}}` from ts-type-forge.',
37
+ },
38
+ },
39
+ create: (context) => {
40
+ const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;
41
+ const sourceCode = context.sourceCode;
42
+ const tsTypeForgeImports = getTsTypeForgeImports(sourceCode.ast);
43
+
44
+
81
45
 
82
- export { preferCanonicalMutableRecord };
83
- //# sourceMappingURL=prefer-canonical-mutable-record.mjs.map
46
+
47
+
48
+
49
+
50
+
51
+ const referencesTsTypeForgeType = (
52
+
53
+ node, canonicalName) => {
54
+ const typeName = node.typeName;
55
+
56
+ if (typeName.type !== AST_NODE_TYPES.Identifier)
57
+ return false;
58
+ return (typeName.name ===
59
+ getImportedLocalName(tsTypeForgeImports, canonicalName) ||
60
+ (typeName.name === canonicalName &&
61
+ !isLocallyBound(sourceCode, node, canonicalName)));
62
+ };
63
+ const mut_rewrites = [];
64
+ return {
65
+ TSTypeReference: (node) => {
66
+ if (!referencesTsTypeForgeType(node, MUTABLE_TYPE_NAME))
67
+ return;
68
+ const wrapped = node.typeArguments?.params;
69
+ if (wrapped === undefined || !Arr.isFixedLengthArray(1, wrapped)) {
70
+ return;
71
+ }
72
+ const record = wrapped[0];
73
+ if (record.type !== AST_NODE_TYPES.TSTypeReference ||
74
+ WRAPPED_RECORD_NAMES.every((name) => !referencesTsTypeForgeType(record, name))) {
75
+ return;
76
+ }
77
+ const recordTypeArgs = record.typeArguments?.params;
78
+ if (recordTypeArgs === undefined ||
79
+ !Arr.isFixedLengthArray(2, recordTypeArgs)) {
80
+ return;
81
+ }
82
+ const [K, V] = recordTypeArgs;
83
+ mut_rewrites.push({
84
+ node,
85
+ canonicalName: MUTABLE_RECORD_TYPE_NAME,
86
+ typeArgs: `${sourceCode.getText(K)}, ${sourceCode.getText(V)}`,
87
+ });
88
+ },
89
+ 'Program:exit': () => {
90
+ reportTypeRewrites(context, mut_rewrites, 'useMutableRecord', importStyle);
91
+ },
92
+ };
93
+ },
94
+ defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }],
95
+ };
96
+ //# sourceMappingURL=prefer-canonical-mutable-record.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-canonical-mutable-record.mjs","sources":["../../src/rules/prefer-canonical-mutable-record.mts"],"sourcesContent":["import {\n AST_NODE_TYPES,\n type TSESLint,\n type TSESTree,\n} from '@typescript-eslint/utils';\nimport { Arr } from 'ts-data-forge';\nimport { isLocallyBound } from './ast-utils.mjs';\nimport {\n DEFAULT_IMPORT_STYLE,\n IMPORT_STYLE_SCHEMA_PROPERTY,\n} from './import-style.mjs';\nimport {\n getImportedLocalName,\n getTsTypeForgeImports,\n} from './import-utils.mjs';\nimport { reportTypeRewrites, type TypeRewrite } from './rewrite-rule-utils.mjs';\n\ntype Options = readonly [\n Readonly<{\n importStyle?: 'global' | 'named';\n }>?,\n];\n\ntype MessageIds = 'useMutableRecord';\n\n/**\n * The record spellings that `Mutable<…>` collapses to `MutableRecord<K, V>`.\n * `Mutable` strips the `readonly` modifier from every property, so applied to\n * any of these it produces exactly the type `MutableRecord` spells directly.\n */\nconst WRAPPED_RECORD_NAMES = [\n 'Record',\n 'ReadonlyRecord',\n 'MutableRecord',\n] as const;\n\nconst MUTABLE_TYPE_NAME = 'Mutable';\n\nconst MUTABLE_RECORD_TYPE_NAME = 'MutableRecord';\n\nexport const preferCanonicalMutableRecord: TSESLint.RuleModule<\n MessageIds,\n Options\n> = {\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Replace `Mutable<Record<K, V>>` (and `Mutable` applied to `ReadonlyRecord` / `MutableRecord`) with the canonical ts-type-forge `MutableRecord<K, V>`.',\n },\n fixable: 'code',\n schema: [\n {\n type: 'object',\n properties: {\n importStyle: IMPORT_STYLE_SCHEMA_PROPERTY,\n },\n additionalProperties: false,\n },\n ],\n messages: {\n useMutableRecord:\n 'Replace `{{original}}` with `{{replacement}}` from ts-type-forge.',\n },\n },\n\n create: (context) => {\n const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;\n\n const sourceCode = context.sourceCode;\n\n const tsTypeForgeImports = getTsTypeForgeImports(sourceCode.ast);\n\n /**\n * Whether this reference denotes the ts-type-forge type `canonicalName` —\n * either through an import from ts-type-forge (aliases included) or as the\n * bare ambient global. A name bound to anything else in this file (a local\n * alias, an import from another module) denotes that declaration instead.\n * The built-in `Record` goes through the same check: ts-type-forge exports\n * no `Record`, so only the unbound global spelling matches.\n */\n const referencesTsTypeForgeType = (\n // eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types\n node: TSESTree.TSTypeReference,\n canonicalName: string,\n ): boolean => {\n const typeName = node.typeName;\n\n // `ns.Mutable` / `import('…').Mutable` never denote the ts-type-forge type.\n if (typeName.type !== AST_NODE_TYPES.Identifier) return false;\n\n return (\n typeName.name ===\n getImportedLocalName(tsTypeForgeImports, canonicalName) ||\n (typeName.name === canonicalName &&\n !isLocallyBound(sourceCode, node, canonicalName))\n );\n };\n\n const mut_rewrites: TypeRewrite[] = [];\n\n return {\n TSTypeReference: (node) => {\n if (!referencesTsTypeForgeType(node, MUTABLE_TYPE_NAME)) return;\n\n const wrapped = node.typeArguments?.params;\n\n if (wrapped === undefined || !Arr.isFixedLengthArray(1, wrapped)) {\n return;\n }\n\n const record = wrapped[0];\n\n if (\n record.type !== AST_NODE_TYPES.TSTypeReference ||\n WRAPPED_RECORD_NAMES.every(\n (name) => !referencesTsTypeForgeType(record, name),\n )\n ) {\n return;\n }\n\n const recordTypeArgs = record.typeArguments?.params;\n\n if (\n recordTypeArgs === undefined ||\n !Arr.isFixedLengthArray(2, recordTypeArgs)\n ) {\n return;\n }\n\n const [K, V] = recordTypeArgs;\n\n mut_rewrites.push({\n node,\n canonicalName: MUTABLE_RECORD_TYPE_NAME,\n typeArgs: `${sourceCode.getText(K)}, ${sourceCode.getText(V)}`,\n });\n },\n 'Program:exit': () => {\n reportTypeRewrites(\n context,\n mut_rewrites,\n 'useMutableRecord',\n importStyle,\n );\n },\n };\n },\n defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }],\n} as const;\n"],"names":[],"mappings":"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"}
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,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAoB,MAAM,0BAA0B,CAAC;AAUhF;;;;GAIG;AACH,MAAM,oBAAoB,GAAG;IAC3B,QAAQ;IACR,gBAAgB;IAChB,eAAe;CACP,CAAC;AAEX,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAEpC,MAAM,wBAAwB,GAAG,eAAe,CAAC;AAEjD,MAAM,CAAC,MAAM,4BAA4B,GAGrC;IACF,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,uJAAuJ;SAC1J;QACD,OAAO,EAAE,MAAM;QACf,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,WAAW,EAAE,4BAA4B;iBAC1C;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,QAAQ,EAAE;YACR,gBAAgB,EACd,mEAAmE;SACtE;KACF;IAED,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,oBAAoB,CAAC;QAE5E,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAEtC,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAEjE;;;;;;;WAOG;QACH,MAAM,yBAAyB,GAAG;QAChC,8EAA8E;QAC9E,IAA8B,EAC9B,aAAqB,EACZ,EAAE;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAE/B,4EAA4E;YAC5E,IAAI,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;gBAAE,OAAO,KAAK,CAAC;YAE9D,OAAO,CACL,QAAQ,CAAC,IAAI;gBACX,oBAAoB,CAAC,kBAAkB,EAAE,aAAa,CAAC;gBACzD,CAAC,QAAQ,CAAC,IAAI,KAAK,aAAa;oBAC9B,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CACpD,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,YAAY,GAAkB,EAAE,CAAC;QAEvC,OAAO;YACL,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,IAAI,CAAC,yBAAyB,CAAC,IAAI,EAAE,iBAAiB,CAAC;oBAAE,OAAO;gBAEhE,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC;gBAE3C,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;oBACjE,OAAO;gBACT,CAAC;gBAED,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAE1B,IACE,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,eAAe;oBAC9C,oBAAoB,CAAC,KAAK,CACxB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,yBAAyB,CAAC,MAAM,EAAE,IAAI,CAAC,CACnD,EACD,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC;gBAEpD,IACE,cAAc,KAAK,SAAS;oBAC5B,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,EAAE,cAAc,CAAC,EAC1C,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC;gBAE9B,YAAY,CAAC,IAAI,CAAC;oBAChB,IAAI;oBACJ,aAAa,EAAE,wBAAwB;oBACvC,QAAQ,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;iBAC/D,CAAC,CAAC;YACL,CAAC;YACD,cAAc,EAAE,GAAG,EAAE;gBACnB,kBAAkB,CAChB,OAAO,EACP,YAAY,EACZ,kBAAkB,EAClB,WAAW,CACZ,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;CAC/C,CAAC"}
@@ -1,49 +1,45 @@
1
- import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY } from './import-style.mjs';
2
- import { reportStdTypeReference } from './std-type-rule-utils.mjs';
1
+ import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY, } from './import-style.mjs';
2
+ import { reportStdTypeReference, } from './std-type-rule-utils.mjs';
3
3
 
4
- const ALTERNATIVES = /* @__PURE__ */ new Map([
5
- ["Record", ["ReadonlyRecord", "MutableRecord"]]
4
+
5
+
6
+
7
+
8
+ const ALTERNATIVES = new Map([
9
+ ['Record', ['ReadonlyRecord', 'MutableRecord']],
6
10
  ]);
7
- const preferReadonlyOrMutableRecord = {
8
- meta: {
9
- type: "suggestion",
10
- docs: {
11
- description: "Replace the built-in `Record` with the ts-type-forge `ReadonlyRecord` or `MutableRecord`, so that the mutability of the record is stated rather than implied."
12
- },
13
- hasSuggestions: true,
14
- schema: [
15
- {
16
- type: "object",
17
- properties: {
18
- importStyle: IMPORT_STYLE_SCHEMA_PROPERTY
11
+ export const preferReadonlyOrMutableRecord = {
12
+ meta: {
13
+ type: 'suggestion',
14
+ docs: {
15
+ description: 'Replace the built-in `Record` with the ts-type-forge `ReadonlyRecord` or `MutableRecord`, so that the mutability of the record is stated rather than implied.',
19
16
  },
20
- additionalProperties: false
21
- }
22
- ],
23
- messages: {
24
- useReadonlyOrMutableRecord: "Use {{alternatives}} from ts-type-forge instead of the built-in `{{name}}`.",
25
- replaceWith: "Replace `{{name}}` with `{{replacement}}`."
26
- }
27
- },
28
- create: (context) => {
29
- const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;
30
- return {
31
- TSTypeReference: (node) => {
32
- reportStdTypeReference(
33
- context,
34
- node,
35
- ALTERNATIVES,
36
- {
37
- report: "useReadonlyOrMutableRecord",
38
- suggestion: "replaceWith"
39
- },
40
- importStyle
41
- );
42
- }
43
- };
44
- },
45
- defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }]
17
+ hasSuggestions: true,
18
+ schema: [
19
+ {
20
+ type: 'object',
21
+ properties: {
22
+ importStyle: IMPORT_STYLE_SCHEMA_PROPERTY,
23
+ },
24
+ additionalProperties: false,
25
+ },
26
+ ],
27
+ messages: {
28
+ useReadonlyOrMutableRecord: 'Use {{alternatives}} from ts-type-forge instead of the built-in `{{name}}`.',
29
+ replaceWith: 'Replace `{{name}}` with `{{replacement}}`.',
30
+ },
31
+ },
32
+ create: (context) => {
33
+ const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;
34
+ return {
35
+ TSTypeReference: (node) => {
36
+ reportStdTypeReference(context, node, ALTERNATIVES, {
37
+ report: 'useReadonlyOrMutableRecord',
38
+ suggestion: 'replaceWith',
39
+ }, importStyle);
40
+ },
41
+ };
42
+ },
43
+ defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }],
46
44
  };
47
-
48
- export { preferReadonlyOrMutableRecord };
49
- //# sourceMappingURL=prefer-readonly-or-mutable-record.mjs.map
45
+ //# sourceMappingURL=prefer-readonly-or-mutable-record.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-readonly-or-mutable-record.mjs","sources":["../../src/rules/prefer-readonly-or-mutable-record.mts"],"sourcesContent":["import { type TSESLint } from '@typescript-eslint/utils';\nimport {\n DEFAULT_IMPORT_STYLE,\n IMPORT_STYLE_SCHEMA_PROPERTY,\n} from './import-style.mjs';\nimport {\n reportStdTypeReference,\n type StdTypeAlternatives,\n} from './std-type-rule-utils.mjs';\n\ntype Options = readonly [\n Readonly<{\n importStyle?: 'global' | 'named';\n }>?,\n];\n\ntype MessageIds = 'useReadonlyOrMutableRecord' | 'replaceWith';\n\n/**\n * `Record` says nothing about whether the properties may be reassigned, so the\n * mutability of every record type spelled with it is decided by whoever reads\n * it. The ts-type-forge pair spells it out.\n */\nconst ALTERNATIVES: StdTypeAlternatives = new Map([\n ['Record', ['ReadonlyRecord', 'MutableRecord']],\n]);\n\nexport const preferReadonlyOrMutableRecord: TSESLint.RuleModule<\n MessageIds,\n Options\n> = {\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Replace the built-in `Record` with the ts-type-forge `ReadonlyRecord` or `MutableRecord`, so that the mutability of the record is stated rather than implied.',\n },\n hasSuggestions: true,\n schema: [\n {\n type: 'object',\n properties: {\n importStyle: IMPORT_STYLE_SCHEMA_PROPERTY,\n },\n additionalProperties: false,\n },\n ],\n messages: {\n useReadonlyOrMutableRecord:\n 'Use {{alternatives}} from ts-type-forge instead of the built-in `{{name}}`.',\n replaceWith: 'Replace `{{name}}` with `{{replacement}}`.',\n },\n },\n\n create: (context) => {\n const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;\n\n return {\n TSTypeReference: (node) => {\n reportStdTypeReference(\n context,\n node,\n ALTERNATIVES,\n {\n report: 'useReadonlyOrMutableRecord',\n suggestion: 'replaceWith',\n },\n importStyle,\n );\n },\n };\n },\n defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }],\n} as const;\n"],"names":[],"mappings":";;;AAuBA,MAAM,YAAA,uBAAwC,GAAA,CAAI;AAAA,EAChD,CAAC,QAAA,EAAU,CAAC,gBAAA,EAAkB,eAAe,CAAC;AAChD,CAAC,CAAA;AAEM,MAAM,6BAAA,GAGT;AAAA,EACF,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,YAAA;AAAA,IACN,IAAA,EAAM;AAAA,MACJ,WAAA,EACE;AAAA,KACJ;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAA,EAAQ;AAAA,MACN;AAAA,QACE,IAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,WAAA,EAAa;AAAA,SACf;AAAA,QACA,oBAAA,EAAsB;AAAA;AACxB,KACF;AAAA,IACA,QAAA,EAAU;AAAA,MACR,0BAAA,EACE,6EAAA;AAAA,MACF,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EAEA,MAAA,EAAQ,CAAC,OAAA,KAAY;AACnB,IAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,CAAC,GAAG,WAAA,IAAe,oBAAA;AAEvD,IAAA,OAAO;AAAA,MACL,eAAA,EAAiB,CAAC,IAAA,KAAS;AACzB,QAAA,sBAAA;AAAA,UACE,OAAA;AAAA,UACA,IAAA;AAAA,UACA,YAAA;AAAA,UACA;AAAA,YACE,MAAA,EAAQ,4BAAA;AAAA,YACR,UAAA,EAAY;AAAA,WACd;AAAA,UACA;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAA;AAAA,EACA,cAAA,EAAgB,CAAC,EAAE,WAAA,EAAa,sBAAsB;AACxD;;;;"}
1
+ {"version":3,"file":"prefer-readonly-or-mutable-record.mjs","sourceRoot":"","sources":["../../src/rules/prefer-readonly-or-mutable-record.mts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,GAEvB,MAAM,2BAA2B,CAAC;AAUnC;;;;GAIG;AACH,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,CAAC,QAAQ,EAAE,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;CAChD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,6BAA6B,GAGtC;IACF,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,+JAA+J;SAClK;QACD,cAAc,EAAE,IAAI;QACpB,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,WAAW,EAAE,4BAA4B;iBAC1C;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,QAAQ,EAAE;YACR,0BAA0B,EACxB,6EAA6E;YAC/E,WAAW,EAAE,4CAA4C;SAC1D;KACF;IAED,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,oBAAoB,CAAC;QAE5E,OAAO;YACL,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,sBAAsB,CACpB,OAAO,EACP,IAAI,EACJ,YAAY,EACZ;oBACE,MAAM,EAAE,4BAA4B;oBACpC,UAAU,EAAE,aAAa;iBAC1B,EACD,WAAW,CACZ,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;CAC/C,CAAC"}
@@ -1,49 +1,51 @@
1
- import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY } from './import-style.mjs';
2
- import { reportStdTypeReference } from './std-type-rule-utils.mjs';
3
-
4
- const ALTERNATIVES = /* @__PURE__ */ new Map([
5
- ["Exclude", ["StrictExclude", "RelaxedExclude"]],
6
- ["Extract", ["StrictExtract", "RelaxedExtract"]],
7
- ["Omit", ["StrictOmit", "RelaxedOmit"]],
8
- ["Pick", ["StrictPick", "RelaxedPick"]]
1
+ import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY, } from './import-style.mjs';
2
+ import { reportStdTypeReference, } from './std-type-rule-utils.mjs';
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+ const ALTERNATIVES = new Map([
15
+ ['Exclude', ['StrictExclude', 'RelaxedExclude']],
16
+ ['Extract', ['StrictExtract', 'RelaxedExtract']],
17
+ ['Omit', ['StrictOmit', 'RelaxedOmit']],
18
+ ['Pick', ['StrictPick', 'RelaxedPick']],
9
19
  ]);
10
- const preferStrictOrRelaxedUtilityType = {
11
- meta: {
12
- type: "suggestion",
13
- docs: {
14
- description: "Replace the built-in `Exclude` / `Extract` / `Omit` / `Pick` with the ts-type-forge `Strict*` or `Relaxed*` counterpart, so that the unchecked second argument becomes an explicit choice."
15
- },
16
- hasSuggestions: true,
17
- schema: [
18
- {
19
- type: "object",
20
- properties: {
21
- importStyle: IMPORT_STYLE_SCHEMA_PROPERTY
20
+ export const preferStrictOrRelaxedUtilityType = {
21
+ meta: {
22
+ type: 'suggestion',
23
+ docs: {
24
+ description: 'Replace the built-in `Exclude` / `Extract` / `Omit` / `Pick` with the ts-type-forge `Strict*` or `Relaxed*` counterpart, so that the unchecked second argument becomes an explicit choice.',
22
25
  },
23
- additionalProperties: false
24
- }
25
- ],
26
- messages: {
27
- useStrictOrRelaxed: "Use {{alternatives}} from ts-type-forge instead of the built-in `{{name}}`.",
28
- replaceWith: "Replace `{{name}}` with `{{replacement}}`."
29
- }
30
- },
31
- create: (context) => {
32
- const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;
33
- return {
34
- TSTypeReference: (node) => {
35
- reportStdTypeReference(
36
- context,
37
- node,
38
- ALTERNATIVES,
39
- { report: "useStrictOrRelaxed", suggestion: "replaceWith" },
40
- importStyle
41
- );
42
- }
43
- };
44
- },
45
- defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }]
26
+ hasSuggestions: true,
27
+ schema: [
28
+ {
29
+ type: 'object',
30
+ properties: {
31
+ importStyle: IMPORT_STYLE_SCHEMA_PROPERTY,
32
+ },
33
+ additionalProperties: false,
34
+ },
35
+ ],
36
+ messages: {
37
+ useStrictOrRelaxed: 'Use {{alternatives}} from ts-type-forge instead of the built-in `{{name}}`.',
38
+ replaceWith: 'Replace `{{name}}` with `{{replacement}}`.',
39
+ },
40
+ },
41
+ create: (context) => {
42
+ const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;
43
+ return {
44
+ TSTypeReference: (node) => {
45
+ reportStdTypeReference(context, node, ALTERNATIVES, { report: 'useStrictOrRelaxed', suggestion: 'replaceWith' }, importStyle);
46
+ },
47
+ };
48
+ },
49
+ defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }],
46
50
  };
47
-
48
- export { preferStrictOrRelaxedUtilityType };
49
- //# sourceMappingURL=prefer-strict-or-relaxed-utility-type.mjs.map
51
+ //# sourceMappingURL=prefer-strict-or-relaxed-utility-type.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prefer-strict-or-relaxed-utility-type.mjs","sources":["../../src/rules/prefer-strict-or-relaxed-utility-type.mts"],"sourcesContent":["import { type TSESLint } from '@typescript-eslint/utils';\nimport {\n DEFAULT_IMPORT_STYLE,\n IMPORT_STYLE_SCHEMA_PROPERTY,\n} from './import-style.mjs';\nimport {\n reportStdTypeReference,\n type StdTypeAlternatives,\n} from './std-type-rule-utils.mjs';\n\ntype Options = readonly [\n Readonly<{\n importStyle?: 'global' | 'named';\n }>?,\n];\n\ntype MessageIds = 'useStrictOrRelaxed' | 'replaceWith';\n\n/**\n * The standard-library types whose second argument is unchecked, and the\n * ts-type-forge pair that makes the choice explicit.\n *\n * `Strict*` constrains the second argument (`U extends T` / `K extends keyof T`),\n * so a key that does not exist — typically a leftover after a rename — is a\n * compile error instead of a silently empty result. `Relaxed*` keeps the\n * standard-library behavior for the cases that genuinely need it (a subtrahend\n * that is not provably part of the union, a key set computed from a still\n * deferred type parameter).\n */\nconst ALTERNATIVES: StdTypeAlternatives = new Map([\n ['Exclude', ['StrictExclude', 'RelaxedExclude']],\n ['Extract', ['StrictExtract', 'RelaxedExtract']],\n ['Omit', ['StrictOmit', 'RelaxedOmit']],\n ['Pick', ['StrictPick', 'RelaxedPick']],\n]);\n\nexport const preferStrictOrRelaxedUtilityType: TSESLint.RuleModule<\n MessageIds,\n Options\n> = {\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Replace the built-in `Exclude` / `Extract` / `Omit` / `Pick` with the ts-type-forge `Strict*` or `Relaxed*` counterpart, so that the unchecked second argument becomes an explicit choice.',\n },\n hasSuggestions: true,\n schema: [\n {\n type: 'object',\n properties: {\n importStyle: IMPORT_STYLE_SCHEMA_PROPERTY,\n },\n additionalProperties: false,\n },\n ],\n messages: {\n useStrictOrRelaxed:\n 'Use {{alternatives}} from ts-type-forge instead of the built-in `{{name}}`.',\n replaceWith: 'Replace `{{name}}` with `{{replacement}}`.',\n },\n },\n\n create: (context) => {\n const importStyle = context.options[0]?.importStyle ?? DEFAULT_IMPORT_STYLE;\n\n return {\n TSTypeReference: (node) => {\n reportStdTypeReference(\n context,\n node,\n ALTERNATIVES,\n { report: 'useStrictOrRelaxed', suggestion: 'replaceWith' },\n importStyle,\n );\n },\n };\n },\n defaultOptions: [{ importStyle: DEFAULT_IMPORT_STYLE }],\n} as const;\n"],"names":[],"mappings":";;;AA6BA,MAAM,YAAA,uBAAwC,GAAA,CAAI;AAAA,EAChD,CAAC,SAAA,EAAW,CAAC,eAAA,EAAiB,gBAAgB,CAAC,CAAA;AAAA,EAC/C,CAAC,SAAA,EAAW,CAAC,eAAA,EAAiB,gBAAgB,CAAC,CAAA;AAAA,EAC/C,CAAC,MAAA,EAAQ,CAAC,YAAA,EAAc,aAAa,CAAC,CAAA;AAAA,EACtC,CAAC,MAAA,EAAQ,CAAC,YAAA,EAAc,aAAa,CAAC;AACxC,CAAC,CAAA;AAEM,MAAM,gCAAA,GAGT;AAAA,EACF,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,YAAA;AAAA,IACN,IAAA,EAAM;AAAA,MACJ,WAAA,EACE;AAAA,KACJ;AAAA,IACA,cAAA,EAAgB,IAAA;AAAA,IAChB,MAAA,EAAQ;AAAA,MACN;AAAA,QACE,IAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY;AAAA,UACV,WAAA,EAAa;AAAA,SACf;AAAA,QACA,oBAAA,EAAsB;AAAA;AACxB,KACF;AAAA,IACA,QAAA,EAAU;AAAA,MACR,kBAAA,EACE,6EAAA;AAAA,MACF,WAAA,EAAa;AAAA;AACf,GACF;AAAA,EAEA,MAAA,EAAQ,CAAC,OAAA,KAAY;AACnB,IAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,CAAC,GAAG,WAAA,IAAe,oBAAA;AAEvD,IAAA,OAAO;AAAA,MACL,eAAA,EAAiB,CAAC,IAAA,KAAS;AACzB,QAAA,sBAAA;AAAA,UACE,OAAA;AAAA,UACA,IAAA;AAAA,UACA,YAAA;AAAA,UACA,EAAE,MAAA,EAAQ,oBAAA,EAAsB,UAAA,EAAY,aAAA,EAAc;AAAA,UAC1D;AAAA,SACF;AAAA,MACF;AAAA,KACF;AAAA,EACF,CAAA;AAAA,EACA,cAAA,EAAgB,CAAC,EAAE,WAAA,EAAa,sBAAsB;AACxD;;;;"}
1
+ {"version":3,"file":"prefer-strict-or-relaxed-utility-type.mjs","sourceRoot":"","sources":["../../src/rules/prefer-strict-or-relaxed-utility-type.mts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,sBAAsB,GAEvB,MAAM,2BAA2B,CAAC;AAUnC;;;;;;;;;;GAUG;AACH,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IAChD,CAAC,SAAS,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;IAChD,CAAC,SAAS,EAAE,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;IAChD,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IACvC,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gCAAgC,GAGzC;IACF,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EACT,4LAA4L;SAC/L;QACD,cAAc,EAAE,IAAI;QACpB,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,WAAW,EAAE,4BAA4B;iBAC1C;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,QAAQ,EAAE;YACR,kBAAkB,EAChB,6EAA6E;YAC/E,WAAW,EAAE,4CAA4C;SAC1D;KACF;IAED,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,oBAAoB,CAAC;QAE5E,OAAO;YACL,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,sBAAsB,CACpB,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,EAAE,MAAM,EAAE,oBAAoB,EAAE,UAAU,EAAE,aAAa,EAAE,EAC3D,WAAW,CACZ,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;IACD,cAAc,EAAE,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;CAC/C,CAAC"}
@@ -2,33 +2,36 @@ import { Arr } from 'ts-data-forge';
2
2
  import { resolveTypeName } from './import-style.mjs';
3
3
  import { buildTypeImportFix } from './import-utils.mjs';
4
4
 
5
- const reportTypeRewrites = (context, rewrites, messageId, importStyle) => {
6
- const sourceCode = context.sourceCode;
7
- const program = sourceCode.ast;
8
- const resolved = rewrites.flatMap((rewrite) => {
9
- const target = resolveTypeName(program, rewrite.canonicalName, importStyle);
10
- return target === void 0 ? [] : [{ rewrite, target }];
11
- });
12
- const importNames = Array.from(
13
- new Set(
14
- resolved.filter(({ target }) => target.needsImport).map(({ rewrite }) => rewrite.canonicalName)
15
- )
16
- );
17
- for (const [index, { rewrite, target }] of resolved.entries()) {
18
- const replacement = `${target.localName}<${rewrite.typeArgs}>`;
19
- context.report({
20
- node: rewrite.node,
21
- messageId,
22
- data: { original: sourceCode.getText(rewrite.node), replacement },
23
- fix: (fixer) => Arr.toPushed(
24
- index === 0 ? importNames.flatMap(
25
- (name) => buildTypeImportFix(fixer, program, name)
26
- ) : [],
27
- fixer.replaceText(rewrite.node, replacement)
28
- )
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+ export const reportTypeRewrites = (context, rewrites, messageId, importStyle) => {
14
+ const sourceCode = context.sourceCode;
15
+ const program = sourceCode.ast;
16
+ const resolved = rewrites.flatMap((rewrite) => {
17
+ const target = resolveTypeName(program, rewrite.canonicalName, importStyle);
18
+
19
+
20
+ return target === undefined ? [] : [{ rewrite, target }];
29
21
  });
30
- }
22
+ const importNames = Array.from(new Set(resolved
23
+ .filter(({ target }) => target.needsImport)
24
+ .map(({ rewrite }) => rewrite.canonicalName)));
25
+ for (const [index, { rewrite, target }] of resolved.entries()) {
26
+ const replacement = `${target.localName}<${rewrite.typeArgs}>`;
27
+ context.report({
28
+ node: rewrite.node,
29
+ messageId,
30
+ data: { original: sourceCode.getText(rewrite.node), replacement },
31
+ fix: (fixer) => Arr.toPushed(index === 0
32
+ ? importNames.flatMap((name) => buildTypeImportFix(fixer, program, name))
33
+ : [], fixer.replaceText(rewrite.node, replacement)),
34
+ });
35
+ }
31
36
  };
32
-
33
- export { reportTypeRewrites };
34
- //# sourceMappingURL=rewrite-rule-utils.mjs.map
37
+ //# sourceMappingURL=rewrite-rule-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rewrite-rule-utils.mjs","sources":["../../src/rules/rewrite-rule-utils.mts"],"sourcesContent":["import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';\nimport { Arr } from 'ts-data-forge';\nimport { resolveTypeName, type ImportStyle } from './import-style.mjs';\nimport { buildTypeImportFix } from './import-utils.mjs';\n\n/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */\n\n/** One deterministic replacement of a type node by a named ts-type-forge type. */\nexport type TypeRewrite = Readonly<{\n node: TSESTree.Node;\n canonicalName: string;\n /** Text inside the `<...>` of the replacement, e.g. `'2, string'`. */\n typeArgs: string;\n}>;\n\n/**\n * Emits one report per rewrite, resolving each target name and attaching every\n * required import to the *first* report.\n *\n * All import fixes must live on a single report: `insertTextBefore(program, …)`\n * produces overlapping ranges, and ESLint merges each report's fixes into one\n * span — so spreading them across reports makes the fixes conflict and only one\n * survives per pass.\n */\nexport const reportTypeRewrites = <MessageIds extends string>(\n context: TSESLint.RuleContext<MessageIds, readonly unknown[]>,\n rewrites: readonly TypeRewrite[],\n messageId: MessageIds,\n importStyle: ImportStyle,\n): void => {\n const sourceCode = context.sourceCode;\n\n const program = sourceCode.ast;\n\n const resolved = rewrites.flatMap((rewrite) => {\n const target = resolveTypeName(program, rewrite.canonicalName, importStyle);\n\n // The name is already bound to something else in this file, so the rewrite\n // would resolve to the wrong declaration.\n return target === undefined ? [] : [{ rewrite, target }];\n });\n\n const importNames = Array.from(\n new Set(\n resolved\n .filter(({ target }) => target.needsImport)\n .map(({ rewrite }) => rewrite.canonicalName),\n ),\n );\n\n for (const [index, { rewrite, target }] of resolved.entries()) {\n const replacement = `${target.localName}<${rewrite.typeArgs}>`;\n\n context.report({\n node: rewrite.node,\n messageId,\n data: { original: sourceCode.getText(rewrite.node), replacement },\n fix: (fixer) =>\n Arr.toPushed(\n index === 0\n ? importNames.flatMap((name) =>\n buildTypeImportFix(fixer, program, name),\n )\n : [],\n fixer.replaceText(rewrite.node, replacement),\n ),\n });\n }\n};\n"],"names":[],"mappings":";;;;AAwBO,MAAM,kBAAA,GAAqB,CAChC,OAAA,EACA,QAAA,EACA,WACA,WAAA,KACS;AACT,EAAA,MAAM,aAAa,OAAA,CAAQ,UAAA;AAE3B,EAAA,MAAM,UAAU,UAAA,CAAW,GAAA;AAE3B,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC7C,IAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,OAAA,EAAS,OAAA,CAAQ,eAAe,WAAW,CAAA;AAI1E,IAAA,OAAO,MAAA,KAAW,SAAY,EAAC,GAAI,CAAC,EAAE,OAAA,EAAS,QAAQ,CAAA;AAAA,EACzD,CAAC,CAAA;AAED,EAAA,MAAM,cAAc,KAAA,CAAM,IAAA;AAAA,IACxB,IAAI,GAAA;AAAA,MACF,QAAA,CACG,MAAA,CAAO,CAAC,EAAE,QAAO,KAAM,MAAA,CAAO,WAAW,CAAA,CACzC,IAAI,CAAC,EAAE,OAAA,EAAQ,KAAM,QAAQ,aAAa;AAAA;AAC/C,GACF;AAEA,EAAA,KAAA,MAAW,CAAC,OAAO,EAAE,OAAA,EAAS,QAAQ,CAAA,IAAK,QAAA,CAAS,OAAA,EAAQ,EAAG;AAC7D,IAAA,MAAM,cAAc,CAAA,EAAG,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,QAAQ,QAAQ,CAAA,CAAA,CAAA;AAE3D,IAAA,OAAA,CAAQ,MAAA,CAAO;AAAA,MACb,MAAM,OAAA,CAAQ,IAAA;AAAA,MACd,SAAA;AAAA,MACA,IAAA,EAAM,EAAE,QAAA,EAAU,UAAA,CAAW,QAAQ,OAAA,CAAQ,IAAI,GAAG,WAAA,EAAY;AAAA,MAChE,GAAA,EAAK,CAAC,KAAA,KACJ,GAAA,CAAI,QAAA;AAAA,QACF,KAAA,KAAU,IACN,WAAA,CAAY,OAAA;AAAA,UAAQ,CAAC,IAAA,KACnB,kBAAA,CAAmB,KAAA,EAAO,SAAS,IAAI;AAAA,YAEzC,EAAC;AAAA,QACL,KAAA,CAAM,WAAA,CAAY,OAAA,CAAQ,IAAA,EAAM,WAAW;AAAA;AAC7C,KACH,CAAA;AAAA,EACH;AACF;;;;"}
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,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAYxD;;;;;;;;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,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;QAE5E,2EAA2E;QAC3E,0CAA0C;QAC1C,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAC5B,IAAI,GAAG,CACL,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,CACF,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,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CACzC;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,4 +1,5 @@
1
1
  export declare const tsTypeForgeRules: {
2
+ readonly 'no-side-effect-import': import("@typescript-eslint/utils/ts-eslint").RuleModule<"removeSideEffectImport", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
3
  readonly 'prefer-canonical-length-constrained-tuple': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useCanonicalTuple", readonly [(Readonly<{
3
4
  importStyle?: 'global' | 'named';
4
5
  maxLength?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.mts","sourceRoot":"","sources":["../../src/rules/rules.mts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;CAMa,CAAC"}
1
+ {"version":3,"file":"rules.d.mts","sourceRoot":"","sources":["../../src/rules/rules.mts"],"names":[],"mappings":"AAOA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;CAOa,CAAC"}
@@ -1,14 +1,13 @@
1
+ import { noSideEffectImport } from './no-side-effect-import.mjs';
1
2
  import { preferCanonicalLengthConstrainedTuple } from './prefer-canonical-length-constrained-tuple.mjs';
2
3
  import { preferCanonicalMutableRecord } from './prefer-canonical-mutable-record.mjs';
3
4
  import { preferReadonlyOrMutableRecord } from './prefer-readonly-or-mutable-record.mjs';
4
5
  import { preferStrictOrRelaxedUtilityType } from './prefer-strict-or-relaxed-utility-type.mjs';
5
-
6
- const tsTypeForgeRules = {
7
- "prefer-canonical-length-constrained-tuple": preferCanonicalLengthConstrainedTuple,
8
- "prefer-canonical-mutable-record": preferCanonicalMutableRecord,
9
- "prefer-readonly-or-mutable-record": preferReadonlyOrMutableRecord,
10
- "prefer-strict-or-relaxed-utility-type": preferStrictOrRelaxedUtilityType
6
+ export const tsTypeForgeRules = {
7
+ 'no-side-effect-import': noSideEffectImport,
8
+ 'prefer-canonical-length-constrained-tuple': preferCanonicalLengthConstrainedTuple,
9
+ 'prefer-canonical-mutable-record': preferCanonicalMutableRecord,
10
+ 'prefer-readonly-or-mutable-record': preferReadonlyOrMutableRecord,
11
+ 'prefer-strict-or-relaxed-utility-type': preferStrictOrRelaxedUtilityType,
11
12
  };
12
-
13
- export { tsTypeForgeRules };
14
- //# sourceMappingURL=rules.mjs.map
13
+ //# sourceMappingURL=rules.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rules.mjs","sources":["../../src/rules/rules.mts"],"sourcesContent":["import { type ESLintPlugin } from '../types.mjs';\nimport { preferCanonicalLengthConstrainedTuple } from './prefer-canonical-length-constrained-tuple.mjs';\nimport { preferCanonicalMutableRecord } from './prefer-canonical-mutable-record.mjs';\nimport { preferReadonlyOrMutableRecord } from './prefer-readonly-or-mutable-record.mjs';\nimport { preferStrictOrRelaxedUtilityType } from './prefer-strict-or-relaxed-utility-type.mjs';\n\nexport const tsTypeForgeRules = {\n 'prefer-canonical-length-constrained-tuple':\n preferCanonicalLengthConstrainedTuple,\n 'prefer-canonical-mutable-record': preferCanonicalMutableRecord,\n 'prefer-readonly-or-mutable-record': preferReadonlyOrMutableRecord,\n 'prefer-strict-or-relaxed-utility-type': preferStrictOrRelaxedUtilityType,\n} as const satisfies ESLintPlugin['rules'];\n"],"names":[],"mappings":";;;;;AAMO,MAAM,gBAAA,GAAmB;AAAA,EAC9B,2CAAA,EACE,qCAAA;AAAA,EACF,iCAAA,EAAmC,4BAAA;AAAA,EACnC,mCAAA,EAAqC,6BAAA;AAAA,EACrC,uCAAA,EAAyC;AAC3C;;;;"}
1
+ {"version":3,"file":"rules.mjs","sourceRoot":"","sources":["../../src/rules/rules.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,qCAAqC,EAAE,MAAM,iDAAiD,CAAC;AACxG,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,6BAA6B,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,gCAAgC,EAAE,MAAM,6CAA6C,CAAC;AAE/F,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,uBAAuB,EAAE,kBAAkB;IAC3C,2CAA2C,EACzC,qCAAqC;IACvC,iCAAiC,EAAE,4BAA4B;IAC/D,mCAAmC,EAAE,6BAA6B;IAClE,uCAAuC,EAAE,gCAAgC;CACjC,CAAC"}