eslint-plugin-ts-data-forge 0.6.1 → 0.7.0

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 (77) hide show
  1. package/README.md +1 -0
  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 +45 -41
  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 +6 -2
  11. package/dist/rule-types.mjs.map +1 -1
  12. package/dist/rules/ast-utils.mjs +107 -50
  13. package/dist/rules/ast-utils.mjs.map +1 -1
  14. package/dist/rules/branded-number-types.mjs +41 -37
  15. package/dist/rules/branded-number-types.mjs.map +1 -1
  16. package/dist/rules/constants.mjs +2 -4
  17. package/dist/rules/constants.mjs.map +1 -1
  18. package/dist/rules/import-utils.mjs +80 -56
  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.mjs +46 -34
  23. package/dist/rules/no-side-effect-import.mjs.map +1 -1
  24. package/dist/rules/no-unnecessary-type-guard.mjs +376 -265
  25. package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
  26. package/dist/rules/prefer-arr-is-array.mjs +64 -52
  27. package/dist/rules/prefer-arr-is-array.mjs.map +1 -1
  28. package/dist/rules/prefer-arr-is-bounded-length-array.mjs +91 -85
  29. package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
  30. package/dist/rules/prefer-arr-is-fixed-length-array.mjs +92 -83
  31. package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
  32. package/dist/rules/prefer-arr-is-max-length-array.mjs +92 -80
  33. package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
  34. package/dist/rules/prefer-arr-is-min-length-array.mjs +92 -80
  35. package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
  36. package/dist/rules/prefer-arr-is-non-empty.mjs +85 -77
  37. package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
  38. package/dist/rules/prefer-arr-scan.d.mts +96 -0
  39. package/dist/rules/prefer-arr-scan.d.mts.map +1 -0
  40. package/dist/rules/prefer-arr-scan.mjs +482 -0
  41. package/dist/rules/prefer-arr-scan.mjs.map +1 -0
  42. package/dist/rules/prefer-arr-sum.mjs +176 -132
  43. package/dist/rules/prefer-arr-sum.mjs.map +1 -1
  44. package/dist/rules/prefer-as-int.mjs +77 -71
  45. package/dist/rules/prefer-as-int.mjs.map +1 -1
  46. package/dist/rules/prefer-canonical-array-slicing.mjs +503 -343
  47. package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
  48. package/dist/rules/prefer-canonical-length-cast.mjs +217 -144
  49. package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
  50. package/dist/rules/prefer-canonical-length-guard.mjs +160 -109
  51. package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
  52. package/dist/rules/prefer-comparison-over-nullish-guard.mjs +89 -71
  53. package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
  54. package/dist/rules/prefer-is-non-null-object.mjs +91 -72
  55. package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
  56. package/dist/rules/prefer-is-record-and-has-key.mjs +148 -105
  57. package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
  58. package/dist/rules/prefer-num-safe-parse-float.mjs +101 -77
  59. package/dist/rules/prefer-num-safe-parse-float.mjs.map +1 -1
  60. package/dist/rules/prefer-num-safe-parse-int.mjs +103 -81
  61. package/dist/rules/prefer-num-safe-parse-int.mjs.map +1 -1
  62. package/dist/rules/prefer-obj-over-entries-round-trip.mjs +299 -194
  63. package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
  64. package/dist/rules/prefer-range-for-loop.mjs +121 -99
  65. package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
  66. package/dist/rules/rules.d.mts +1 -0
  67. package/dist/rules/rules.d.mts.map +1 -1
  68. package/dist/rules/rules.mjs +19 -20
  69. package/dist/rules/rules.mjs.map +1 -1
  70. package/dist/types.mjs +2 -2
  71. package/dist/types.mjs.map +1 -1
  72. package/package.json +6 -7
  73. package/src/plugin.mts +1 -0
  74. package/src/rule-types.mts +16 -0
  75. package/src/rules/prefer-arr-scan.mts +693 -0
  76. package/src/rules/prefer-arr-scan.test.mts +295 -0
  77. package/src/rules/rules.mts +2 -0
@@ -1,61 +1,85 @@
1
- import { AST_NODE_TYPES } from '@typescript-eslint/utils';
1
+ import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
2
2
  import { TS_DATA_FORGE_MODULE } from './constants.mjs';
3
3
 
