eslint-plugin-code-style 3.0.0 → 3.0.2
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 +4 -4
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ When combined with ESLint's native rules and other popular plugins, this package
|
|
|
44
44
|
|
|
45
45
|
<br />
|
|
46
46
|
|
|
47
|
-
[Documentation](https://eslint-plugin-code-style.
|
|
47
|
+
[Documentation](https://www.eslint-plugin-code-style.org) •
|
|
48
48
|
[Installation](#-installation) •
|
|
49
49
|
[Quick Start](#-quick-start) •
|
|
50
50
|
[Recommended Configs](#-recommended-configurations) •
|
|
@@ -290,7 +290,7 @@ rules: {
|
|
|
290
290
|
|
|
291
291
|
> **81 rules total** — 71 with auto-fix 🔧, 20 configurable ⚙️, 10 report-only
|
|
292
292
|
>
|
|
293
|
-
> 📖 **Full documentation with examples:** [eslint-plugin-code-style.
|
|
293
|
+
> 📖 **Full documentation with examples:** [www.eslint-plugin-code-style.org](https://www.eslint-plugin-code-style.org/docs/rules) • [Local docs](./docs/rules/)
|
|
294
294
|
>
|
|
295
295
|
> **Legend:** 🔧 Auto-fixable with `eslint --fix` • ⚙️ Customizable options
|
|
296
296
|
|
|
@@ -401,7 +401,7 @@ rules: {
|
|
|
401
401
|
|
|
402
402
|
## 📖 Rules Reference
|
|
403
403
|
|
|
404
|
-
For detailed documentation with examples, configuration options, and best practices for each rule, see the **[Rules Reference Documentation](https://eslint-plugin-code-style.
|
|
404
|
+
For detailed documentation with examples, configuration options, and best practices for each rule, see the **[Rules Reference Documentation](https://www.eslint-plugin-code-style.org/docs/rules)** or the [local docs](./docs/rules/).
|
|
405
405
|
|
|
406
406
|
| Category | Rules | Highlights |
|
|
407
407
|
|----------|:-----:|------------|
|
|
@@ -468,7 +468,7 @@ rules: {
|
|
|
468
468
|
|
|
469
469
|
## 📖 Documentation
|
|
470
470
|
|
|
471
|
-
Full documentation is available at **[eslint-plugin-code-style.
|
|
471
|
+
Full documentation is available at **[www.eslint-plugin-code-style.org](https://www.eslint-plugin-code-style.org)** — including installation guides, configuration examples, and detailed rule references with good/bad code examples.
|
|
472
472
|
|
|
473
473
|
<br />
|
|
474
474
|
|
package/dist/index.js
CHANGED
|
@@ -281,4 +281,4 @@ ${x})`;e.report({fix:f=>f.replaceTextRange([u.range[0],i.range[1]],o),message:"F
|
|
|
281
281
|
`);return b.replaceTextRange([y.range[1],o.range[0]],E)},message:"No empty lines allowed between interface properties",node:o})}}),s.length>1){let o=n.getText(c),f=o.trimEnd(),T=n.getTokenAfter(c),y=f.endsWith(",")||T&&T.value===",",b=f.endsWith(";"),d=x.loc.start.line===c.loc.end.line;if(b){let E=o.lastIndexOf(";"),w=c.range[0]+E;d?e.report({fix:S=>S.replaceTextRange([w,x.range[0]],`,
|
|
282
282
|
`+a),message:"Last interface property must end with comma and closing brace must be on its own line",node:c}):e.report({fix:S=>S.replaceTextRange([w,w+1],","),message:"Interface properties must end with comma (,) not semicolon (;)",node:c})}else!y&&d?e.report({fix:E=>E.replaceTextRange([c.range[1],x.range[0]],`,
|
|
283
283
|
`+a),message:"Last interface property must have trailing comma and closing brace must be on its own line",node:c}):y?d&&e.report({fix:E=>E.replaceTextRange([c.range[1],x.range[0]],`
|
|
284
|
-
`+a),message:"Closing brace must be on its own line",node:x}):e.report({fix:E=>E.insertTextAfter(c,","),message:"Last interface property must have trailing comma",node:c})}}}},meta:{docs:{description:"Enforce interface naming (PascalCase + Interface suffix), camelCase properties, proper formatting, and trailing commas"},fixable:"code",schema:[],type:"suggestion"}},Zt={create(e){let L=(e.filename||e.getFilename()).replace(/\\/g,"/"),A=r=>new RegExp(`/${r}/[^/]+\\.(ts|tsx)$`).test(L),h=()=>/\.(ts|tsx)$/.test(L);return{TSInterfaceDeclaration(r){h()&&(A("interfaces")||e.report({message:'Interfaces must be declared in files inside the "interfaces" folder',node:r.id||r}))},TSEnumDeclaration(r){h()&&(A("enums")||e.report({message:'Enums must be declared in files inside the "enums" folder',node:r.id||r}))},TSTypeAliasDeclaration(r){h()&&(A("types")||e.report({message:'Type aliases must be declared in files inside the "types" folder',node:r.id||r}))}}},meta:{docs:{description:"Enforce that interfaces are in interfaces folder, enums in enums folder, and types in types folder"},schema:[],type:"suggestion"}};var Kt={create(e){let n=e.sourceCode||e.getSourceCode(),L=/^[a-z][a-zA-Z0-9]*$/,A=/^[A-Z][a-zA-Z0-9]*$/,h=/^use[A-Z][a-zA-Z0-9]*$/,r=/^[A-Z][A-Z0-9_]*$/,u=d=>/^[A-Z][A-Z0-9_]*$/.test(d)?d.toLowerCase().replace(/_([a-z0-9])/g,(E,w)=>w.toUpperCase()):/_/.test(d)?d.toLowerCase().replace(/_([a-z0-9])/g,(E,w)=>w.toUpperCase()):/^[A-Z]/.test(d)?d[0].toLowerCase()+d.slice(1):d,i=d=>{let w=(n.getScope?n.getScope(d):e.getScope()).variables.find(S=>S.name===d.name);return w?w.references.map(S=>S.identifier):[]},s=["ArrowFunctionExpression","CallExpression","FunctionDeclaration","FunctionExpression","Property","VariableDeclarator","JSXElement","JSXOpeningElement","ReturnStatement","SwitchCase","SwitchStatement","ObjectExpression","ObjectPattern","BlockStatement","IfStatement","Identifier","RestElement","AssignmentPattern","ArrayPattern","MemberExpression","JSXText","JSXAttribute","JSXExpressionContainer","Function","Object","Array","String","Number","Boolean","Symbol","BigInt","Date","RegExp","Error","Map","Set","WeakMap","WeakSet","Promise"],l=d=>{if(!d||d.type!=="CallExpression")return!1;let{callee:E}=d;if(E.type==="CallExpression"){let w=E.callee;if(w.type==="Identifier"&&w.name==="styled"||w.type==="MemberExpression"&&w.object.name==="styled")return!0}return!1},a=d=>{if(d.type!=="CallExpression")return!1;let{callee:E}=d;return E.type==="Identifier"&&E.name==="styled"},t=d=>{if(!d)return!1;if(d.type==="ArrowFunctionExpression"||d.type==="FunctionExpression")return!0;if(d.type==="CallExpression"&&d.callee){let E=d.callee.name||d.callee.property&&d.callee.property.name;return["memo","forwardRef","lazy","createContext"].includes(E)}return!1},x=d=>{if(!d.init)return!1;let E=d.id.name;if(/^[A-Z]/.test(E)&&t(d.init)||/^[A-Z]/.test(E)&&d.init.type==="MemberExpression"&&d.init.object.type==="Identifier"&&/^[A-Z]/.test(d.init.object.name))return!0;if(/^[A-Z]/.test(E)&&d.init.type==="ConditionalExpression"){let{consequent:w,alternate:S}=d.init,k=I=>I.type==="Identifier"&&/^[A-Z]/.test(I.name)||I.type==="Literal"&&typeof I.value=="string"||I.type==="MemberExpression"&&I.object.type==="Identifier"&&/^[A-Z]/.test(I.object.name);if(k(w)||k(S))return!0}return!1},p=d=>{if(!d.init)return!1;let E=d.id.name;return E.startsWith("use")&&/^use[A-Z]/.test(E)&&t(d.init)},c=["Icon","Component","FormComponent","Layout","Wrapper","Container","Provider"],o=(d,E)=>{if(d.type==="Identifier"){let w=d.name;if(w.startsWith("_")||r.test(w)||s.includes(w)||c.includes(w))return;L.test(w)||e.report({message:`${E} "${w}" should be camelCase`,node:d})}else d.type==="ObjectPattern"?d.properties.forEach(w=>{w.type==="Property"?o(w.value,E):w.type==="RestElement"&&o(w.argument,E)}):d.type==="ArrayPattern"?d.elements.forEach(w=>{w&&o(w,E)}):d.type==="AssignmentPattern"?o(d.left,E):d.type==="RestElement"&&o(d.argument,E)},f=d=>{if(d.id.type!=="Identifier"){o(d.id,"Variable");return}let E=d.id.name;if(l(d.init)){A.test(E)||e.report({message:`Styled component "${E}" should be PascalCase (e.g., StyledCard instead of styledCard)`,node:d.id});return}if(E.startsWith("_")||x(d))return;let w=["Component","Icon","Layout","Wrapper","Container","Provider","View","Screen","Page"];if(A.test(E)&&w.some(k=>E.endsWith(k)))return;if(p(d)){h.test(E)||e.report({message:`Hook "${E}" should start with "use" followed by PascalCase (e.g., useEventsList)`,node:d.id});return}if(!([/^[A-Z][a-zA-Z]*Data$/,/^[A-Z][a-zA-Z]*Config$/,/^Routes$/].some(k=>k.test(E))&&d.init&&(d.init.type==="ArrayExpression"||d.init.type==="ObjectExpression"||d.init.type==="CallExpression"))&&!L.test(E)){let k=u(E),I=i(d.id);e.report({fix:$=>{let g=[];return I.forEach(m=>{g.push($.replaceText(m,k))}),g},message:`Variable "${E}" should be camelCase (e.g., ${k} instead of ${E})`,node:d.id})}},T=d=>{if(d.computed||d.key.type!=="Identifier")return;let E=d.key.name;if(!(E.startsWith("_")||s.includes(E))){if(d.value&&d.value.type==="Identifier"){let w=d.value.name;if(A.test(w)&&A.test(E))return}if(!c.includes(E)&&!E.startsWith("Mui")&&!L.test(E)){let w=u(E);e.report({fix:S=>S.replaceText(d.key,w),message:`Property "${E}" should be camelCase (e.g., ${w} instead of ${E})`,node:d.key})}}},y=d=>{d.params.forEach(E=>o(E,"Parameter"))};return{ArrowFunctionExpression:y,CallExpression:d=>{a(d)||d.arguments.forEach(E=>{if(E.type==="Identifier"){let w=E.name;if(w.startsWith("_")||r.test(w)||s.includes(w)||c.includes(w)||A.test(w))return;if(!L.test(w)){let S=u(w);e.report({fix(k){let I=n.getScope?n.getScope(E):e.getScope(),$=I.variables.find(v=>v.name===w)||I.upper&&I.upper.variables.find(v=>v.name===w);if(!$)return k.replaceText(E,S);let g=[],m=new Set;return $.references.forEach(v=>{let C=`${v.identifier.range[0]}-${v.identifier.range[1]}`;m.has(C)||(m.add(C),g.push(k.replaceText(v.identifier,S)))}),g},message:`Argument "${w}" should be camelCase (e.g., ${S} instead of ${w})`,node:E})}}})},FunctionDeclaration:y,FunctionExpression:y,Property:T,VariableDeclarator:f}},meta:{docs:{description:"Enforce naming conventions: camelCase for variables/properties/params/arguments, PascalCase for components, useXxx for hooks"},fixable:"code",schema:[],type:"suggestion"}};var Jn={meta:{name:"eslint-plugin-code-style",version:"3.0.
|
|
284
|
+
`+a),message:"Closing brace must be on its own line",node:x}):e.report({fix:E=>E.insertTextAfter(c,","),message:"Last interface property must have trailing comma",node:c})}}}},meta:{docs:{description:"Enforce interface naming (PascalCase + Interface suffix), camelCase properties, proper formatting, and trailing commas"},fixable:"code",schema:[],type:"suggestion"}},Zt={create(e){let L=(e.filename||e.getFilename()).replace(/\\/g,"/"),A=r=>new RegExp(`/${r}/[^/]+\\.(ts|tsx)$`).test(L),h=()=>/\.(ts|tsx)$/.test(L);return{TSInterfaceDeclaration(r){h()&&(A("interfaces")||e.report({message:'Interfaces must be declared in files inside the "interfaces" folder',node:r.id||r}))},TSEnumDeclaration(r){h()&&(A("enums")||e.report({message:'Enums must be declared in files inside the "enums" folder',node:r.id||r}))},TSTypeAliasDeclaration(r){h()&&(A("types")||e.report({message:'Type aliases must be declared in files inside the "types" folder',node:r.id||r}))}}},meta:{docs:{description:"Enforce that interfaces are in interfaces folder, enums in enums folder, and types in types folder"},schema:[],type:"suggestion"}};var Kt={create(e){let n=e.sourceCode||e.getSourceCode(),L=/^[a-z][a-zA-Z0-9]*$/,A=/^[A-Z][a-zA-Z0-9]*$/,h=/^use[A-Z][a-zA-Z0-9]*$/,r=/^[A-Z][A-Z0-9_]*$/,u=d=>/^[A-Z][A-Z0-9_]*$/.test(d)?d.toLowerCase().replace(/_([a-z0-9])/g,(E,w)=>w.toUpperCase()):/_/.test(d)?d.toLowerCase().replace(/_([a-z0-9])/g,(E,w)=>w.toUpperCase()):/^[A-Z]/.test(d)?d[0].toLowerCase()+d.slice(1):d,i=d=>{let w=(n.getScope?n.getScope(d):e.getScope()).variables.find(S=>S.name===d.name);return w?w.references.map(S=>S.identifier):[]},s=["ArrowFunctionExpression","CallExpression","FunctionDeclaration","FunctionExpression","Property","VariableDeclarator","JSXElement","JSXOpeningElement","ReturnStatement","SwitchCase","SwitchStatement","ObjectExpression","ObjectPattern","BlockStatement","IfStatement","Identifier","RestElement","AssignmentPattern","ArrayPattern","MemberExpression","JSXText","JSXAttribute","JSXExpressionContainer","Function","Object","Array","String","Number","Boolean","Symbol","BigInt","Date","RegExp","Error","Map","Set","WeakMap","WeakSet","Promise"],l=d=>{if(!d||d.type!=="CallExpression")return!1;let{callee:E}=d;if(E.type==="CallExpression"){let w=E.callee;if(w.type==="Identifier"&&w.name==="styled"||w.type==="MemberExpression"&&w.object.name==="styled")return!0}return!1},a=d=>{if(d.type!=="CallExpression")return!1;let{callee:E}=d;return E.type==="Identifier"&&E.name==="styled"},t=d=>{if(!d)return!1;if(d.type==="ArrowFunctionExpression"||d.type==="FunctionExpression")return!0;if(d.type==="CallExpression"&&d.callee){let E=d.callee.name||d.callee.property&&d.callee.property.name;return["memo","forwardRef","lazy","createContext"].includes(E)}return!1},x=d=>{if(!d.init)return!1;let E=d.id.name;if(/^[A-Z]/.test(E)&&t(d.init)||/^[A-Z]/.test(E)&&d.init.type==="MemberExpression"&&d.init.object.type==="Identifier"&&/^[A-Z]/.test(d.init.object.name))return!0;if(/^[A-Z]/.test(E)&&d.init.type==="ConditionalExpression"){let{consequent:w,alternate:S}=d.init,k=I=>I.type==="Identifier"&&/^[A-Z]/.test(I.name)||I.type==="Literal"&&typeof I.value=="string"||I.type==="MemberExpression"&&I.object.type==="Identifier"&&/^[A-Z]/.test(I.object.name);if(k(w)||k(S))return!0}return!1},p=d=>{if(!d.init)return!1;let E=d.id.name;return E.startsWith("use")&&/^use[A-Z]/.test(E)&&t(d.init)},c=["Icon","Component","FormComponent","Layout","Wrapper","Container","Provider"],o=(d,E)=>{if(d.type==="Identifier"){let w=d.name;if(w.startsWith("_")||r.test(w)||s.includes(w)||c.includes(w))return;L.test(w)||e.report({message:`${E} "${w}" should be camelCase`,node:d})}else d.type==="ObjectPattern"?d.properties.forEach(w=>{w.type==="Property"?o(w.value,E):w.type==="RestElement"&&o(w.argument,E)}):d.type==="ArrayPattern"?d.elements.forEach(w=>{w&&o(w,E)}):d.type==="AssignmentPattern"?o(d.left,E):d.type==="RestElement"&&o(d.argument,E)},f=d=>{if(d.id.type!=="Identifier"){o(d.id,"Variable");return}let E=d.id.name;if(l(d.init)){A.test(E)||e.report({message:`Styled component "${E}" should be PascalCase (e.g., StyledCard instead of styledCard)`,node:d.id});return}if(E.startsWith("_")||x(d))return;let w=["Component","Icon","Layout","Wrapper","Container","Provider","View","Screen","Page"];if(A.test(E)&&w.some(k=>E.endsWith(k)))return;if(p(d)){h.test(E)||e.report({message:`Hook "${E}" should start with "use" followed by PascalCase (e.g., useEventsList)`,node:d.id});return}if(!([/^[A-Z][a-zA-Z]*Data$/,/^[A-Z][a-zA-Z]*Config$/,/^Routes$/].some(k=>k.test(E))&&d.init&&(d.init.type==="ArrayExpression"||d.init.type==="ObjectExpression"||d.init.type==="CallExpression"))&&!L.test(E)){let k=u(E),I=i(d.id);e.report({fix:$=>{let g=[];return I.forEach(m=>{g.push($.replaceText(m,k))}),g},message:`Variable "${E}" should be camelCase (e.g., ${k} instead of ${E})`,node:d.id})}},T=d=>{if(d.computed||d.key.type!=="Identifier")return;let E=d.key.name;if(!(E.startsWith("_")||s.includes(E))){if(d.value&&d.value.type==="Identifier"){let w=d.value.name;if(A.test(w)&&A.test(E))return}if(!c.includes(E)&&!E.startsWith("Mui")&&!L.test(E)){let w=u(E);e.report({fix:S=>S.replaceText(d.key,w),message:`Property "${E}" should be camelCase (e.g., ${w} instead of ${E})`,node:d.key})}}},y=d=>{d.params.forEach(E=>o(E,"Parameter"))};return{ArrowFunctionExpression:y,CallExpression:d=>{a(d)||d.arguments.forEach(E=>{if(E.type==="Identifier"){let w=E.name;if(w.startsWith("_")||r.test(w)||s.includes(w)||c.includes(w)||A.test(w))return;if(!L.test(w)){let S=u(w);e.report({fix(k){let I=n.getScope?n.getScope(E):e.getScope(),$=I.variables.find(v=>v.name===w)||I.upper&&I.upper.variables.find(v=>v.name===w);if(!$)return k.replaceText(E,S);let g=[],m=new Set;return $.references.forEach(v=>{let C=`${v.identifier.range[0]}-${v.identifier.range[1]}`;m.has(C)||(m.add(C),g.push(k.replaceText(v.identifier,S)))}),g},message:`Argument "${w}" should be camelCase (e.g., ${S} instead of ${w})`,node:E})}}})},FunctionDeclaration:y,FunctionExpression:y,Property:T,VariableDeclarator:f}},meta:{docs:{description:"Enforce naming conventions: camelCase for variables/properties/params/arguments, PascalCase for components, useXxx for hooks"},fixable:"code",schema:[],type:"suggestion"}};var Jn={meta:{name:"eslint-plugin-code-style",version:"3.0.2"},rules:{"array-callback-destructure":ve,"array-items-per-line":we,"array-objects-on-new-lines":Ce,"arrow-function-block-body":Ae,"arrow-function-simple-jsx":$e,"arrow-function-simplify":Ie,"curried-arrow-same-line":Le,"function-arguments-format":Pe,"nested-call-closing-brackets":Re,"no-empty-lines-in-function-calls":Fe,"opening-brackets-same-line":Be,"simple-call-single-line":He,"single-argument-on-one-line":Oe,"comment-format":Ne,"component-props-destructure":De,"component-props-inline-type":Je,"folder-based-naming-convention":ze,"folder-structure-consistency":We,"no-redundant-folder-suffix":Ue,"svg-icon-naming-convention":Xe,"react-code-order":Mt,"block-statement-newlines":Ve,"empty-line-after-block":Ye,"if-else-spacing":qe,"if-statement-format":_e,"logical-expression-multiline":Ge,"multiline-if-conditions":Ze,"no-empty-lines-in-switch-cases":Qe,"ternary-condition-multiline":Ke,"class-method-definition-format":Me,"class-naming-convention":je,"function-call-spacing":et,"function-declaration-style":tt,"function-naming-convention":nt,"function-object-destructure":it,"function-params-per-line":rt,"no-empty-lines-in-function-params":st,"hook-callback-format":at,"hook-deps-per-line":ot,"hook-file-naming-convention":ct,"hook-function-naming-convention":pt,"use-state-naming-convention":lt,"absolute-imports-only":ft,"export-format":ut,"import-format":gt,"import-source-spacing":dt,"index-export-style":yt,"index-exports-only":ht,"inline-export-declaration":xt,"module-index-exports":mt,"classname-dynamic-at-end":Ct,"classname-multiline":It,"classname-no-extra-spaces":At,"classname-order":$t,"jsx-children-on-new-line":Tt,"jsx-closing-bracket-spacing":bt,"jsx-element-child-new-line":kt,"jsx-logical-expression-simplify":Et,"jsx-parentheses-position":St,"jsx-prop-naming-convention":wt,"jsx-simple-element-one-line":vt,"jsx-string-value-trim":Lt,"jsx-ternary-format":Pt,"no-empty-lines-in-jsx":Rt,"no-empty-lines-in-objects":Ft,"object-property-per-line":Bt,"object-property-value-brace":Ht,"object-property-value-format":Ot,"string-property-spacing":jt,"assignment-value-same-line":Nt,"member-expression-bracket-spacing":Dt,"enum-format":_t,"enum-type-enforcement":Xt,"interface-format":qt,"no-inline-type-definitions":Wt,"prop-naming-convention":zt,"type-annotation-spacing":Vt,"type-format":Ut,"typescript-definition-location":Zt,"no-hardcoded-strings":Jt,"variable-naming-convention":Kt}};export{Jn as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-code-style",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "A custom ESLint plugin for enforcing consistent code formatting and style rules in React/JSX projects",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"bugs": {
|
|
42
42
|
"url": "https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/issues"
|
|
43
43
|
},
|
|
44
|
-
"homepage": "https://eslint-plugin-code-style.
|
|
44
|
+
"homepage": "https://www.eslint-plugin-code-style.org",
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"eslint": ">=9.0.0"
|
|
47
47
|
},
|