eslint-plugin-ts-type-forge 0.8.0 → 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 (35) hide show
  1. package/dist/index.mjs +2 -2
  2. package/dist/index.mjs.map +1 -1
  3. package/dist/plugin.mjs +34 -31
  4. package/dist/plugin.mjs.map +1 -1
  5. package/dist/rule-types.mjs +2 -1
  6. package/dist/rule-types.mjs.map +1 -1
  7. package/dist/rules/ast-utils.mjs +224 -103
  8. package/dist/rules/ast-utils.mjs.map +1 -1
  9. package/dist/rules/constants.mjs +14 -11
  10. package/dist/rules/constants.mjs.map +1 -1
  11. package/dist/rules/import-style.mjs +31 -26
  12. package/dist/rules/import-style.mjs.map +1 -1
  13. package/dist/rules/import-utils.mjs +49 -29
  14. package/dist/rules/import-utils.mjs.map +1 -1
  15. package/dist/rules/index.mjs +2 -2
  16. package/dist/rules/index.mjs.map +1 -1
  17. package/dist/rules/no-side-effect-import.mjs +48 -34
  18. package/dist/rules/no-side-effect-import.mjs.map +1 -1
  19. package/dist/rules/prefer-canonical-length-constrained-tuple.mjs +93 -73
  20. package/dist/rules/prefer-canonical-length-constrained-tuple.mjs.map +1 -1
  21. package/dist/rules/prefer-canonical-mutable-record.mjs +88 -75
  22. package/dist/rules/prefer-canonical-mutable-record.mjs.map +1 -1
  23. package/dist/rules/prefer-readonly-or-mutable-record.mjs +41 -45
  24. package/dist/rules/prefer-readonly-or-mutable-record.mjs.map +1 -1
  25. package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs +48 -46
  26. package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs.map +1 -1
  27. package/dist/rules/rewrite-rule-utils.mjs +31 -28
  28. package/dist/rules/rewrite-rule-utils.mjs.map +1 -1
  29. package/dist/rules/rules.mjs +7 -10
  30. package/dist/rules/rules.mjs.map +1 -1
  31. package/dist/rules/std-type-rule-utils.mjs +47 -30
  32. package/dist/rules/std-type-rule-utils.mjs.map +1 -1
  33. package/dist/types.mjs +2 -2
  34. package/dist/types.mjs.map +1 -1
  35. package/package.json +6 -7
@@ -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":"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"}
@@ -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"}
@@ -3,14 +3,11 @@ import { preferCanonicalLengthConstrainedTuple } from './prefer-canonical-length
3
3
  import { preferCanonicalMutableRecord } from './prefer-canonical-mutable-record.mjs';
4
4
  import { preferReadonlyOrMutableRecord } from './prefer-readonly-or-mutable-record.mjs';
5
5
  import { preferStrictOrRelaxedUtilityType } from './prefer-strict-or-relaxed-utility-type.mjs';
6
-
7
- const tsTypeForgeRules = {
8
- "no-side-effect-import": noSideEffectImport,
9
- "prefer-canonical-length-constrained-tuple": preferCanonicalLengthConstrainedTuple,
10
- "prefer-canonical-mutable-record": preferCanonicalMutableRecord,
11
- "prefer-readonly-or-mutable-record": preferReadonlyOrMutableRecord,
12
- "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,
13
12
  };