4
- const getTsDataForgeImport = (program) => program.body.find(
5
- (node) => node.type === AST_NODE_TYPES.ImportDeclaration && node.source.value === TS_DATA_FORGE_MODULE
6
- );
7
- const getNamedImports = (node) => {
8
- if (node === void 0) return [];
9
- return node.specifiers.flatMap(
10
- (specifier) => specifier.type === AST_NODE_TYPES.ImportSpecifier ? (() => {
11
- const importedName = specifier.imported.type === AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value;
12
- return typeof importedName === "string" ? [importedName] : [];
13
- })() : []
14
- );
4
+ export const getTsDataForgeImport = (program) => program.body.find((node) => node.type === AST_NODE_TYPES.ImportDeclaration &&
5
+ node.source.value === TS_DATA_FORGE_MODULE);
6
+ export const getNamedImports = (node) => {
7
+ if (node === undefined)
8
+ return [];
9
+ return node.specifiers.flatMap((specifier) => specifier.type === AST_NODE_TYPES.ImportSpecifier
10
+ ? (() => {
11
+ const importedName = specifier.imported.type === AST_NODE_TYPES.Identifier
12
+ ? specifier.imported.name
13
+ : specifier.imported.value;
14
+ return typeof importedName === 'string' ? [importedName] : [];
15
+ })()
16
+ : []);
15
17
  };
16
- const getImportedLocalName = (node, importedName) => node?.specifiers.find(
17
- (specifier) => specifier.type === AST_NODE_TYPES.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value) === importedName
18
- )?.local.name;
19
- const buildCalleeResolver = (importDecl) => {
20
- const specifiers = importDecl?.specifiers ?? [];
21
- const namespaceName = specifiers.find(
22
- (specifier) => specifier.type === AST_NODE_TYPES.ImportNamespaceSpecifier
23
- )?.local.name;
24
- const localToCanonical = new Map(
25
- specifiers.flatMap((specifier) => {
26
- if (specifier.type !== AST_NODE_TYPES.ImportSpecifier) return [];
27
- const importedName = specifier.imported.type === AST_NODE_TYPES.Identifier ? specifier.imported.name : specifier.imported.value;
28
- return typeof importedName === "string" ? [[specifier.local.name, importedName]] : [];
29
- })
30
- );
31
- return (callee) => {
32
- if (callee.type === AST_NODE_TYPES.Identifier) {
33
- const canonicalName = localToCanonical.get(callee.name);
34
- return canonicalName === void 0 ? void 0 : {
35
- canonicalName,
36
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
37
- propertyNode: callee,
38
- isNamespace: false
39
- };
40
- }
41
- if (namespaceName !== void 0 && callee.type === AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === AST_NODE_TYPES.Identifier && callee.object.name === namespaceName && callee.property.type === AST_NODE_TYPES.Identifier) {
42
- return {
43
- canonicalName: callee.property.name,
44
- // eslint-disable-next-line total-functions/no-unsafe-type-assertion
45
- propertyNode: callee.property,
46
- isNamespace: true
47
- };
48
- }
49
- return void 0;
50
- };
51
- };
52
- const buildImportFixes = (fixer, program, _tsDataForgeImport, requiredNames) => {
53
- const specifierText = requiredNames.join(", ");
54
- const importStatement = `import { ${specifierText} } from '${TS_DATA_FORGE_MODULE}';`;
55
- const newLine = "\n";
56
- const insertionText = `${importStatement}${newLine}`;
57
- return [fixer.insertTextBefore(program, insertionText)];
18
+
19
+
20
+
21
+
22
+
23
+
24
+ export const getImportedLocalName = (node, importedName) => node?.specifiers.find((specifier) => specifier.type === AST_NODE_TYPES.ImportSpecifier &&
25
+ (specifier.imported.type === AST_NODE_TYPES.Identifier
26
+ ? specifier.imported.name
27
+ : specifier.imported.value) === importedName)?.local.name;
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+ export const buildCalleeResolver = (importDecl) => {
36
+ const specifiers = importDecl?.specifiers ?? [];
37
+ const namespaceName = specifiers.find((specifier) => specifier.type === AST_NODE_TYPES.ImportNamespaceSpecifier)?.local.name;
38
+ const localToCanonical = new Map(specifiers.flatMap((specifier) => {
39
+ if (specifier.type !== AST_NODE_TYPES.ImportSpecifier)
40
+ return [];
41
+ const importedName = specifier.imported.type === AST_NODE_TYPES.Identifier
42
+ ? specifier.imported.name
43
+ : specifier.imported.value;
44
+ return typeof importedName === 'string'
45
+ ? [[specifier.local.name, importedName]]
46
+ : [];
47
+ }));
48
+ return (callee) => {
49
+ if (callee.type === AST_NODE_TYPES.Identifier) {
50
+ const canonicalName = localToCanonical.get(callee.name);
51
+ return canonicalName === undefined
52
+ ? undefined
53
+ : {
54
+ canonicalName,
55
+
56
+ propertyNode: callee,
57
+ isNamespace: false,
58
+ };
59
+ }
60
+ if (namespaceName !== undefined &&
61
+ callee.type === AST_NODE_TYPES.MemberExpression &&
62
+ !callee.computed &&
63
+ callee.object.type === AST_NODE_TYPES.Identifier &&
64
+ callee.object.name === namespaceName &&
65
+ callee.property.type === AST_NODE_TYPES.Identifier) {
66
+ return {
67
+ canonicalName: callee.property.name,
68
+
69
+ propertyNode: callee.property,
70
+ isNamespace: true,
71
+ };
72
+ }
73
+ return undefined;
74
+ };
58
75
  };
76
+ export const buildImportFixes = (fixer, program, _tsDataForgeImport, requiredNames) => {
77
+ const specifierText = requiredNames.join(', ');
78
+ const importStatement = `import { ${specifierText} } from '${TS_DATA_FORGE_MODULE}';`;
79
+ const newLine = '\n';
80
+ const insertionText = `${importStatement}${newLine}`;
59
81
 
60
- export { buildCalleeResolver, buildImportFixes, getImportedLocalName, getNamedImports, getTsDataForgeImport };
61
- //# sourceMappingURL=import-utils.mjs.map
82
+
83
+ return [fixer.insertTextBefore(program, insertionText)];
84
+ };
85
+ //# sourceMappingURL=import-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"import-utils.mjs","sources":["../../src/rules/import-utils.mts"],"sourcesContent":["import {\n AST_NODE_TYPES,\n type TSESLint,\n type TSESTree,\n} from '@typescript-eslint/utils';\nimport { type DeepReadonly } from 'ts-type-forge';\nimport { TS_DATA_FORGE_MODULE } from './constants.mjs';\n\n/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */\n\nexport const getTsDataForgeImport = (\n program: TSESTree.Program,\n): TSESTree.ImportDeclaration | undefined =>\n program.body.find(\n (node): node is TSESTree.ImportDeclaration =>\n node.type === AST_NODE_TYPES.ImportDeclaration &&\n node.source.value === TS_DATA_FORGE_MODULE,\n );\n\nexport const getNamedImports = (\n node: DeepReadonly<TSESTree.ImportDeclaration> | undefined,\n): readonly string[] => {\n if (node === undefined) return [];\n\n return node.specifiers.flatMap((specifier) =>\n specifier.type === AST_NODE_TYPES.ImportSpecifier\n ? (() => {\n const importedName =\n specifier.imported.type === AST_NODE_TYPES.Identifier\n ? specifier.imported.name\n : specifier.imported.value;\n\n return typeof importedName === 'string' ? [importedName] : [];\n })()\n : [],\n );\n};\n\n/**\n * Returns the in-scope local name a given canonical export is imported as\n * (handling aliases such as `import { isX as y }` → `'y'`), or `undefined` when\n * it is not imported. Used so autofixes reference the binding that actually\n * exists rather than the canonical name.\n */\nexport const getImportedLocalName = (\n node: DeepReadonly<TSESTree.ImportDeclaration> | undefined,\n importedName: string,\n): string | undefined =>\n node?.specifiers.find(\n (specifier) =>\n specifier.type === AST_NODE_TYPES.ImportSpecifier &&\n (specifier.imported.type === AST_NODE_TYPES.Identifier\n ? specifier.imported.name\n : specifier.imported.value) === importedName,\n )?.local.name;\n\ntype ResolvedCallee = Readonly<{\n /** The canonical (imported) ts-data-forge name, regardless of local alias. */\n canonicalName: string;\n /** The identifier node to rewrite when replacing the callee name. */\n propertyNode: TSESTree.Node;\n /** Whether the call was made through a namespace import (`tf.isX(...)`). */\n isNamespace: boolean;\n}>;\n\n/**\n * Builds a resolver that maps a call expression's callee to the canonical\n * ts-data-forge function it refers to. Handles named imports (including aliases\n * such as `import { isX as y }`) and namespace imports (`import * as tf` →\n * `tf.isX(...)`). Returns `undefined` for any callee that does not reference the\n * given ts-data-forge import.\n */\nexport const buildCalleeResolver = (\n importDecl: TSESTree.ImportDeclaration | undefined,\n): ((\n callee: DeepReadonly<TSESTree.Expression>,\n) => ResolvedCallee | undefined) => {\n const specifiers = importDecl?.specifiers ?? [];\n\n const namespaceName = specifiers.find(\n (specifier) => specifier.type === AST_NODE_TYPES.ImportNamespaceSpecifier,\n )?.local.name;\n\n const localToCanonical = new Map<string, string>(\n specifiers.flatMap((specifier) => {\n if (specifier.type !== AST_NODE_TYPES.ImportSpecifier) return [];\n\n const importedName =\n specifier.imported.type === AST_NODE_TYPES.Identifier\n ? specifier.imported.name\n : specifier.imported.value;\n\n return typeof importedName === 'string'\n ? [[specifier.local.name, importedName] as const]\n : [];\n }),\n );\n\n return (callee) => {\n if (callee.type === AST_NODE_TYPES.Identifier) {\n const canonicalName = localToCanonical.get(callee.name);\n\n return canonicalName === undefined\n ? undefined\n : {\n canonicalName,\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n propertyNode: callee as TSESTree.Node,\n isNamespace: false,\n };\n }\n\n if (\n namespaceName !== undefined &&\n callee.type === AST_NODE_TYPES.MemberExpression &&\n !callee.computed &&\n callee.object.type === AST_NODE_TYPES.Identifier &&\n callee.object.name === namespaceName &&\n callee.property.type === AST_NODE_TYPES.Identifier\n ) {\n return {\n canonicalName: callee.property.name,\n // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n propertyNode: callee.property as TSESTree.Node,\n isNamespace: true,\n };\n }\n\n return undefined;\n };\n};\n\nexport const buildImportFixes = (\n fixer: TSESLint.RuleFixer,\n program: TSESTree.Program,\n _tsDataForgeImport: TSESTree.ImportDeclaration | undefined,\n requiredNames: readonly string[],\n): readonly TSESLint.RuleFix[] => {\n const specifierText = requiredNames.join(', ');\n\n const importStatement =\n `import { ${specifierText} } from '${TS_DATA_FORGE_MODULE}';` as const;\n\n const newLine = '\\n';\n\n const insertionText = `${importStatement}${newLine}` as const;\n\n // Always insert at the beginning of the file\n // (organize-imports will handle merging/deduplication)\n return [fixer.insertTextBefore(program, insertionText)];\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"import-utils.mjs","sourceRoot":"","sources":["../../src/rules/import-utils.mts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { tsDataForgeRules } from './rules.mjs';
2
- //# sourceMappingURL=index.mjs.map
1
+ export * from './rules.mjs';
2
+ //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/rules/index.mts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -1,41 +1,53 @@
1
1
  import { Arr } from 'ts-data-forge';
2
2
  import { TS_DATA_FORGE_MODULE } from './constants.mjs';
3
3
 
4
- const noSideEffectImport = {
5
- meta: {
6
- type: "suggestion",
7
- docs: {
8
- description: `Remove a side-effect-only \`import '${TS_DATA_FORGE_MODULE}';\`, which binds no name and, the package being \`sideEffects: false\`, does nothing.`
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+ export const noSideEffectImport = {
15
+ meta: {
16
+ type: 'suggestion',
17
+ docs: {
18
+ description: `Remove a side-effect-only \`import '${TS_DATA_FORGE_MODULE}';\`, which binds no name and, the package being \`sideEffects: false\`, does nothing.`,
19
+ },
20
+ fixable: 'code',
21
+ schema: [],
22
+ messages: {
23
+ removeSideEffectImport: `\`import '${TS_DATA_FORGE_MODULE}';\` binds no name, and \`${TS_DATA_FORGE_MODULE}\` declares \`sideEffects: false\`, so loading it does nothing. Remove it, and import what you need by name.`,
24
+ },
9
25
  },
10
- fixable: "code",
11
- schema: [],
12
- messages: {
13
- removeSideEffectImport: `\`import '${TS_DATA_FORGE_MODULE}';\` binds no name, and \`${TS_DATA_FORGE_MODULE}\` declares \`sideEffects: false\`, so loading it does nothing. Remove it, and import what you need by name.`
14
- }
15
- },
16
- create: (context) => ({
17
- ImportDeclaration: (node) => {
18
- if (node.source.value !== TS_DATA_FORGE_MODULE || !Arr.isEmpty(node.specifiers)) {
19
- return;
20
- }
21
- context.report({
22
- node,
23
- messageId: "removeSideEffectImport",
24
- fix: (fixer) => removeStatement(fixer, context.sourceCode, node)
25
- });
26
- }
27
- }),
28
- defaultOptions: []
26
+ create: (context) => ({
27
+ ImportDeclaration: (node) => {
28
+ if (node.source.value !== TS_DATA_FORGE_MODULE ||
29
+ !Arr.isEmpty(node.specifiers)) {
30
+ return;
31
+ }
32
+ context.report({
33
+ node,
34
+ messageId: 'removeSideEffectImport',
35
+ fix: (fixer) => removeStatement(fixer, context.sourceCode, node),
36
+ });
37
+ },
38
+ }),
39
+ defaultOptions: [],
29
40
  };
41
+
42
+
43
+
44
+
45
+
30
46
  const removeStatement = (fixer, sourceCode, node) => {
31
- const restOfLine = /^[^\S\n]*\n/u.exec(
32
- sourceCode.getText().slice(node.range[1])
33
- );
34
- return fixer.removeRange([
35
- node.range[0],
36
- node.range[1] + (restOfLine?.[0].length ?? 0)
37
- ]);
47
+ const restOfLine = /^[^\S\n]*\n/u.exec(sourceCode.getText().slice(node.range[1]));
48
+ return fixer.removeRange([
49
+ node.range[0],
50
+ node.range[1] + (restOfLine?.[0].length ?? 0),
51
+ ]);
38
52
  };
39
-
40
- export { noSideEffectImport };
41
- //# sourceMappingURL=no-side-effect-import.mjs.map
53
+ //# sourceMappingURL=no-side-effect-import.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-side-effect-import.mjs","sources":["../../src/rules/no-side-effect-import.mts"],"sourcesContent":["import { type TSESLint, type TSESTree } from '@typescript-eslint/utils';\nimport { Arr } from 'ts-data-forge';\nimport { TS_DATA_FORGE_MODULE } from './constants.mjs';\n\ntype Options = readonly [];\n\ntype MessageIds = 'removeSideEffectImport';\n\n/**\n * `import 'ts-data-forge';` binds nothing and runs nothing: every export is a\n * pure value or function, and the package declares `sideEffects: false`, which\n * is a promise that evaluating it changes nothing observable. TypeScript keeps\n * a side-effect import in the emitted JavaScript — that is the one kind it\n * never elides — so what is left is a module loaded for no reason, and a\n * bundler that trusts the flag drops it anyway.\n *\n * The rule matches the bare specifier exactly; an import of some other module\n * is none of its business.\n */\nexport const noSideEffectImport: TSESLint.RuleModule<MessageIds, Options> = {\n meta: {\n type: 'suggestion',\n docs: {\n description: `Remove a side-effect-only \\`import '${TS_DATA_FORGE_MODULE}';\\`, which binds no name and, the package being \\`sideEffects: false\\`, does nothing.`,\n },\n fixable: 'code',\n schema: [],\n messages: {\n removeSideEffectImport: `\\`import '${TS_DATA_FORGE_MODULE}';\\` binds no name, and \\`${TS_DATA_FORGE_MODULE}\\` declares \\`sideEffects: false\\`, so loading it does nothing. Remove it, and import what you need by name.`,\n },\n },\n\n create: (context) => ({\n ImportDeclaration: (node) => {\n if (\n node.source.value !== TS_DATA_FORGE_MODULE ||\n !Arr.isEmpty(node.specifiers)\n ) {\n return;\n }\n\n context.report({\n node,\n messageId: 'removeSideEffectImport',\n fix: (fixer) => removeStatement(fixer, context.sourceCode, node),\n });\n },\n }),\n defaultOptions: [],\n} as const;\n\n/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */\n\n/**\n * Removes a statement along with the rest of its line, so that deleting it does\n * not leave a blank line where it was.\n */\nconst removeStatement = (\n fixer: TSESLint.RuleFixer,\n sourceCode: TSESLint.SourceCode,\n node: TSESTree.Node,\n): TSESLint.RuleFix => {\n const restOfLine = /^[^\\S\\n]*\\n/u.exec(\n sourceCode.getText().slice(node.range[1]),\n );\n\n return fixer.removeRange([\n node.range[0],\n node.range[1] + (restOfLine?.[0].length ?? 0),\n ]);\n};\n"],"names":[],"mappings":";;;AAmBO,MAAM,kBAAA,GAA+D;AAAA,EAC1E,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,YAAA;AAAA,IACN,IAAA,EAAM;AAAA,MACJ,WAAA,EAAa,uCAAuC,oBAAoB,CAAA,sFAAA;AAAA,KAC1E;AAAA,IACA,OAAA,EAAS,MAAA;AAAA,IACT,QAAQ,EAAC;AAAA,IACT,QAAA,EAAU;AAAA,MACR,sBAAA,EAAwB,CAAA,UAAA,EAAa,oBAAoB,CAAA,0BAAA,EAA6B,oBAAoB,CAAA,4GAAA;AAAA;AAC5G,GACF;AAAA,EAEA,MAAA,EAAQ,CAAC,OAAA,MAAa;AAAA,IACpB,iBAAA,EAAmB,CAAC,IAAA,KAAS;AAC3B,MAAA,IACE,IAAA,CAAK,OAAO,KAAA,KAAU,oBAAA,IACtB,CAAC,GAAA,CAAI,OAAA,CAAQ,IAAA,CAAK,UAAU,CAAA,EAC5B;AACA,QAAA;AAAA,MACF;AAEA,MAAA,OAAA,CAAQ,MAAA,CAAO;AAAA,QACb,IAAA;AAAA,QACA,SAAA,EAAW,wBAAA;AAAA,QACX,KAAK,CAAC,KAAA,KAAU,gBAAgB,KAAA,EAAO,OAAA,CAAQ,YAAY,IAAI;AAAA,OAChE,CAAA;AAAA,IACH;AAAA,GACF,CAAA;AAAA,EACA,gBAAgB;AAClB;AAQA,MAAM,eAAA,GAAkB,CACtB,KAAA,EACA,UAAA,EACA,IAAA,KACqB;AACrB,EAAA,MAAM,aAAa,cAAA,CAAe,IAAA;AAAA,IAChC,WAAW,OAAA,EAAQ,CAAE,MAAM,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC;AAAA,GAC1C;AAEA,EAAA,OAAO,MAAM,WAAA,CAAY;AAAA,IACvB,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,IACZ,KAAK,KAAA,CAAM,CAAC,KAAK,UAAA,GAAa,CAAC,EAAE,MAAA,IAAU,CAAA;AAAA,GAC5C,CAAA;AACH,CAAA;;"}
1
+ {"version":3,"file":"no-side-effect-import.mjs","sourceRoot":"","sources":["../../src/rules/no-side-effect-import.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAMvD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA6C;IAC1E,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EAAE,uCAAuC,oBAAoB,wFAAwF;SACjK;QACD,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,sBAAsB,EAAE,aAAa,oBAAoB,6BAA6B,oBAAoB,8GAA8G;SACzN;KACF;IAED,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACpB,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1B,IACE,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,oBAAoB;gBAC1C,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAC7B,CAAC;gBACD,OAAO;YACT,CAAC;YAED,OAAO,CAAC,MAAM,CAAC;gBACb,IAAI;gBACJ,SAAS,EAAE,wBAAwB;gBACnC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;aACjE,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IACF,cAAc,EAAE,EAAE;CACV,CAAC;AAEX,uEAAuE;AAEvE;;;GAGG;AACH,MAAM,eAAe,GAAG,CACtB,KAAyB,EACzB,UAA+B,EAC/B,IAAmB,EACD,EAAE;IACpB,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CACpC,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC1C,CAAC;IAEF,OAAO,KAAK,CAAC,WAAW,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACb,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;KAC9C,CAAC,CAAC;AACL,CAAC,CAAC"}