@dvukovic/style-guide 0.3.97 → 0.3.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -152
- package/package.json +16 -16
- package/src/cspell/base.txt +12 -0
- package/src/eslint/configs/core.js +42 -30
- package/src/eslint/configs/core.test.js +4 -4
- package/src/eslint/configs/jest.js +26 -3
- package/src/eslint/configs/jest.test.js +3 -3
- package/src/eslint/configs/mobx.js +15 -3
- package/src/eslint/configs/mobx.test.js +3 -3
- package/src/eslint/configs/next.js +15 -3
- package/src/eslint/configs/next.test.js +3 -3
- package/src/eslint/configs/node.js +16 -4
- package/src/eslint/configs/node.test.js +3 -3
- package/src/eslint/configs/playwright.js +26 -3
- package/src/eslint/configs/playwright.test.js +3 -3
- package/src/eslint/configs/react.js +16 -4
- package/src/eslint/configs/react.test.js +3 -3
- package/src/eslint/configs/storybook.js +15 -3
- package/src/eslint/configs/storybook.test.js +3 -3
- package/src/eslint/configs/typescript-strict.js +14 -2
- package/src/eslint/configs/typescript-strict.test.js +6 -4
- package/src/eslint/configs/typescript.js +37 -4
- package/src/eslint/configs/typescript.test.js +6 -4
- package/src/eslint/configs/vitest.js +26 -3
- package/src/eslint/configs/vitest.test.js +3 -3
- package/src/eslint/index.js +25 -0
- package/src/eslint/plugins/dvukovic.js +15 -0
- package/src/eslint/plugins/es-x.js +7 -6
- package/src/eslint/plugins/eslint-comments.js +4 -5
- package/src/eslint/plugins/eslint.js +9 -3
- package/src/eslint/plugins/eslint.test.js +42 -0
- package/src/eslint/plugins/import-x.js +4 -5
- package/src/eslint/plugins/jest.js +4 -5
- package/src/eslint/plugins/mobx.js +4 -5
- package/src/eslint/plugins/n.js +4 -5
- package/src/eslint/plugins/next.js +4 -5
- package/src/eslint/plugins/playwright.js +4 -5
- package/src/eslint/plugins/promise.js +4 -5
- package/src/eslint/plugins/react-hooks.js +4 -5
- package/src/eslint/plugins/react.js +4 -5
- package/src/eslint/plugins/rimac.js +4 -5
- package/src/eslint/plugins/security-node.js +4 -5
- package/src/eslint/plugins/simple-import-sort.js +4 -5
- package/src/eslint/plugins/sonarjs.js +261 -37
- package/src/eslint/plugins/sort-destructure-keys.js +4 -5
- package/src/eslint/plugins/sort-keys-fix.js +4 -5
- package/src/eslint/plugins/storybook.js +4 -5
- package/src/eslint/plugins/stylistic.js +4 -5
- package/src/eslint/plugins/typescript-eslint.js +4 -5
- package/src/eslint/plugins/typescript-sort-keys.js +4 -5
- package/src/eslint/plugins/unicorn.js +4 -5
- package/src/eslint/plugins/unused-imports.js +4 -5
- package/src/eslint/plugins/vitest.js +4 -5
- package/src/eslint/rules/no-commented-out-code/no-commented-out-code.js +80 -0
- package/src/eslint/rules/no-commented-out-code/no-commented-out-code.test.js +89 -0
- package/src/eslint/rules/no-commented-out-code/no-commented-out-code.utils.js +119 -0
- package/src/eslint/types.js +19 -0
- package/src/eslint/plugins/etc.js +0 -3
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ESLint } from "eslint"
|
|
2
|
+
import tseslint from "typescript-eslint"
|
|
3
|
+
|
|
4
|
+
import { dvukovic } from "../../plugins/dvukovic.js"
|
|
5
|
+
|
|
6
|
+
const eslint = new ESLint({
|
|
7
|
+
overrideConfig: [
|
|
8
|
+
{
|
|
9
|
+
files: ["**/*.ts"],
|
|
10
|
+
languageOptions: {
|
|
11
|
+
parser: tseslint.parser,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
dvukovic,
|
|
15
|
+
],
|
|
16
|
+
overrideConfigFile: true,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
describe("dvukovic/no-commented-out-code", () => {
|
|
20
|
+
test("detects commented-out code", async () => {
|
|
21
|
+
const code = `// const x = 1\nconst y = 2\n`
|
|
22
|
+
|
|
23
|
+
const results = await eslint.lintText(code, { filePath: "test.ts" })
|
|
24
|
+
const errors = results[0]?.messages.filter((message) => {
|
|
25
|
+
return message.ruleId === "dvukovic/no-commented-out-code"
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
expect(errors?.length).toBe(1)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test("detects multi-line commented-out code", async () => {
|
|
32
|
+
const code = `// function foo() {
|
|
33
|
+
// return 1
|
|
34
|
+
// }
|
|
35
|
+
const y = 2
|
|
36
|
+
`
|
|
37
|
+
|
|
38
|
+
const results = await eslint.lintText(code, { filePath: "test.ts" })
|
|
39
|
+
const errors = results[0]?.messages.filter((message) => {
|
|
40
|
+
return message.ruleId === "dvukovic/no-commented-out-code"
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
expect(errors?.length).toBe(1)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test("detects block commented-out code", async () => {
|
|
47
|
+
const code = `/* const x = 1 */\nconst y = 2\n`
|
|
48
|
+
|
|
49
|
+
const results = await eslint.lintText(code, { filePath: "test.ts" })
|
|
50
|
+
const errors = results[0]?.messages.filter((message) => {
|
|
51
|
+
return message.ruleId === "dvukovic/no-commented-out-code"
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
expect(errors?.length).toBe(1)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test("allows regular comments", async () => {
|
|
58
|
+
const code = `// This is a regular comment\nconst y = 2\n`
|
|
59
|
+
|
|
60
|
+
const results = await eslint.lintText(code, { filePath: "test.ts" })
|
|
61
|
+
const errors = results[0]?.messages.filter((message) => {
|
|
62
|
+
return message.ruleId === "dvukovic/no-commented-out-code"
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
expect(errors?.length).toBe(0)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test("allows TODO comments", async () => {
|
|
69
|
+
const code = `// TODO: fix this later\nconst y = 2\n`
|
|
70
|
+
|
|
71
|
+
const results = await eslint.lintText(code, { filePath: "test.ts" })
|
|
72
|
+
const errors = results[0]?.messages.filter((message) => {
|
|
73
|
+
return message.ruleId === "dvukovic/no-commented-out-code"
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
expect(errors).toHaveLength(0)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test("allows region comments", async () => {
|
|
80
|
+
const code = `// #region\nconst y = 2\n// #endregion\n`
|
|
81
|
+
|
|
82
|
+
const results = await eslint.lintText(code, { filePath: "test.ts" })
|
|
83
|
+
const errors = results[0]?.messages.filter((message) => {
|
|
84
|
+
return message.ruleId === "dvukovic/no-commented-out-code"
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
expect(errors).toHaveLength(0)
|
|
88
|
+
})
|
|
89
|
+
})
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export function isExpressionOrIdentifierOrLiteral(node) {
|
|
2
|
+
if (node.type === "Identifier") {
|
|
3
|
+
return true
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
if (node.type === "Literal") {
|
|
7
|
+
return true
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (node.type === "BinaryExpression") {
|
|
11
|
+
return (
|
|
12
|
+
isExpressionOrIdentifierOrLiteral(node.left) &&
|
|
13
|
+
isExpressionOrIdentifierOrLiteral(node.right)
|
|
14
|
+
)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function hasEmptyBody(program) {
|
|
21
|
+
return program.type === "Program" && program.body.length === 0
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function hasExpressionBody(program) {
|
|
25
|
+
return (
|
|
26
|
+
program.type === "Program" &&
|
|
27
|
+
program.body.every((statement) => {
|
|
28
|
+
return (
|
|
29
|
+
statement.type === "ExpressionStatement" &&
|
|
30
|
+
isExpressionOrIdentifierOrLiteral(statement.expression)
|
|
31
|
+
)
|
|
32
|
+
})
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function hasLabeledStatementBody(program) {
|
|
37
|
+
return (
|
|
38
|
+
program.type === "Program" &&
|
|
39
|
+
program.body.length === 1 &&
|
|
40
|
+
program.body[0]?.type === "LabeledStatement"
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function isRegionComment(content) {
|
|
45
|
+
return /\s*#(end)?region/.test(content)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function toBlocks(comments) {
|
|
49
|
+
const blocks = []
|
|
50
|
+
let prevLine
|
|
51
|
+
|
|
52
|
+
for (const comment of comments) {
|
|
53
|
+
if (comment.type === "Block") {
|
|
54
|
+
blocks.push({
|
|
55
|
+
content: comment.value.replace(/^\s*\*/, "").replaceAll(/\n\s*\*/g, "\n"),
|
|
56
|
+
loc: { ...comment.loc },
|
|
57
|
+
})
|
|
58
|
+
prevLine = undefined
|
|
59
|
+
} else if (comment.type === "Line") {
|
|
60
|
+
if (prevLine && prevLine.loc.start.line === comment.loc.start.line - 1) {
|
|
61
|
+
const previousBlock = blocks.at(-1)
|
|
62
|
+
|
|
63
|
+
previousBlock.content = `${previousBlock.content}\n${comment.value}`
|
|
64
|
+
previousBlock.loc.end = comment.loc.end
|
|
65
|
+
} else {
|
|
66
|
+
blocks.push({
|
|
67
|
+
content: comment.value,
|
|
68
|
+
loc: { ...comment.loc },
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
prevLine = comment
|
|
73
|
+
} else {
|
|
74
|
+
prevLine = undefined
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return blocks
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function wrapContent(content, node) {
|
|
82
|
+
switch (node?.type) {
|
|
83
|
+
case "ArrayExpression": {
|
|
84
|
+
return `let wrapper = [${content}]`
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
case "ClassBody": {
|
|
88
|
+
return `class Wrapper { ${content} }`
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
case "ImportDeclaration": {
|
|
92
|
+
return `import { ${content} } from "wrapper"`
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
case "ObjectExpression": {
|
|
96
|
+
return `let wrapper = { ${content} }`
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
case "FunctionDeclaration": {
|
|
100
|
+
return `function wrapper(${content}) {}`
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
case "SwitchStatement": {
|
|
104
|
+
return `switch (wrapper) { ${content} }`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
case "TSInterfaceBody": {
|
|
108
|
+
return `interface Wrapper { ${content} }`
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
case "TSTypeLiteral": {
|
|
112
|
+
return `type Wrapper = { ${content} }`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
default: {
|
|
116
|
+
return null
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} ConfigOptions
|
|
3
|
+
* @property {boolean} [replace=false] - If true, replaces default config entirely with custom
|
|
4
|
+
* configs. Default is `false`
|
|
5
|
+
* @property {any[]} [configs=[]] - Additional configs to append or use as replacement. Default is
|
|
6
|
+
* `[]`
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} TypeScriptConfigOptions
|
|
11
|
+
* @property {boolean} [replace=false] - If true, replaces default config entirely with custom
|
|
12
|
+
* configs. Default is `false`
|
|
13
|
+
* @property {any[]} [configs=[]] - Additional configs to append or use as replacement. Default is
|
|
14
|
+
* `[]`
|
|
15
|
+
* @property {string} [tsconfigPath="./tsconfig.json"] - Path to tsconfig.json file. Default is
|
|
16
|
+
* `"./tsconfig.json"`
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export {}
|