@firefoxic/eslint-config 6.0.0 → 6.0.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.
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import noMultilineNamedImports from "./no-multiline-named-imports/index.js"
|
|
2
|
+
import noSingleQuotesInImportsAndObjectKeys from "./no-single-quotes-in-imports-and-object-keys/index.js"
|
|
3
|
+
|
|
4
|
+
const plugin = {
|
|
5
|
+
// preferred location of name and version
|
|
6
|
+
meta: {
|
|
7
|
+
name: `eslint-plugin-enough-is-enough`,
|
|
8
|
+
namespace: `enough-is-enough`,
|
|
9
|
+
},
|
|
10
|
+
rules: {
|
|
11
|
+
"no-multiline-named-imports": noMultilineNamedImports,
|
|
12
|
+
"no-single-quotes-in-imports-and-object-keys": noSingleQuotesInImportsAndObjectKeys,
|
|
13
|
+
},
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default plugin
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
type: `layout`,
|
|
4
|
+
fixable: `code`,
|
|
5
|
+
messages: {
|
|
6
|
+
multiline: `Multi-line named imports are disallowed.`,
|
|
7
|
+
},
|
|
8
|
+
},
|
|
9
|
+
create (context) {
|
|
10
|
+
let sourceCode = context.sourceCode
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
ImportDeclaration (node) {
|
|
14
|
+
let namedSpecifiers = node.specifiers.filter((s) => s.type === `ImportSpecifier`)
|
|
15
|
+
|
|
16
|
+
if (namedSpecifiers.length === 0) return
|
|
17
|
+
|
|
18
|
+
let tokens = sourceCode.getTokens(node)
|
|
19
|
+
let openBrace = tokens.find((t) => t.value === `{`)
|
|
20
|
+
let closeBrace = tokens.reverse().find((t) => t.value === `}`)
|
|
21
|
+
|
|
22
|
+
if (!openBrace || !closeBrace) return
|
|
23
|
+
|
|
24
|
+
if (openBrace.loc.start.line !== closeBrace.loc.end.line) {
|
|
25
|
+
context.report({
|
|
26
|
+
node,
|
|
27
|
+
messageId: `multiline`,
|
|
28
|
+
fix (fixer) {
|
|
29
|
+
let imports = namedSpecifiers.map((s) => sourceCode.getText(s)).join(`, `)
|
|
30
|
+
let defaultImport = node.specifiers.find((s) => s.type === `ImportDefaultSpecifier`)
|
|
31
|
+
let namespaceImport = node.specifiers.find((s) => s.type === `ImportNamespaceSpecifier`)
|
|
32
|
+
let source = sourceCode.getText(node.source)
|
|
33
|
+
|
|
34
|
+
let newImport = `import `
|
|
35
|
+
|
|
36
|
+
if (defaultImport) newImport += `${sourceCode.getText(defaultImport)}, `
|
|
37
|
+
if (namespaceImport) newImport += `${sourceCode.getText(namespaceImport)}, `
|
|
38
|
+
newImport += `{ ${imports} } from ${source}`
|
|
39
|
+
|
|
40
|
+
let lastToken = sourceCode.getLastToken(node)
|
|
41
|
+
let hasSemicolon = lastToken && lastToken.value === `;`
|
|
42
|
+
|
|
43
|
+
if (hasSemicolon) newImport += `;`
|
|
44
|
+
|
|
45
|
+
return fixer.replaceText(node, newImport)
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
type: `suggestion`,
|
|
4
|
+
docs: { description: `Disallow single quotes in import/export sources and object keys when quoted` },
|
|
5
|
+
fixable: `code`,
|
|
6
|
+
schema: [],
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
create (context) {
|
|
10
|
+
let sourceCode = context.sourceCode
|
|
11
|
+
|
|
12
|
+
function isSingleQuoted (node) {
|
|
13
|
+
if (typeof node.value !== `string`) return false
|
|
14
|
+
|
|
15
|
+
let text = sourceCode.getText(node)
|
|
16
|
+
|
|
17
|
+
return text.startsWith(`'`) && text.endsWith(`'`)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function checkLiteralInImportOrExport (node) {
|
|
21
|
+
if (!node.source) return
|
|
22
|
+
|
|
23
|
+
let literal = node.source
|
|
24
|
+
|
|
25
|
+
if (isSingleQuoted(literal)) {
|
|
26
|
+
context.report({
|
|
27
|
+
node: literal,
|
|
28
|
+
message: `Use double quotes for import/export source.`,
|
|
29
|
+
fix (fixer) {
|
|
30
|
+
let newText = `"${literal.value.replace(/"/g, `\\"`)}"`
|
|
31
|
+
|
|
32
|
+
return fixer.replaceText(literal, newText)
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function checkObjectExpression (node) {
|
|
39
|
+
let properties = node.properties
|
|
40
|
+
|
|
41
|
+
let hasQuotedKey = properties.some(
|
|
42
|
+
(prop) => prop.type === `Property`
|
|
43
|
+
&& prop.key.type === `Literal`
|
|
44
|
+
&& typeof prop.key.value === `string`,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if (!hasQuotedKey) return
|
|
48
|
+
|
|
49
|
+
for (let prop of properties) {
|
|
50
|
+
if (
|
|
51
|
+
prop.type !== `Property`
|
|
52
|
+
|| prop.key.type !== `Literal`
|
|
53
|
+
|| typeof prop.key.value !== `string`
|
|
54
|
+
) continue
|
|
55
|
+
|
|
56
|
+
let key = prop.key
|
|
57
|
+
|
|
58
|
+
if (isSingleQuoted(key)) {
|
|
59
|
+
context.report({
|
|
60
|
+
node: key,
|
|
61
|
+
message: `Use double quotes for quoted object keys.`,
|
|
62
|
+
fix (fixer) {
|
|
63
|
+
let newText = `"${key.value.replace(/"/g, `\\"`)}"`
|
|
64
|
+
|
|
65
|
+
return fixer.replaceText(key, newText)
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
ImportDeclaration: checkLiteralInImportOrExport,
|
|
74
|
+
ExportNamedDeclaration: checkLiteralInImportOrExport,
|
|
75
|
+
ExportAllDeclaration: checkLiteralInImportOrExport,
|
|
76
|
+
ObjectExpression: checkObjectExpression,
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firefoxic/eslint-config",
|
|
3
3
|
"description": "Shared config for eslint by firefoxic.",
|
|
4
|
-
"version": "6.0.
|
|
4
|
+
"version": "6.0.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Sergey Artemov",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"types": "./lib/index.d.ts"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
|
-
"./lib
|
|
28
|
-
"./lib
|
|
27
|
+
"./lib/**/*.d.ts",
|
|
28
|
+
"./lib/**/*.js"
|
|
29
29
|
],
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"eslint": "^9.39.2"
|