@fenge/eslint-plugin 0.4.0 → 0.4.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 (45) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +3 -1
  4. package/dist/rules/call-arguments-length.d.ts.map +1 -1
  5. package/dist/rules/call-arguments-length.js +1 -1
  6. package/dist/rules/no-nested-class.d.ts.map +1 -1
  7. package/dist/rules/no-nested-class.js +1 -1
  8. package/dist/rules/no-nested-function.d.ts.map +1 -1
  9. package/dist/rules/no-nested-function.js +1 -1
  10. package/dist/rules/no-restricted-loops.d.ts.map +1 -1
  11. package/dist/rules/no-restricted-loops.js +1 -1
  12. package/dist/rules/no-top-level-arrow-function.d.ts.map +1 -1
  13. package/dist/rules/no-top-level-arrow-function.js +1 -1
  14. package/dist/rules/no-triple-slash-directive.d.ts +6 -0
  15. package/dist/rules/no-triple-slash-directive.d.ts.map +1 -0
  16. package/dist/rules/no-triple-slash-directive.js +33 -0
  17. package/dist/utils.d.ts +2 -0
  18. package/dist/utils.d.ts.map +1 -1
  19. package/dist/utils.js +1 -1
  20. package/package.json +5 -3
  21. package/CHANGELOG.md +0 -46
  22. package/doc/rules/call-arguments-length.md +0 -52
  23. package/doc/rules/no-instanceof-builtin.md +0 -50
  24. package/doc/rules/no-nested-class.md +0 -31
  25. package/doc/rules/no-nested-function.md +0 -42
  26. package/doc/rules/no-restricted-loops.md +0 -23
  27. package/doc/rules/no-top-level-arrow-function.md +0 -45
  28. package/doc/rules/no-unnecessary-template-string.md +0 -34
  29. package/src/index.ts +0 -17
  30. package/src/rules/call-arguments-length.test.ts +0 -48
  31. package/src/rules/call-arguments-length.ts +0 -163
  32. package/src/rules/no-instanceof-builtin.test.ts +0 -48
  33. package/src/rules/no-instanceof-builtin.ts +0 -46
  34. package/src/rules/no-nested-class.test.ts +0 -27
  35. package/src/rules/no-nested-class.ts +0 -31
  36. package/src/rules/no-nested-function.test.ts +0 -49
  37. package/src/rules/no-nested-function.ts +0 -32
  38. package/src/rules/no-restricted-loops.test.ts +0 -13
  39. package/src/rules/no-restricted-loops.ts +0 -30
  40. package/src/rules/no-top-level-arrow-function.test.ts +0 -32
  41. package/src/rules/no-top-level-arrow-function.ts +0 -35
  42. package/src/rules/no-unnecessary-template-string.test.ts +0 -25
  43. package/src/rules/no-unnecessary-template-string.ts +0 -29
  44. package/src/utils.ts +0 -7
  45. package/tsconfig.json +0 -5