14
-
15
- export { tsTypeForgeRules };
16
- //# 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 { noSideEffectImport } from './no-side-effect-import.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 'no-side-effect-import': noSideEffectImport,\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":";;;;;;AAOO,MAAM,gBAAA,GAAmB;AAAA,EAC9B,uBAAA,EAAyB,kBAAA;AAAA,EACzB,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"}
@@ -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
- const reportStdTypeReference = (context, node, alternatives, messageIds, importStyle) => {
8
- const typeName = node.typeName;
9
- if (typeName.type !== AST_NODE_TYPES.Identifier) return;
10
- const stdName = typeName.name;
11
- const candidates = alternatives.get(stdName);
12
- if (candidates === void 0) return;
13
- if (isLocallyBound(context.sourceCode, node, stdName)) return;
14
- const program = context.sourceCode.ast;
15
- context.report({
16
- node: typeName,
17
- messageId: messageIds.report,
18
- data: { name: stdName, alternatives: formatAlternatives(candidates) },
19
- suggest: candidates.flatMap((candidate) => {
20
- const target = resolveTypeName(program, candidate, importStyle);
21
- return target === void 0 ? [] : [
22
- {
23
- messageId: messageIds.suggestion,
24
- data: { name: stdName, replacement: target.localName },
25
- fix: (fixer) => Arr.toPushed(
26
- target.needsImport ? buildTypeImportFix(fixer, program, candidate) : [],
27
- fixer.replaceText(typeName, target.localName)
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
- export { reportStdTypeReference };
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"],"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 { 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/**\n * The ts-type-forge replacements offered for one standard-library type, in the\n * order they are suggested.\n */\nexport type StdTypeAlternatives = ReadonlyMap<string, readonly string[]>;\n\n/**\n * Reports a reference to a banned standard-library type and offers one\n * suggestion per ts-type-forge alternative.\n *\n * Choosing between the alternatives is a semantic decision — `StrictExclude`\n * additionally checks that the subtrahend is part of the union, `ReadonlyRecord`\n * and `MutableRecord` describe different types — so this is deliberately *not*\n * an autofix. Each suggestion carries its own import fix, which is safe because\n * ESLint applies suggestions one at a time.\n */\nexport const reportStdTypeReference = <MessageIds extends string>(\n context: TSESLint.RuleContext<MessageIds, readonly unknown[]>,\n node: TSESTree.TSTypeReference,\n alternatives: StdTypeAlternatives,\n messageIds: Readonly<{ report: MessageIds; suggestion: MessageIds }>,\n importStyle: ImportStyle,\n): void => {\n const typeName = node.typeName;\n\n // `ns.Pick` / `import('…').Pick` never denote the standard-library type.\n if (typeName.type !== AST_NODE_TYPES.Identifier) return;\n\n const stdName = typeName.name;\n\n const candidates = alternatives.get(stdName);\n\n if (candidates === undefined) return;\n\n // A file that declares — or imports — its own `Pick` does not mean the\n // standard-library one, so there is nothing to steer.\n if (isLocallyBound(context.sourceCode, node, stdName)) return;\n\n const program = context.sourceCode.ast;\n\n context.report({\n node: typeName,\n messageId: messageIds.report,\n data: { name: stdName, alternatives: formatAlternatives(candidates) },\n suggest: candidates.flatMap((candidate) => {\n const target = resolveTypeName(program, candidate, importStyle);\n\n // The replacement name is already bound to something else in this file,\n // so rewriting to it would resolve to the wrong declaration.\n return target === undefined\n ? []\n : [\n {\n messageId: messageIds.suggestion,\n data: { name: stdName, replacement: target.localName },\n fix: (fixer: TSESLint.RuleFixer): readonly TSESLint.RuleFix[] =>\n Arr.toPushed(\n target.needsImport\n ? buildTypeImportFix(fixer, program, candidate)\n : [],\n fixer.replaceText(typeName, target.localName),\n ),\n },\n ];\n }),\n });\n};\n\n/** `['StrictPick', 'RelaxedPick']` → `` '`StrictPick` or `RelaxedPick`' ``. */\nconst formatAlternatives = (candidates: readonly string[]): string =>\n candidates.map((candidate) => `\\`${candidate}\\``).join(' or ');\n"],"names":[],"mappings":";;;;;;AA4BO,MAAM,yBAAyB,CACpC,OAAA,EACA,IAAA,EACA,YAAA,EACA,YACA,WAAA,KACS;AACT,EAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAGtB,EAAA,IAAI,QAAA,CAAS,IAAA,KAAS,cAAA,CAAe,UAAA,EAAY;AAEjD,EAAA,MAAM,UAAU,QAAA,CAAS,IAAA;AAEzB,EAAA,MAAM,UAAA,GAAa,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA;AAE3C,EAAA,IAAI,eAAe,MAAA,EAAW;AAI9B,EAAA,IAAI,cAAA,CAAe,OAAA,CAAQ,UAAA,EAAY,IAAA,EAAM,OAAO,CAAA,EAAG;AAEvD,EAAA,MAAM,OAAA,GAAU,QAAQ,UAAA,CAAW,GAAA;AAEnC,EAAA,OAAA,CAAQ,MAAA,CAAO;AAAA,IACb,IAAA,EAAM,QAAA;AAAA,IACN,WAAW,UAAA,CAAW,MAAA;AAAA,IACtB,MAAM,EAAE,IAAA,EAAM,SAAS,YAAA,EAAc,kBAAA,CAAmB,UAAU,CAAA,EAAE;AAAA,IACpE,OAAA,EAAS,UAAA,CAAW,OAAA,CAAQ,CAAC,SAAA,KAAc;AACzC,MAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,OAAA,EAAS,SAAA,EAAW,WAAW,CAAA;AAI9D,MAAA,OAAO,MAAA,KAAW,MAAA,GACd,EAAC,GACD;AAAA,QACE;AAAA,UACE,WAAW,UAAA,CAAW,UAAA;AAAA,UACtB,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,WAAA,EAAa,OAAO,SAAA,EAAU;AAAA,UACrD,GAAA,EAAK,CAAC,KAAA,KACJ,GAAA,CAAI,QAAA;AAAA,YACF,OAAO,WAAA,GACH,kBAAA,CAAmB,OAAO,OAAA,EAAS,SAAS,IAC5C,EAAC;AAAA,YACL,KAAA,CAAM,WAAA,CAAY,QAAA,EAAU,MAAA,CAAO,SAAS;AAAA;AAC9C;AACJ,OACF;AAAA,IACN,CAAC;AAAA,GACF,CAAA;AACH;AAGA,MAAM,kBAAA,GAAqB,CAAC,UAAA,KAC1B,UAAA,CAAW,GAAA,CAAI,CAAC,SAAA,KAAc,CAAA,EAAA,EAAK,SAAS,CAAA,EAAA,CAAI,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA;;"}
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
@@ -1 +1 @@
1
- {"version":3,"file":"types.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
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.8.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.1",
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.10.4",
47
- "eslint-plugin-ts-data-forge": "0.6.0",
48
- "eslint-plugin-ts-fortress": "1.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
- "rollup": "4.63.0",
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",