package/src/index.ts DELETED
@@ -1,17 +0,0 @@
1
- import { callArgumentsLength } from "./rules/call-arguments-length.ts";
2
- import { noInstanceofBuiltin } from "./rules/no-instanceof-builtin.ts";
3
- import { noNestedClass } from "./rules/no-nested-class.ts";
4
- import { noNestedFunction } from "./rules/no-nested-function.ts";
5
- import { noRestrictedLoops } from "./rules/no-restricted-loops.ts";
6
- import { noTopLevelArrowFunction } from "./rules/no-top-level-arrow-function.ts";
7
- import { noUnnecessaryTemplateString } from "./rules/no-unnecessary-template-string.ts";
8
-
9
- export const rules = {
10
- [callArgumentsLength.name]: callArgumentsLength.rule,
11
- [noInstanceofBuiltin.name]: noInstanceofBuiltin.rule,
12
- [noNestedClass.name]: noNestedClass.rule,
13
- [noNestedFunction.name]: noNestedFunction.rule,
14
- [noRestrictedLoops.name]: noRestrictedLoops.rule,
15
- [noTopLevelArrowFunction.name]: noTopLevelArrowFunction.rule,
16
- [noUnnecessaryTemplateString.name]: noUnnecessaryTemplateString.rule,
17
- };
@@ -1,48 +0,0 @@
1
- import { test } from "@fenge/dev-utils";
2
- import { callArgumentsLength } from "./call-arguments-length.ts";
3
-
4
- const valid = [
5
- "push()",
6
- "[].push('')",
7
- "foo.push('')",
8
- "foo.push(bar)",
9
- "[].push('', '', '')",
10
- "[].push(...foo)",
11
- "foo.push(...([]))",
12
-
13
- "[].reduce(()=>123, 0)",
14
- "foo.reduce(()=>123, 0)",
15
- "foo.reduce(bar, baz)",
16
- "[].reduceRight(()=>123, 0)",
17
- "foo.reduceRight(()=>123, 0)",
18
- "foo.reduceRight(bar, baz)",
19
- "reduce(()=>123)",
20
- "foo.reduceLeft(()=>123)",
21
- "Math.max(...foo)",
22
-
23
- "new foo.Set(...bar)",
24
- "new Set(bar)",
25
- "new Set()",
26
- ];
27
- const invalid = [
28
- "[].push()",
29
- "foo.push()",
30
-
31
- "foo.reduce()",
32
- "[].reduce(()=>123)",
33
- "foo.reduce(()=>123)",
34
- "foo.reduce(bar)",
35
- "[].reduceRight(()=>123)",
36
- "foo.reduceRight(()=>123)",
37
- "foo.reduceRight(bar)",
38
- "[].reduce(...foo)",
39
- "[].reduce(...foo, ...bar)",
40
- "Math.max()",
41
- "Math.max(1)",
42
- "Math.min(foo)",
43
-
44
- "new Set(...foo)",
45
- "new Set(foo,bar)",
46
- ];
47
-
48
- test({ valid, invalid, ...callArgumentsLength });
@@ -1,163 +0,0 @@
1
- import type { Rule } from "eslint";
2
- import type { CallExpression, NewExpression } from "estree";
3
- import { getRuleName } from "../utils.ts";
4
-
5
- // TODO: If https://github.com/sindresorhus/eslint-plugin-unicorn/issues/1356 is implemented, migrate this rule to `eslint-plugin-unicorn`
6
- const name = getRuleName(import.meta.url);
7
- const rule: Rule.RuleModule = {
8
- meta: {
9
- docs: {
10
- description:
11
- "Disallow calling a function with incorrect arguments length.",
12
- },
13
- messages: {
14
- [`${name}/error`]:
15
- "The arguments length of calling `{{ functionPattern }}` should be {{ lengthMsg }}",
16
- },
17
- schema: [{ type: "object" }], // TODO: enhance schema for checking options
18
- },
19
- create: (context) => {
20
- const getLengthMsg = (expectedLength: unknown) => {
21
- if (typeof expectedLength === "number") {
22
- return String(expectedLength);
23
- }
24
- if (Array.isArray(expectedLength)) {
25
- return expectedLength.join(" or ");
26
- }
27
- const result: string[] = [];
28
- if (
29
- typeof expectedLength === "object" &&
30
- expectedLength &&
31
- "min" in expectedLength
32
- ) {
33
- result.push(`>= ${String(expectedLength.min)}`);
34
- }
35
- if (
36
- typeof expectedLength === "object" &&
37
- expectedLength &&
38
- "max" in expectedLength
39
- ) {
40
- result.push(`<= ${String(expectedLength.max)}`);
41
- }
42
- return result.join(" and ");
43
- };
44
- const isLengthValid = (length: number, expectedLength: unknown) => {
45
- if (typeof expectedLength === "number") {
46
- return length === expectedLength;
47
- }
48
- if (Array.isArray(expectedLength)) {
49
- return expectedLength.includes(length);
50
- }
51
- const result: boolean[] = [];
52
- if (
53
- typeof expectedLength === "object" &&
54
- expectedLength &&
55
- "min" in expectedLength &&
56
- typeof expectedLength.min === "number"
57
- ) {
58
- result.push(length >= expectedLength.min);
59
- }
60
- if (
61
- typeof expectedLength === "object" &&
62
- expectedLength &&
63
- "max" in expectedLength &&
64
- typeof expectedLength.max === "number"
65
- ) {
66
- result.push(length <= expectedLength.max);
67
- }
68
- return result.every((item) => item);
69
- };
70
- const report = (
71
- node: CallExpression | NewExpression,
72
- functionPattern: string,
73
- expectedLength: unknown,
74
- ) => {
75
- const argsLength = node.arguments.some(
76
- (arg) => arg.type === "SpreadElement",
77
- )
78
- ? Infinity
79
- : node.arguments.length;
80
- if (!isLengthValid(argsLength, expectedLength))
81
- context.report({
82
- node,
83
- messageId: `${name}/error`,
84
- data: {
85
- functionPattern,
86
- lengthMsg: getLengthMsg(expectedLength),
87
- },
88
- });
89
- };
90
-
91
- const options = Object.entries(
92
- context.options[0] ?? {
93
- // 1
94
- "*.reduce": 2,
95
- "*.reduceRight": 2,
96
- "*.push": { min: 1 },
97
- "Math.max": { min: 2 },
98
- "Math.min": { min: 2 },
99
- // 2
100
- "new Set": { max: 1 },
101
- "new Map": { max: 1 },
102
- },
103
- ).map(([pattern, expectedLength]) => ({
104
- regex: new RegExp(
105
- `^${pattern.replaceAll(".", "\\.").replaceAll("*", ".*")}$`,
106
- ),
107
- pattern,
108
- expectedLength,
109
- }));
110
-
111
- const handle = (node: CallExpression | NewExpression) => {
112
- const prefix = node.type === "NewExpression" ? "new " : "";
113
-
114
- const { callee } = node;
115
- // function call
116
- if (callee.type === "Identifier") {
117
- // code like `foo()` or `new Foo()`
118
- options
119
- .filter((option) => option.regex.test(`${prefix}${callee.name}`))
120
- .forEach(({ pattern, expectedLength }) => {
121
- report(node, pattern, expectedLength);
122
- });
123
- }
124
- // method call
125
- else if (
126
- callee.type === "MemberExpression" &&
127
- callee.property.type === "Identifier"
128
- ) {
129
- const { object: calleeObject, property: calleeProperty } = callee;
130
- options
131
- .filter((option) => {
132
- // code like `Math.max()` or `new Foo.Bar()`, the calleeObject is `Math` or `Foo`
133
- if (
134
- "name" in calleeObject &&
135
- option.regex.test(
136
- `${prefix}${calleeObject.name}.${calleeProperty.name}`,
137
- )
138
- ) {
139
- return true;
140
- }
141
- // code like `[].reduce()` or `new ({Foo: class{}}).Foo()`, the calleeObject is `[]` or `{Foo: class{}}`
142
- if (
143
- !("name" in calleeObject) &&
144
- option.regex.test(`${prefix}.${calleeProperty.name}`)
145
- ) {
146
- return true;
147
- }
148
- return false;
149
- })
150
- .forEach(({ pattern, expectedLength }) => {
151
- report(node, pattern, expectedLength);
152
- });
153
- }
154
- };
155
-
156
- return {
157
- CallExpression: handle,
158
- NewExpression: handle,
159
- };
160
- },
161
- };
162
-
163
- export const callArgumentsLength = { name, rule };
@@ -1,48 +0,0 @@
1
- import { test } from "@fenge/dev-utils";
2
- import { noInstanceofBuiltin } from "./no-instanceof-builtin.ts";
3
-
4
- const invalid = [
5
- // Primitive
6
- "Number",
7
- "String",
8
- "Boolean",
9
- "Symbol",
10
- "BigInt",
11
-
12
- // Object
13
- "Object",
14
- "Array",
15
- "Function",
16
-
17
- // Builtin
18
- "ArrayBuffer",
19
- "BigInt64Array",
20
- "BigUint64Array",
21
- "DataView",
22
- "Date",
23
- "Float32Array",
24
- "Float64Array",
25
- "Int16Array",
26
- "Int32Array",
27
- "Int8Array",
28
- "Map",
29
- "Error",
30
- "Promise",
31
- "Proxy",
32
- "RegExp",
33
- "Set",
34
- "SharedArrayBuffer",
35
- "Uint16Array",
36
- "Uint32Array",
37
- "Uint8Array",
38
- "Uint8ClampedArray",
39
- "WeakMap",
40
- "WeakSet",
41
- ].map((i) => `const i = {} instanceof ${i}`);
42
-
43
- const valid = [
44
- "const i = Math.random() > 0.5 ? true: false",
45
- "const i = {} instanceof await import('http')",
46
- ];
47
-
48
- test({ valid, invalid, ...noInstanceofBuiltin });
@@ -1,46 +0,0 @@
1
- import type { Rule } from "eslint";
2
- import { getRuleName } from "../utils.ts";
3
-
4
- // TODO: If https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2452 is accepted, migrate this rule to `eslint-plugin-unicorn`
5
- const name = getRuleName(import.meta.url);
6
- const rule: Rule.RuleModule = {
7
- meta: {
8
- docs: {
9
- description: "Right hand of `instanceof` can't be a builtin class.",
10
- },
11
- messages: {
12
- [`${name}/error`]: "Right hand of `instanceof` can't be a builtin class.",
13
- },
14
- },
15
- create: (context) => {
16
- let builtins: Set<string> | undefined = undefined;
17
- return {
18
- // ESLint visit the Node from root to leaf. The Program Node is the root.
19
- // Therefore, Program will be called before BinaryExpression.
20
- // https://eslint.org/docs/latest/extend/code-path-analysis
21
- Program: (node) => {
22
- const scope = context.sourceCode.getScope(node);
23
- builtins = new Set([
24
- // Variables declared in `globals`
25
- ...scope.variables.map((v) => v.name),
26
- // Variables not declared at all
27
- ...scope.through.map((ref) => ref.identifier.name),
28
- ]);
29
- },
30
- BinaryExpression: (node) => {
31
- if (
32
- node.operator !== "instanceof" ||
33
- node.right.type !== "Identifier"
34
- ) {
35
- return;
36
- }
37
-
38
- if (builtins?.has(node.right.name) ?? true) {
39
- context.report({ node: node.right, messageId: `${name}/error` });
40
- }
41
- },
42
- };
43
- },
44
- };
45
-
46
- export const noInstanceofBuiltin = { name, rule };
@@ -1,27 +0,0 @@
1
- import { test } from "@fenge/dev-utils";
2
- import { noNestedClass } from "./no-nested-class.ts";
3
-
4
- const valid = [
5
- "class Foo{}",
6
- "export class Foo{}",
7
- "export default class Foo{}",
8
- "export default class {}",
9
- ];
10
-
11
- const invalid = [
12
- // nested
13
- "if(true) class Foo{}",
14
- "if(true) const foo = class {}",
15
- "function foo(){class Foo{}}",
16
- "function foo(){const foo = class {}}",
17
- "function foo(){return class Foo{}}",
18
- "function foo(){return class{}}",
19
-
20
- // normal
21
- "const Foo = class{}",
22
- "let Foo = class Bar{}",
23
- "let Foo; Foo = class{}",
24
- "(class {})",
25
- ];
26
-
27
- test({ valid, invalid, ...noNestedClass });
@@ -1,31 +0,0 @@
1
- import type { Rule } from "eslint";
2
- import type { Node } from "estree";
3
- import { getRuleName } from "../utils.ts";
4
-
5
- const name = getRuleName(import.meta.url);
6
- const rule: Rule.RuleModule = {
7
- meta: {
8
- docs: {
9
- description:
10
- "Disallow nested class. Classes are expected to place at top level.",
11
- },
12
- messages: {
13
- [`${name}/error`]:
14
- "Disallow nested class. Classes are expected to place at top level.",
15
- },
16
- },
17
- create: (context) => {
18
- const handle = (node: Node) =>
19
- context.report({ node, messageId: `${name}/error` });
20
- return {
21
- // ClassDeclaration is only allowed when parent is Program, or parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
22
- "ClassDeclaration[parent.type!='Program'][parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']":
23
- handle,
24
- // ClassExpression is only allowed when parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
25
- "ClassExpression[parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']":
26
- handle,
27
- };
28
- },
29
- };
30
-
31
- export const noNestedClass = { name, rule };
@@ -1,49 +0,0 @@
1
- import { test } from "@fenge/dev-utils";
2
- import { noNestedFunction } from "./no-nested-function.ts";
3
-
4
- const valid = [
5
- // normal
6
- "function foo(){}",
7
- "const foo = () => {}",
8
-
9
- // export
10
- "export function foo() {}",
11
- "export default function foo() {}",
12
- "export default function() {}",
13
-
14
- // class
15
- "class Foo{bar(){}}",
16
- ];
17
-
18
- const invalid = [
19
- // normal
20
- "Foo.prototype.bar = function(){}",
21
- "Foo.prototype.bar = function bar(){}",
22
- "const foo = function(){}",
23
- "const foo = function foo(){}",
24
- "let foo; foo = function(){}",
25
- "let foo; foo = function foo(){}",
26
- "(function(){})",
27
-
28
- // nested
29
- "const foo = () => {function bar(){}}",
30
- "function foo() {function bar(){}}",
31
- "function foo() {let bar = function(){}}",
32
- "function foo() {let bar = function bar(){}}",
33
- "if(true) function foo(){}",
34
-
35
- // class
36
- "class Foo{bar = function(){}}",
37
- "class Foo{bar = function bar(){}}",
38
-
39
- // object
40
- "const foo = {bar: function() {}}",
41
- "const foo = {bar: function bar() {}}",
42
- "const foo = {bar() {}}", // disallow this case
43
-
44
- // callback
45
- "setTimeout(function(){},100)",
46
- "setTimeout(function callback(){},100)",
47
- ];
48
-
49
- test({ valid, invalid, ...noNestedFunction });
@@ -1,32 +0,0 @@
1
- import type { Rule } from "eslint";
2
- import type { Node } from "estree";
3
- import { getRuleName } from "../utils.ts";
4
-
5
- const name = getRuleName(import.meta.url);
6
- const rule: Rule.RuleModule = {
7
- meta: {
8
- docs: {
9
- description:
10
- "Non top-level functions are expected to be arrow functions instead of function declarations.",
11
- },
12
- messages: {
13
- [`${name}/error`]:
14
- "Non top-level functions are expected to be arrow functions instead of function declarations.",
15
- },
16
- },
17
- create: (context) => {
18
- const handle = (node: Node) =>
19
- context.report({ node, messageId: `${name}/error` });
20
- return {
21
- // FunctionDeclaration is only allowed when parent is Program, or parent is ExportNamedDeclaration, or parent is ExportDefaultDeclaration
22
- // function foo(){}
23
- "FunctionDeclaration[parent.type!='Program'][parent.type!='ExportNamedDeclaration'][parent.type!='ExportDefaultDeclaration']":
24
- handle,
25
- // FunctionExpression is only allowed when parent is MethodDefinition
26
- // function (){}
27
- "FunctionExpression[parent.type!='MethodDefinition']": handle,
28
- };
29
- },
30
- };
31
-
32
- export const noNestedFunction = { name, rule };
@@ -1,13 +0,0 @@
1
- import { test } from "@fenge/dev-utils";
2
- import { noRestrictedLoops } from "./no-restricted-loops.ts";
3
-
4
- const valid = ["for(const bar of foo) {}", "while(condition){}"];
5
-
6
- const invalid = [
7
- "for(let i = 0; i < foo.length; i++) {}",
8
- "for(const bar in foo) {}",
9
- "do{}while(condition)",
10
- "for await (const bar of foo()) {}",
11
- ];
12
-
13
- test({ valid, invalid, ...noRestrictedLoops });
@@ -1,30 +0,0 @@
1
- import type { Rule } from "eslint";
2
- import type { Node } from "estree";
3
- import { getRuleName } from "../utils.ts";
4
-
5
- // TODO: If https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2453 is accepted, migrate this rule to `eslint-plugin-unicorn`
6
- const name = getRuleName(import.meta.url);
7
- /**
8
- * Only allow `while` and `for-of` loops. `for`, `for-in`, `do-while` and `for-await-of` loops are disallowed.
9
- * Visit https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2453 for more details.
10
- */
11
- const rule: Rule.RuleModule = {
12
- meta: {
13
- docs: {
14
- description:
15
- "Only allow `while` and `for-of` loops. `for`, `for-in`, `do-while` and `for-await-of` loops are disallowed.",
16
- },
17
- messages: {
18
- [`${name}/error`]:
19
- "Only allow `while` and `for-of` loops. `for`, `for-in`, `do-while` and `for-await-of` loops are disallowed.",
20
- },
21
- },
22
- create: (context) => ({
23
- ":matches(ForStatement, ForInStatement, DoWhileStatement, ForOfStatement[await=true])":
24
- (node: Node) => {
25
- context.report({ node, messageId: `${name}/error` });
26
- },
27
- }),
28
- };
29
-
30
- export const noRestrictedLoops = { name, rule };
@@ -1,32 +0,0 @@
1
- import { test } from "@fenge/dev-utils";
2
- import { noTopLevelArrowFunction } from "./no-top-level-arrow-function.ts";
3
-
4
- const valid = [
5
- "function foo(){}",
6
- "const foo = function(){}",
7
- "const foo = function foo(){}",
8
- "if(true) const foo = () => {\n}",
9
-
10
- // allow one-line function
11
- "let foo = () => ''",
12
- "let foo = () => [\n]",
13
- "let foo = () => ({})",
14
- "const foo = () => ({})",
15
- "let foo; foo = () => ({})",
16
- "export const foo = () => ({})",
17
- "export let foo = () => ({})",
18
- "export default () => ({})",
19
- ];
20
-
21
- const invalid = [
22
- "let foo = () => {}",
23
- "const foo = () => {}",
24
- "let foo = () => {\n}",
25
- "const foo = () => {\n}",
26
- "let foo; foo = () => {\n}",
27
- "export const foo = () => {\n}",
28
- "export let foo = () => {\n}",
29
- "export default () => {\n}",
30
- ];
31
-
32
- test({ valid, invalid, ...noTopLevelArrowFunction });
@@ -1,35 +0,0 @@
1
- import type { Rule } from "eslint";
2
- import type { ArrowFunctionExpression } from "estree";
3
- import { getRuleName } from "../utils.ts";
4
-
5
- const name = getRuleName(import.meta.url);
6
- const rule: Rule.RuleModule = {
7
- meta: {
8
- docs: {
9
- description:
10
- "Top-level functions are expected to be function declarations instead of arrow functions.",
11
- },
12
- messages: {
13
- [`${name}/error`]:
14
- "Top-level functions are expected to be function declarations instead of arrow functions.",
15
- },
16
- },
17
- create: (context) => {
18
- const handle = (node: ArrowFunctionExpression) => {
19
- if (node.body.type === "BlockStatement") {
20
- context.report({ node, messageId: `${name}/error` });
21
- }
22
- };
23
- return {
24
- "VariableDeclaration[parent.type='Program'] > VariableDeclarator > ArrowFunctionExpression":
25
- handle,
26
- "ExpressionStatement[parent.type='Program'] > AssignmentExpression > ArrowFunctionExpression":
27
- handle,
28
- "ExportNamedDeclaration > VariableDeclaration > VariableDeclarator > ArrowFunctionExpression":
29
- handle,
30
- "ExportDefaultDeclaration > ArrowFunctionExpression": handle,
31
- };
32
- },
33
- };
34
-
35
- export const noTopLevelArrowFunction = { name, rule };
@@ -1,25 +0,0 @@
1
- import { test } from "@fenge/dev-utils";
2
- import { noUnnecessaryTemplateString } from "./no-unnecessary-template-string.ts";
3
-
4
- const valid = [
5
- "'abc'",
6
- '"def"',
7
- "`ab${cd}ef`",
8
- "`\n`",
9
- "`abc\n`",
10
- "`\nabc`",
11
- "`a\nbc`",
12
- ];
13
-
14
- const invalid = [
15
- // Currently, tagged template string should be reported as well.
16
- // Moving it to `valid` part is also reasonable.
17
- "outdent`foo`",
18
- "``",
19
- "`abc`",
20
- "`abc\\n`",
21
- "`\\nabc`",
22
- "`a\\nbc`",
23
- ];
24
-
25
- test({ valid, invalid, ...noUnnecessaryTemplateString });
@@ -1,29 +0,0 @@
1
- import type { Rule } from "eslint";
2
- import { getRuleName } from "../utils.ts";
3
-
4
- // TODO deprecate this rule if https://github.com/sindresorhus/eslint-plugin-unicorn/issues/71 is implemented.
5
- const name = getRuleName(import.meta.url);
6
- const rule: Rule.RuleModule = {
7
- meta: {
8
- docs: {
9
- description:
10
- "Disallow using template string when it's unnecessary. Use normal literal string expression instead.",
11
- },
12
- messages: {
13
- [`${name}/error`]:
14
- "Disallow using template string when it's unnecessary. Use normal literal string expression instead.",
15
- },
16
- },
17
- create: (context) => ({
18
- TemplateLiteral: (node) => {
19
- if (
20
- node.quasis.length === 1 &&
21
- node.expressions.length === 0 &&
22
- node.loc?.start.line === node.loc?.end.line
23
- ) {
24
- context.report({ node, messageId: `${name}/error` });
25
- }
26
- },
27
- }),
28
- };
29
- export const noUnnecessaryTemplateString = { name, rule };
package/src/utils.ts DELETED
@@ -1,7 +0,0 @@
1
- import path from "node:path";
2
- import { fileURLToPath } from "node:url";
3
-
4
- export function getRuleName(importMetaUrl: string) {
5
- // remove '.js' extension
6
- return path.basename(fileURLToPath(importMetaUrl)).slice(0, -3);
7
- }
package/tsconfig.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "extends": "../../tsconfig",
3
- "include": ["src"],
4
- "exclude": ["**/*.test.ts"]
5
- }