eslint-plugin-code-style 2.0.14 → 2.0.16

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 (2) hide show
  1. package/dist/index.js +20 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -20,14 +20,17 @@ ${n} }`)},message:"Destructured properties in array callback should each be o
20
20
  `+m),message:"With multiple arguments, first argument should be on its own line: fn(\\n arg1,\\n arg2,\\n)",node:u});for(let E=0;E<n.length-1;E+=1){let A=n[E],S=n[E+1];if(A.loc.end.line===S.loc.start.line){let k=t.getTokenAfter(A,$=>$.value===",");k&&e.report({fix:$=>$.replaceTextRange([k.range[1],S.range[0]],`
21
21
  `+m),message:"Each argument should be on its own line",node:S})}}if(a.loc.start.line===b.loc.end.line){let E=t.getTokenBefore(a),A=E&&E.value===",";e.report({fix:S=>A?S.replaceTextRange([E.range[1],a.range[0]],`
22
22
  `+T):S.replaceTextRange([b.range[1],a.range[0]],`,
23
- `+T),message:"Closing parenthesis should be on its own line",node:a})}}}},meta:{docs:{description:"Enforce function arguments formatting: each argument on its own line when >= minArgs (default: 2) or any argument is multiline"},fixable:"code",schema:[{additionalProperties:!1,properties:{minArgs:{default:2,description:"Minimum arguments to enforce multiline formatting (default: 2)",minimum:1,type:"integer"},skipHooks:{default:!0,description:"Skip React hooks (default: true)",type:"boolean"},skipSingleArg:{default:!0,description:"Skip single argument patterns like objects, arrays, callbacks (default: true)",type:"boolean"}},type:"object"}],type:"layout"}},Ie={create(e){let t=e.sourceCode||e.getSourceCode(),I=(y,s)=>{let g=t.getLastToken(s),i=t.getTokenAfter(s);if(!i||i.value!==")")return;let r=t.getTokenAfter(i);r&&r.value===","&&(r=t.getTokenAfter(r));let l=r;if(!l||l.value!==")")return;if(g.loc.end.line!==i.loc.start.line){e.report({fix:n=>n.replaceTextRange([g.range[1],i.range[0]],""),message:"Closing brace and parenthesis should be on the same line: })",node:i});return}if(i.loc.end.line!==l.loc.start.line){e.report({fix:n=>n.replaceTextRange([i.range[1],l.range[0]],""),message:"Closing parentheses should be on the same line: ))",node:l});return}let o=t.getTokenAfter(l);o&&o.value==="||"&&l.loc.end.line!==o.loc.start.line&&e.report({fix:n=>n.replaceTextRange([l.range[1],o.range[0]]," "),message:"Logical operator || should be on the same line as closing ))",node:o})},C=y=>{let{arguments:s}=y;if(s.length!==1)return;let g=s[0],i=null;if(g.type==="ObjectExpression"||g.type==="ArrayExpression")i=t.getLastToken(g);else if(g.type==="ArrowFunctionExpression"){let n=g.body;n.type==="TSAsExpression"&&n.typeAnnotation&&n.typeAnnotation.type==="TSTypeLiteral"?i=t.getLastToken(n.typeAnnotation):(n.type==="ObjectExpression"||n.type==="ArrayExpression")&&(i=t.getLastToken(n))}if(!i||i.value!=="}"&&i.value!=="]")return;let r=t.getLastToken(y);if(!r||r.value!==")")return;let l=t.getTokenAfter(i),o=i;l&&l.value===","&&(o=l),o.loc.end.line!==r.loc.start.line&&e.report({fix:n=>n.replaceTextRange([o.range[1],r.range[0]],""),message:"Closing parenthesis should be on same line as closing brace: });",node:r})};return{CallExpression(y){let{callee:s,arguments:g}=y;if(C(y),g.length!==1)return;let i=g[0];if(!(i.type!=="ArrowFunctionExpression"||i.body.type!=="ObjectExpression")){if(s.type==="CallExpression"){I(y,i.body);return}s.type==="MemberExpression"&&I(y,i.body)}}}},meta:{docs:{description:"Enforce nested function call closing brackets on same line: }));"},fixable:"code",schema:[],type:"layout"}},Re={create(e){let t=e.sourceCode||e.getSourceCode(),I=i=>["Literal","Identifier","MemberExpression","TemplateLiteral"].includes(i.type),C=i=>i.loc.start.line===i.loc.end.line,y=i=>i.type==="ObjectExpression"&&i.properties.length===1,s=i=>{let r=i.properties[0];if(r.type==="SpreadElement")return t.getText(i);let l=t.getText(r.key),o=t.getText(r.value);return`{ ${l}: ${o} }`};return{CallExpression:i=>{let r=i.arguments;if(r.length===0)return;let l=t.getTokenAfter(i.callee,f=>f.value==="("),o=t.getLastToken(i);if(!l||!o||o.value!==")")return;let n=r[0],h=r[r.length-1];if(r.length===1&&(I(n)||y(n))&&C(n)&&n.loc.start.line!==l.loc.end.line){let f=y(n)?s(n):t.getText(n);e.report({fix:c=>c.replaceTextRange([l.range[1],o.range[0]],f),message:"Single simple argument should be on the same line as function call",node:n});return}n.loc.start.line-l.loc.end.line>1&&e.report({fix:f=>f.replaceTextRange([l.range[1],n.range[0]],`
23
+ `+T),message:"Closing parenthesis should be on its own line",node:a})}}}},meta:{docs:{description:"Enforce function arguments formatting: each argument on its own line when >= minArgs (default: 2) or any argument is multiline"},fixable:"code",schema:[{additionalProperties:!1,properties:{minArgs:{default:2,description:"Minimum arguments to enforce multiline formatting (default: 2)",minimum:1,type:"integer"},skipHooks:{default:!0,description:"Skip React hooks (default: true)",type:"boolean"},skipSingleArg:{default:!0,description:"Skip single argument patterns like objects, arrays, callbacks (default: true)",type:"boolean"}},type:"object"}],type:"layout"}},Ie={create(e){let t=e.sourceCode||e.getSourceCode(),I=(y,s)=>{let g=t.getLastToken(s),i=t.getTokenAfter(s);if(!i||i.value!==")")return;let r=t.getTokenAfter(i);r&&r.value===","&&(r=t.getTokenAfter(r));let l=r;if(!l||l.value!==")")return;if(g.loc.end.line!==i.loc.start.line){e.report({fix:n=>n.replaceTextRange([g.range[1],i.range[0]],""),message:"Closing brace and parenthesis should be on the same line: })",node:i});return}if(i.loc.end.line!==l.loc.start.line){e.report({fix:n=>n.replaceTextRange([i.range[1],l.range[0]],""),message:"Closing parentheses should be on the same line: ))",node:l});return}let o=t.getTokenAfter(l);o&&o.value==="||"&&l.loc.end.line!==o.loc.start.line&&e.report({fix:n=>n.replaceTextRange([l.range[1],o.range[0]]," "),message:"Logical operator || should be on the same line as closing ))",node:o})},C=y=>{let{arguments:s}=y;if(s.length!==1)return;let g=s[0],i=null;if(g.type==="ObjectExpression"||g.type==="ArrayExpression")i=t.getLastToken(g);else if(g.type==="ArrowFunctionExpression"){let n=g.body;if(n.type==="TSAsExpression"&&n.typeAnnotation&&n.typeAnnotation.type==="TSTypeLiteral")i=t.getLastToken(n.typeAnnotation);else if(n.type==="ObjectExpression"||n.type==="ArrayExpression")i=t.getLastToken(n);else{let h=t.getLastToken(g),f=t.getLastToken(y);if(!f||f.value!==")")return;let c=t.getTokenAfter(h);(c&&c.value===","?c:h).loc.end.line!==f.loc.start.line&&e.report({fix:b=>b.replaceTextRange([h.range[1],f.range[0]],""),message:"Closing parenthesis should be on same line as arrow function body",node:f});return}}if(!i||i.value!=="}"&&i.value!=="]")return;let r=t.getLastToken(y);if(!r||r.value!==")")return;let l=t.getTokenAfter(i),o=i;l&&l.value===","&&(o=l),o.loc.end.line!==r.loc.start.line&&e.report({fix:n=>n.replaceTextRange([o.range[1],r.range[0]],""),message:"Closing parenthesis should be on same line as closing brace: });",node:r})};return{CallExpression(y){let{callee:s,arguments:g}=y;if(C(y),g.length!==1)return;let i=g[0];if(!(i.type!=="ArrowFunctionExpression"||i.body.type!=="ObjectExpression")){if(s.type==="CallExpression"){I(y,i.body);return}s.type==="MemberExpression"&&I(y,i.body)}}}},meta:{docs:{description:"Enforce nested function call closing brackets on same line: }));"},fixable:"code",schema:[],type:"layout"}},Re={create(e){let t=e.sourceCode||e.getSourceCode(),I=i=>["Literal","Identifier","MemberExpression","TemplateLiteral"].includes(i.type),C=i=>i.loc.start.line===i.loc.end.line,y=i=>i.type==="ObjectExpression"&&i.properties.length===1,s=i=>{let r=i.properties[0];if(r.type==="SpreadElement")return t.getText(i);let l=t.getText(r.key),o=t.getText(r.value);return`{ ${l}: ${o} }`};return{CallExpression:i=>{let r=i.arguments;if(r.length===0)return;let l=t.getTokenAfter(i.callee,f=>f.value==="("),o=t.getLastToken(i);if(!l||!o||o.value!==")")return;let n=r[0],h=r[r.length-1];if(r.length===1&&(I(n)||y(n))&&C(n)&&n.loc.start.line!==l.loc.end.line){let f=y(n)?s(n):t.getText(n);e.report({fix:c=>c.replaceTextRange([l.range[1],o.range[0]],f),message:"Single simple argument should be on the same line as function call",node:n});return}n.loc.start.line-l.loc.end.line>1&&e.report({fix:f=>f.replaceTextRange([l.range[1],n.range[0]],`
24
24
  `+" ".repeat(n.loc.start.column)),message:"No empty line after opening parenthesis in function call",node:n}),o.loc.start.line-h.loc.end.line>1&&e.report({fix:f=>f.replaceTextRange([h.range[1],o.range[0]],`
25
25
  `+" ".repeat(o.loc.start.column)),message:"No empty line before closing parenthesis in function call",node:h});for(let f=0;f<r.length-1;f+=1){let c=r[f],a=r[f+1];if(a.loc.start.line-c.loc.end.line>1){let u=t.getTokenAfter(c,b=>b.value===",");e.report({fix:b=>b.replaceTextRange([u.range[1],a.range[0]],`
26
26
  `+" ".repeat(a.loc.start.column)),message:"No empty line between function arguments",node:a})}}}}},meta:{docs:{description:"Disallow empty lines in function calls and enforce single simple argument on same line"},fixable:"whitespace",schema:[],type:"layout"}},Pe={create(e){let t=e.sourceCode||e.getSourceCode();return{ArrowFunctionExpression:i=>{if(i.body.type==="BlockStatement"){let a=t.getTokenBefore(i.body,b=>b.value==="=>"),u=t.getFirstToken(i.body);a&&u&&a.loc.end.line!==u.loc.start.line&&e.report({fix:b=>b.replaceTextRange([a.range[1],u.range[0]]," "),message:"Opening brace should be on the same line as arrow",node:u})}if(i.body.type==="CallExpression"){let a=t.getTokenBefore(i.body,u=>u.value==="=>");if(a){let u=t.getTokenAfter(a);if(u&&u.value==="("){a.loc.end.line!==u.loc.start.line&&e.report({fix:x=>x.replaceTextRange([a.range[1],u.range[1]]," ("),message:"Opening parenthesis should be on the same line as arrow: => (",node:u});return}t.text.slice(a.range[1],i.body.range[0])!==" "&&e.report({fix:x=>x.replaceTextRange([a.range[1],i.body.range[0]]," "),message:"Expression body should be on the same line as arrow with single space",node:i.body})}}if(i.body.type==="ObjectExpression"){let a=t.getTokenBefore(i.body,u=>u.value==="=>");if(a){let u=t.getTokenAfter(a);if(u&&u.value==="("){if(a.loc.end.line!==u.loc.start.line){e.report({fix:x=>x.replaceTextRange([a.range[1],u.range[1]]," ("),message:"Parenthesized object should be on the same line as arrow: => (",node:u});return}let b=t.getFirstToken(i.body);u.loc.end.line!==b.loc.start.line&&e.report({fix:x=>x.replaceTextRange([u.range[1],b.range[1]],"{"),message:"Opening brace should be on the same line as opening paren: ({",node:b})}}}if(i.body.type==="TSAsExpression"||i.body.type==="Identifier"||i.body.type==="MemberExpression"){let a=t.getTokenBefore(i.body,u=>u.value==="=>");if(a){let u=t.getTokenAfter(a);u&&u.value!=="("&&t.text.slice(a.range[1],i.body.range[0])!==" "&&e.report({fix:x=>x.replaceTextRange([a.range[1],i.body.range[0]]," "),message:"Expression body should be on the same line as arrow with single space",node:i.body})}}let r=t.getFirstToken(i,a=>a.value==="=>");if(r){let a=t.getTokenBefore(r);a&&t.text.slice(a.range[1],r.range[0])!==" "&&e.report({fix:b=>b.replaceTextRange([a.range[1],r.range[0]]," "),message:"Arrow function should have space before =>",node:r})}let l=i.params;if(l.length!==1)return;let o=l[0];if(o.type!=="ObjectPattern"||o.properties.length<2)return;let n=t.getTokenBefore(o);if(!n||n.value!=="(")return;let h=t.getFirstToken(o);n.loc.end.line!==h.loc.start.line&&e.report({fix:a=>a.replaceTextRange([n.range[1],h.range[1]],"{"),message:"Opening parenthesis and brace should be on the same line for destructured param",node:h});let f=t.getLastToken(o),c=t.getTokenAfter(o);c&&c.value===","&&(c=t.getTokenAfter(c)),c&&c.value===")"&&f.loc.end.line!==c.loc.start.line&&e.report({fix:a=>a.replaceTextRange([f.range[1],c.range[0]],""),message:"Closing brace and parenthesis should be on the same line for destructured param",node:c})},CallExpression:i=>{let{callee:r}=i,l=t.getLastToken(r),o=i.typeArguments||i.typeParameters,n;if(o?n=t.getTokenAfter(o):n=t.getTokenAfter(r),!n||n.value!=="("){let a=t.getTokenAfter(r);for(;a&&a.range[0]<i.range[1];){if(a.value==="("){n=a;break}a=t.getTokenAfter(a)}}if(!n||n.value!=="(")return;if(l.loc.end.line!==n.loc.start.line){if(o&&o.loc.start.line!==o.loc.end.line)return;let a="";o&&(a=t.getText(o)),a+="(",e.report({fix:u=>u.replaceTextRange([l.range[1],n.range[1]],a),message:"Opening parenthesis should be on the same line as function name",node:n});return}let h=i.arguments;if(h.length===0)return;let f=h[0],c=t.getTokenBefore(f);if(f.type==="ObjectExpression"&&f.properties.length>=1){let a=i.loc.start.line!==i.loc.end.line,u=h.length>1;if(a&&u)return;let b=t.getFirstToken(f);c.loc.end.line!==b.loc.start.line&&e.report({fix:m=>m.replaceTextRange([c.range[1],b.range[1]],"{"),message:"Opening parenthesis and brace should be on the same line",node:b});let x=t.getLastToken(f),T=t.getTokenAfter(f);T&&T.value===","&&(T=t.getTokenAfter(T)),T&&T.value===")"&&x.loc.end.line!==T.loc.start.line&&e.report({fix:m=>m.replaceTextRange([x.range[1],T.range[0]],""),message:"Closing brace and parenthesis should be on the same line",node:T});return}if(f.type==="ArrayExpression"&&h.length===1){let a=f.loc.start.line!==f.loc.end.line,u=t.getFirstToken(f);if(c.loc.end.line!==u.loc.start.line){e.report({fix:T=>T.replaceTextRange([c.range[1],u.range[0]],""),message:"Opening parenthesis and bracket should be on the same line: fn([",node:u});return}if(!a&&f.elements.length>0&&f.elements[0]&&f.elements[0].type==="ObjectExpression"){let T=f.elements[0],m=t.getFirstToken(T);u.loc.end.line!==m.loc.start.line&&e.report({fix:E=>E.replaceTextRange([u.range[1],m.range[1]],"{"),message:"Opening bracket and brace should be on the same line",node:m})}let b=t.getLastToken(f),x=t.getTokenAfter(f);x&&x.value===","&&(x=t.getTokenAfter(x)),x&&x.value===")"&&b.loc.end.line!==x.loc.start.line&&e.report({fix:T=>T.replaceTextRange([b.range[1],x.range[0]],""),message:"Closing bracket and parenthesis should be on the same line: ])",node:x});return}if(f.type==="CallExpression"&&h.length>1){if(c.loc.end.line===f.loc.start.line){let a=" ".repeat(c.loc.start.column+4);e.report({fix:u=>u.replaceTextRange([c.range[1],f.range[0]],`
27
- `+a),message:"Function call argument should start on a new line when there are multiple arguments",node:f})}return}if(f.type==="ArrowFunctionExpression"){if(h.length>1)return;let a=f.params;if(a.length===0)return;let u=a[0],b=a[a.length-1];if(a.length===1&&u.type==="ObjectPattern"){let x=t.getTokenBefore(u);if(!x||x.value!=="(")return;if(c.loc.end.line!==x.loc.start.line){e.report({fix:m=>m.replaceTextRange([c.range[1],x.range[1]],"("),message:"Callback opening parenthesis should be on the same line as function call",node:x});return}let T=t.getFirstToken(u);x.loc.end.line!==T.loc.start.line&&e.report({fix:m=>m.replaceTextRange([x.range[1],T.range[1]],"{"),message:"Opening parenthesis and brace should be on the same line for callback destructured param",node:T});return}if(a.length===1&&u.type==="Identifier"){let x=t.getTokenBefore(u);if(!x||x.value!=="(")return;if(c.loc.end.line!==x.loc.start.line){e.report({fix:T=>T.replaceTextRange([c.range[1],x.range[1]],"("),message:"Callback opening parenthesis should be on the same line as function call",node:x});return}x.loc.end.line!==u.loc.start.line&&e.report({fix:T=>T.replaceTextRange([x.range[1],u.range[0]],""),message:"Single callback param should be on the same line as opening parenthesis",node:u});return}if(a.length>=2){let x=t.getTokenBefore(u);if(!x||x.value!=="(")return;let T=x.loc.end.line!==u.loc.start.line,m=f.body,E=m&&m.loc.start.line!==m.loc.end.line;if(T||E)return;c.loc.end.line!==x.loc.start.line&&e.report({fix:A=>A.replaceTextRange([c.range[1],x.range[1]],"("),message:"Opening parentheses should be on the same line for callback params",node:x})}}},JSXExpressionContainer:i=>{let r=i.expression;if(r.type==="JSXEmptyExpression")return;let l=t.getFirstToken(i),o=t.getLastToken(i);if(r.type==="ObjectExpression"&&r.properties.length>=1){let f=t.getFirstToken(r);l.loc.end.line!==f.loc.start.line&&e.report({fix:a=>a.replaceTextRange([l.range[1],f.range[1]],"{"),message:"Opening braces should be on the same line for JSX object expression",node:f});let c=t.getLastToken(r);o.loc.start.line!==c.loc.end.line&&e.report({fix:a=>a.replaceTextRange([c.range[1],o.range[0]],""),message:"Closing braces should be on the same line for JSX object expression",node:o});return}if(r.type==="CallExpression"){l.loc.end.line!==r.loc.start.line&&e.report({fix:c=>c.replaceTextRange([l.range[1],r.range[0]],""),message:"Opening brace and expression should be on the same line",node:r}),r.loc.start.line===r.loc.end.line&&r.loc.end.line!==o.loc.start.line&&e.report({fix:c=>c.replaceTextRange([r.range[1],o.range[0]],""),message:"Closing brace should be on the same line as simple call expression",node:o});return}if(r.type==="TemplateLiteral"){if(r.expressions.every(c=>c.type==="Identifier"||c.type==="MemberExpression")){let c=r.quasis,a=r.expressions,u="`",b=[];for(let S=0;S<c.length;S+=1){let k=c[S].value.raw.replace(/\s*\n\s*/g," ").trim();k&&b.push(k),S<a.length&&b.push("${"+t.getText(a[S])+"}")}u="`"+b.join(" ")+"`";let x=i.parent;if(x&&x.type==="JSXAttribute"&&x.name&&x.name.name==="className"){let S=u.slice(1,-1),k=S.replace(/\$\{[^}]+\}/g,"").trim(),$=k.split(/\s+/).filter(Boolean),v=a.length,p=be,d=ke;if($.length+v>p||S.length>d)return;if(a.length===0){let L=`"${k}"`,R=r.loc.start.line!==r.loc.end.line,P=l.loc.end.line!==r.loc.start.line;(R||P)&&e.report({fix:H=>H.replaceTextRange([l.range[0],o.range[1]],L),message:"Short className should use a string literal on a single line",node:r});return}}let m=r.loc.start.line!==r.loc.end.line,E=l.loc.end.line!==r.loc.start.line,A=r.loc.end.line!==o.loc.start.line;(m||E||A)&&u.length<=80&&e.report({fix:S=>S.replaceTextRange([l.range[1],o.range[0]],u),message:"Simple template literal should be on a single line",node:r})}return}let n=["Identifier","MemberExpression","Literal"],h=["ConditionalExpression","BinaryExpression","LogicalExpression","UnaryExpression"].includes(r.type)&&r.loc.start.line===r.loc.end.line;if(n.includes(r.type)||h){if(l.loc.end.line!==o.loc.start.line){let a=t.getText(r);e.report({fix:u=>u.replaceTextRange([l.range[1],o.range[0]],a),message:"Simple expression should be on single line in JSX attribute",node:r});return}let c=i.parent;if(c&&c.type==="JSXElement"){let a=c.children.filter(u=>!(u.type==="JSXText"&&/^\s*$/.test(u.value)));if(a.length===1&&a[0]===i){let u=c.openingElement,b=c.closingElement;if(b){let x=u.loc.end.line,T=b.loc.start.line;if(x!==T){let m=t.getText(u),E=t.getText(b),A=t.getText(i);m.length+A.length+E.length<=120&&e.report({fix:k=>k.replaceTextRange([u.range[1],b.range[0]],A),message:"JSX element with simple expression should be on single line",node:c})}}}}return}if(r.type==="ArrowFunctionExpression"){if(l.loc.end.line!==r.loc.start.line){e.report({fix:f=>f.replaceTextRange([l.range[1],r.range[0]],""),message:"Opening brace and arrow function should be on the same line in JSX attribute",node:r});return}if(r.body.type==="BlockStatement"){if(i.parent&&i.parent.type==="JSXAttribute"){let f=t.getLastToken(r.body);f&&o.loc.start.line!==f.loc.end.line&&e.report({fix:c=>c.replaceTextRange([f.range[1],o.range[0]],""),message:"Closing braces should be together for arrow function in JSX attribute",node:o})}return}if(i.parent&&i.parent.type==="JSXAttribute"){let f=r.loc.start.line===r.loc.end.line,c=l.loc.end.line!==r.loc.start.line,a=r.loc.end.line!==o.loc.start.line;if((c||a)&&f){let x=t.getText(r);e.report({fix:T=>T.replaceTextRange([l.range[1],o.range[0]],x),message:"Simple arrow function should be on single line in JSX attribute",node:r});return}if(r.body.loc.start.line===r.body.loc.end.line){let x=t.getTokenBefore(r.body,T=>T.value==="=>");if(x&&x.loc.end.line!==r.body.loc.start.line){let T=t.getText(r.body);e.report({fix:m=>m.replaceTextRange([x.range[1],o.range[0]]," "+T),message:"Simple arrow function expression should be on single line",node:r.body})}}}return}if(r.type==="JSXElement"||r.type==="JSXFragment"){let f=t.getTokenBefore(r);if(f&&f.value==="("){l.loc.end.line!==f.loc.start.line&&e.report({fix:a=>a.replaceTextRange([l.range[1],f.range[1]],"("),message:"Opening brace and parenthesis should be together for JSX expression",node:f});let c=t.getTokenAfter(r);c&&c.value===")"&&o.loc.start.line!==c.loc.end.line&&e.report({fix:a=>a.replaceTextRange([c.range[1],o.range[0]],""),message:"Closing parenthesis and brace should be together for JSX expression",node:o})}return}if(r.type==="LogicalExpression"){let f=T=>T.type==="LogicalExpression"?f(T.left)+f(T.right):1,c=f(r),a=t.getText(r),u=r.loc.start.line!==r.loc.end.line;if(c<=2&&a.length<=80){let T=a.replace(/\s*\n\s*/g," ");if(u||l.loc.end.line!==r.loc.start.line||r.loc.end.line!==o.loc.start.line){e.report({fix:E=>E.replaceTextRange([l.range[1],o.range[0]],T),message:"Simple logical expression should be on a single line",node:r});return}let m=i.parent;if(m&&m.type==="JSXElement"){let E=m.children.filter(A=>!(A.type==="JSXText"&&/^\s*$/.test(A.value)));if(E.length===1&&E[0]===i){let A=m.openingElement,S=m.closingElement;if(S){let k=A.loc.end.line,$=S.loc.start.line;if(k!==$){let v=t.getText(A),p=t.getText(S),d="{"+T+"}";v.length+d.length+p.length<=120&&e.report({fix:L=>L.replaceTextRange([A.range[1],S.range[0]],d),message:"JSX element with simple logical expression should be on single line",node:m})}}}}return}if(c>=3&&u){if(l.loc.end.line!==r.loc.start.line){e.report({fix:T=>T.replaceTextRange([l.range[1],r.range[0]],""),message:"Opening brace and logical expression should be on the same line",node:r});return}if(r.loc.end.line===o.loc.start.line){let m=t.lines[l.loc.start.line-1].match(/^\s*/)[0];e.report({fix:E=>E.replaceTextRange([r.range[1],o.range[0]],`
27
+ `+a),message:"Function call argument should start on a new line when there are multiple arguments",node:f})}return}if(f.type==="ArrowFunctionExpression"){if(h.length>1)return;let a=f.params;if(a.length===0){c.loc.end.line!==f.loc.start.line&&e.report({fix:x=>x.replaceTextRange([c.range[1],f.range[0]],""),message:"Arrow function should start on the same line as opening parenthesis",node:f});return}let u=a[0],b=a[a.length-1];if(a.length===1&&u.type==="ObjectPattern"){let x=t.getTokenBefore(u);if(!x||x.value!=="(")return;if(c.loc.end.line!==x.loc.start.line){e.report({fix:S=>S.replaceTextRange([c.range[1],x.range[1]],"("),message:"Callback opening parenthesis should be on the same line as function call",node:x});return}let T=t.getFirstToken(u);if(x.loc.end.line!==T.loc.start.line){e.report({fix:S=>S.replaceTextRange([x.range[1],T.range[1]],"{"),message:"Opening parenthesis and brace should be on the same line for callback destructured param",node:T});return}let m=t.getTokenBefore(f.body),E=t.getTokenAfter(m),A=m.value==="=>"&&m.loc.end.line!==E.loc.start.line;if(u.properties.length>=2){let S=t.getLastToken(u);if(T.loc.start.line===S.loc.end.line&&A){let v=t.lines[c.loc.start.line-1].match(/^(\s*)/)[1],p=v+" ",d=u.properties.map(w=>p+t.getText(w)).join(`,
28
+ `);e.report({fix:w=>[w.replaceTextRange([T.range[0],S.range[1]],`{
29
+ `+d+`
30
+ `+v+"}"),w.replaceTextRange([m.range[1],E.range[0]]," ")],message:"Destructured callback params with 2+ properties should each be on their own line",node:u});return}}A&&e.report({fix:S=>S.replaceTextRange([m.range[1],E.range[0]]," "),message:"Arrow function body should start on the same line as =>",node:E});return}if(a.length===1&&u.type==="Identifier"){let x=t.getTokenBefore(u);if(!x||x.value!=="(")return;if(c.loc.end.line!==x.loc.start.line){e.report({fix:T=>T.replaceTextRange([c.range[1],x.range[1]],"("),message:"Callback opening parenthesis should be on the same line as function call",node:x});return}x.loc.end.line!==u.loc.start.line&&e.report({fix:T=>T.replaceTextRange([x.range[1],u.range[0]],""),message:"Single callback param should be on the same line as opening parenthesis",node:u});return}if(a.length>=2){let x=t.getTokenBefore(u);if(!x||x.value!=="(")return;let T=x.loc.end.line!==u.loc.start.line,m=f.body,E=m&&m.loc.start.line!==m.loc.end.line;if(T||E)return;c.loc.end.line!==x.loc.start.line&&e.report({fix:A=>A.replaceTextRange([c.range[1],x.range[1]],"("),message:"Opening parentheses should be on the same line for callback params",node:x})}}},JSXExpressionContainer:i=>{let r=i.expression;if(r.type==="JSXEmptyExpression")return;let l=t.getFirstToken(i),o=t.getLastToken(i);if(r.type==="ObjectExpression"&&r.properties.length>=1){let f=t.getFirstToken(r);l.loc.end.line!==f.loc.start.line&&e.report({fix:a=>a.replaceTextRange([l.range[1],f.range[1]],"{"),message:"Opening braces should be on the same line for JSX object expression",node:f});let c=t.getLastToken(r);o.loc.start.line!==c.loc.end.line&&e.report({fix:a=>a.replaceTextRange([c.range[1],o.range[0]],""),message:"Closing braces should be on the same line for JSX object expression",node:o});return}if(r.type==="CallExpression"){l.loc.end.line!==r.loc.start.line&&e.report({fix:c=>c.replaceTextRange([l.range[1],r.range[0]],""),message:"Opening brace and expression should be on the same line",node:r}),r.loc.start.line===r.loc.end.line&&r.loc.end.line!==o.loc.start.line&&e.report({fix:c=>c.replaceTextRange([r.range[1],o.range[0]],""),message:"Closing brace should be on the same line as simple call expression",node:o});return}if(r.type==="TemplateLiteral"){if(r.expressions.every(c=>c.type==="Identifier"||c.type==="MemberExpression")){let c=r.quasis,a=r.expressions,u="`",b=[];for(let S=0;S<c.length;S+=1){let k=c[S].value.raw.replace(/\s*\n\s*/g," ").trim();k&&b.push(k),S<a.length&&b.push("${"+t.getText(a[S])+"}")}u="`"+b.join(" ")+"`";let x=i.parent;if(x&&x.type==="JSXAttribute"&&x.name&&x.name.name==="className"){let S=u.slice(1,-1),k=S.replace(/\$\{[^}]+\}/g,"").trim(),$=k.split(/\s+/).filter(Boolean),v=a.length,p=be,d=ke;if($.length+v>p||S.length>d)return;if(a.length===0){let L=`"${k}"`,R=r.loc.start.line!==r.loc.end.line,P=l.loc.end.line!==r.loc.start.line;(R||P)&&e.report({fix:H=>H.replaceTextRange([l.range[0],o.range[1]],L),message:"Short className should use a string literal on a single line",node:r});return}}let m=r.loc.start.line!==r.loc.end.line,E=l.loc.end.line!==r.loc.start.line,A=r.loc.end.line!==o.loc.start.line;(m||E||A)&&u.length<=80&&e.report({fix:S=>S.replaceTextRange([l.range[1],o.range[0]],u),message:"Simple template literal should be on a single line",node:r})}return}let n=["Identifier","MemberExpression","Literal"],h=["ConditionalExpression","BinaryExpression","LogicalExpression","UnaryExpression"].includes(r.type)&&r.loc.start.line===r.loc.end.line;if(n.includes(r.type)||h){if(l.loc.end.line!==o.loc.start.line){let a=t.getText(r);e.report({fix:u=>u.replaceTextRange([l.range[1],o.range[0]],a),message:"Simple expression should be on single line in JSX attribute",node:r});return}let c=i.parent;if(c&&c.type==="JSXElement"){let a=c.children.filter(u=>!(u.type==="JSXText"&&/^\s*$/.test(u.value)));if(a.length===1&&a[0]===i){let u=c.openingElement,b=c.closingElement;if(b){let x=u.loc.end.line,T=b.loc.start.line;if(x!==T){let m=t.getText(u),E=t.getText(b),A=t.getText(i);m.length+A.length+E.length<=120&&e.report({fix:k=>k.replaceTextRange([u.range[1],b.range[0]],A),message:"JSX element with simple expression should be on single line",node:c})}}}}return}if(r.type==="ArrowFunctionExpression"){if(l.loc.end.line!==r.loc.start.line){e.report({fix:f=>f.replaceTextRange([l.range[1],r.range[0]],""),message:"Opening brace and arrow function should be on the same line in JSX attribute",node:r});return}if(r.body.type==="BlockStatement"){if(i.parent&&i.parent.type==="JSXAttribute"){let f=t.getLastToken(r.body);f&&o.loc.start.line!==f.loc.end.line&&e.report({fix:c=>c.replaceTextRange([f.range[1],o.range[0]],""),message:"Closing braces should be together for arrow function in JSX attribute",node:o})}return}if(i.parent&&i.parent.type==="JSXAttribute"){let f=r.loc.start.line===r.loc.end.line,c=l.loc.end.line!==r.loc.start.line,a=r.loc.end.line!==o.loc.start.line;if((c||a)&&f){let x=t.getText(r);e.report({fix:T=>T.replaceTextRange([l.range[1],o.range[0]],x),message:"Simple arrow function should be on single line in JSX attribute",node:r});return}if(r.body.loc.start.line===r.body.loc.end.line){let x=t.getTokenBefore(r.body,T=>T.value==="=>");if(x&&x.loc.end.line!==r.body.loc.start.line){let T=t.getText(r.body);e.report({fix:m=>m.replaceTextRange([x.range[1],o.range[0]]," "+T),message:"Simple arrow function expression should be on single line",node:r.body})}}}return}if(r.type==="JSXElement"||r.type==="JSXFragment"){let f=t.getTokenBefore(r);if(f&&f.value==="("){l.loc.end.line!==f.loc.start.line&&e.report({fix:a=>a.replaceTextRange([l.range[1],f.range[1]],"("),message:"Opening brace and parenthesis should be together for JSX expression",node:f});let c=t.getTokenAfter(r);c&&c.value===")"&&o.loc.start.line!==c.loc.end.line&&e.report({fix:a=>a.replaceTextRange([c.range[1],o.range[0]],""),message:"Closing parenthesis and brace should be together for JSX expression",node:o})}return}if(r.type==="LogicalExpression"){let f=T=>T.type==="LogicalExpression"?f(T.left)+f(T.right):1,c=f(r),a=t.getText(r),u=r.loc.start.line!==r.loc.end.line;if(c<=2&&a.length<=80){let T=a.replace(/\s*\n\s*/g," ");if(u||l.loc.end.line!==r.loc.start.line||r.loc.end.line!==o.loc.start.line){e.report({fix:E=>E.replaceTextRange([l.range[1],o.range[0]],T),message:"Simple logical expression should be on a single line",node:r});return}let m=i.parent;if(m&&m.type==="JSXElement"){let E=m.children.filter(A=>!(A.type==="JSXText"&&/^\s*$/.test(A.value)));if(E.length===1&&E[0]===i){let A=m.openingElement,S=m.closingElement;if(S){let k=A.loc.end.line,$=S.loc.start.line;if(k!==$){let v=t.getText(A),p=t.getText(S),d="{"+T+"}";v.length+d.length+p.length<=120&&e.report({fix:L=>L.replaceTextRange([A.range[1],S.range[0]],d),message:"JSX element with simple logical expression should be on single line",node:m})}}}}return}if(c>=3&&u){if(l.loc.end.line!==r.loc.start.line){e.report({fix:T=>T.replaceTextRange([l.range[1],r.range[0]],""),message:"Opening brace and logical expression should be on the same line",node:r});return}if(r.loc.end.line===o.loc.start.line){let m=t.lines[l.loc.start.line-1].match(/^\s*/)[0];e.report({fix:E=>E.replaceTextRange([r.range[1],o.range[0]],`
28
31
  `+m),message:"Closing brace should be on its own line for multiline logical expression",node:o})}return}if(l.loc.end.line!==r.loc.start.line){e.report({fix:T=>T.replaceTextRange([l.range[1],r.range[0]],""),message:"Opening brace and logical expression should be on the same line",node:r});return}let b=T=>{if(T.type!=="LogicalExpression"&&T.type!=="BinaryExpression")return!1;let{left:m,right:E}=T;if(T.loc.start.line!==T.loc.end.line){let A=t.getTokenAfter(m,S=>["&&","||","===","!==","==","!=",">","<",">=","<="].includes(S.value));if(A){let S=t.text.slice(m.range[1],A.range[0]);if(S.includes(`
29
32
  `)&&/\n\s*$/.test(S))return!1;let v=m.loc.end.line,p=A.loc.start.line,d=E.loc.start.line;if(v!==p||p!==d){let w=t.getTokenBefore(T),L=t.getTokenAfter(T),R=w?.value==="("&&L?.value===")",P=t.getText(T).replace(/\s*\n\s*/g," ").trim();return e.report({fix:H=>R?H.replaceTextRange([w.range[0],L.range[1]],`(${P})`):H.replaceText(T,P),message:"Condition operands should be on the same line",node:T}),!0}}}return T.type==="LogicalExpression"?b(m)||b(E):!1};if(r.operator==="&&"&&b(r.left))return;let x=t.getTokenAfter(r.left,T=>T.value==="&&"||T.value==="||");if(x){let T=r.right.type==="JSXElement"||r.right.type==="JSXFragment"||r.right.type==="ConditionalExpression"||r.right.type==="ObjectExpression"||t.getTokenBefore(r.right)?.value==="(",m=t.getTokenAfter(r.left),E=m&&m.value===")",A=E?m.range[1]:r.left.range[1],S=E?m.loc.end.line:r.left.loc.end.line;if(T&&S!==x.loc.start.line){e.report({fix:v=>v.replaceTextRange([A,x.range[1]]," "+x.value),message:"Logical operator should be on the same line as the left operand",node:x});return}let k=t.getTokenAfter(x);k&&k.value==="("&&x.loc.end.line!==k.loc.start.line&&e.report({fix:v=>v.replaceTextRange([x.range[1],k.range[1]]," ("),message:"Opening parenthesis should be on same line as logical operator",node:k});let $=t.getTokenAfter(r.right);$&&$.value===")"&&o.loc.start.line!==$.loc.end.line&&e.report({fix:v=>v.replaceTextRange([$.range[1],o.range[0]],""),message:"Closing parenthesis and brace should be together for logical expression",node:o})}}},JSXSpreadAttribute:i=>{let{argument:r}=i;if(!(r.type==="Identifier"||r.type==="MemberExpression"))return;let o=t.getFirstToken(i),n=t.getLastToken(i);if(o.loc.start.line!==n.loc.end.line){let h=t.getText(r);e.report({fix:f=>f.replaceTextRange([o.range[0],n.range[1]],`{...${h}}`),message:"Simple JSX spread attribute should be on a single line",node:i})}},LogicalExpression:i=>{if(i.parent&&i.parent.type==="JSXExpressionContainer"||i.parent&&i.parent.type==="LogicalExpression"||i.parent&&i.parent.type==="IfStatement"&&i.parent.test===i||i.parent&&i.parent.type==="ConditionalExpression"&&i.parent.test===i)return;let r=o=>o.type==="CallExpression"||o.type==="LogicalExpression"||o.type==="MemberExpression"||o.type==="Identifier"||o.type==="TSAsExpression"||o.type==="ObjectExpression"||o.type==="ArrayExpression";if(!r(i.left)||!r(i.right))return;let l=o=>{if(o.type!=="LogicalExpression")return;let{left:n,right:h,operator:f}=o;l(n),l(h);let c=t.getTokenAfter(n,x=>x.value==="||"||x.value==="&&");if(!c)return;let a=n.loc.end.line,u=c.loc.start.line,b=h.loc.start.line;if(a!==u||u!==b){let x=t.text.slice(n.range[1],c.range[0]);if(x.includes(`
30
- `)&&/\n\s*$/.test(x))return;let m=t.getLastToken(n),E=t.getFirstToken(h);e.report({fix:A=>A.replaceTextRange([m.range[1],E.range[0]],` ${f} `),message:"Logical operator should be on the same line as both operands: ) || func(",node:c})}};l(i)}}},meta:{docs:{description:"Enforce opening brackets on same line for function calls and arrow function params"},fixable:"code",schema:[],type:"layout"}},Fe={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>s?s.type==="Literal"||s.type==="Identifier"||s.type==="TemplateLiteral"&&s.expressions.length===0:!1,C=s=>{if(s.type==="ImportExpression")return I(s.source);if(s.type==="CallExpression"){let g=s.callee.type==="Import",i=s.callee.type==="Identifier",r=s.callee.type==="MemberExpression";return!g&&!i&&!r||s.arguments.length>2?!1:s.arguments.every(I)}return!1},y=s=>s?!!(s.type==="Literal"||s.type==="Identifier"||s.type==="TemplateLiteral"&&s.expressions.length===0||C(s)||s.type==="BinaryExpression"||s.type==="LogicalExpression"||s.type==="MemberExpression"||s.type==="UnaryExpression"):!1;return{CallExpression(s){let{callee:g,arguments:i}=s;if(g.type!=="Identifier"&&g.type!=="MemberExpression"||i.length!==1)return;let r=i[0];if(r.type!=="ArrowFunctionExpression"||r.params.length>=2)return;let{body:l}=r;if(r.params.length===0&&!C(l)||r.params.length===1&&(l.type==="BlockStatement"||!y(l)))return;let o=s,n=s.parent;for(;n&&(n.type==="MemberExpression"||n.type==="ChainExpression");)o=n,n=n.parent;if(o.loc.start.line===o.loc.end.line)return;let f=t.getText(o).replace(/\s*\n\s*/g," ").replace(/\s+/g," ").replace(/\( \)/,"()").replace(/,\s*\)/,")").replace(/\s+\?\./g,"?.").replace(/\?\.\s+/g,"?."),a=t.lines[o.loc.start.line-1].match(/^(\s*)/)[1].length,u=0,b=o.parent;for(;b;){if(b.type==="VariableDeclarator"){u=`const ${t.getText(b.id)} = `.length;break}if(b.type==="MemberExpression"||b.type==="ChainExpression"){b=b.parent;continue}break}a+u+f.length>120||e.report({fix:T=>T.replaceText(o,f),message:"Simple function call with arrow function should be on a single line",node:s})}}},meta:{docs:{description:"Simplify simple function calls with arrow function to single line"},fixable:"code",schema:[],type:"layout"}},Be={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>s?s.type==="Literal"||s.type==="Identifier"?!0:s.type==="MemberExpression"?s.object.type==="Identifier"&&s.property.type==="Identifier"&&!s.computed:s.type==="TemplateLiteral"&&s.expressions.length===0?s.loc.start.line===s.loc.end.line:s.type==="UnaryExpression"?I(s.argument):!1:!1,C=s=>s?s.type==="Literal"||s.type==="Identifier"||s.type==="MemberExpression"||s.type==="UnaryExpression"||s.type==="TemplateLiteral"&&s.expressions.length===0&&s.loc.start.line===s.loc.end.line:!1,y=s=>{let g=[],i=s;for(;i&&i.type==="CallExpression"&&(g.unshift(i),i.callee&&i.callee.type==="MemberExpression");)i=i.callee.object;return g};return{CallExpression(s){let{arguments:g,callee:i}=s,r=!(s.parent&&s.parent.type==="MemberExpression"&&s.parent.parent&&s.parent.parent.type==="CallExpression"&&s.parent.parent.callee===s.parent);if(r&&i&&i.type==="MemberExpression"){let u=y(s);if(u.length>=2&&u[0].loc.start.line!==s.loc.end.line){let x=u.every(T=>!(T.arguments.length>1||T.arguments.length===1&&!C(T.arguments[0])));if(x){let T=t.getText(s),m=T.replace(/\s*\n\s*/g,"").replace(/\s{2,}/g," "),E=t.lines[s.loc.start.line-1],A=E.match(/^(\s*)/)[1].length,S=E.slice(A,E.indexOf(T.split(`
33
+ `)&&/\n\s*$/.test(x))return;let m=t.getLastToken(n),E=t.getFirstToken(h);e.report({fix:A=>A.replaceTextRange([m.range[1],E.range[0]],` ${f} `),message:"Logical operator should be on the same line as both operands: ) || func(",node:c})}};l(i)}}},meta:{docs:{description:"Enforce opening brackets on same line for function calls and arrow function params"},fixable:"code",schema:[],type:"layout"}},Fe={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>s?s.type==="Literal"||s.type==="Identifier"||s.type==="TemplateLiteral"&&s.expressions.length===0:!1,C=s=>{if(s.type==="ImportExpression")return I(s.source);if(s.type==="CallExpression"){let g=s.callee.type==="Import",i=s.callee.type==="Identifier",r=s.callee.type==="MemberExpression";return!g&&!i&&!r||s.arguments.length>2?!1:s.arguments.every(I)}return!1},y=s=>s?!!(s.type==="Literal"||s.type==="Identifier"||s.type==="TemplateLiteral"&&s.expressions.length===0||C(s)||s.type==="BinaryExpression"||s.type==="LogicalExpression"||s.type==="MemberExpression"||s.type==="UnaryExpression"):!1;return{CallExpression(s){let{callee:g,arguments:i}=s;if(g.type!=="Identifier"&&g.type!=="MemberExpression"||i.length!==1)return;let r=i[0];if(r.type!=="ArrowFunctionExpression"||r.params.length>=2)return;let{body:l}=r;if(l.type==="BlockStatement"||!y(l))return;let o=s,n=s.parent;for(;n&&(n.type==="MemberExpression"||n.type==="ChainExpression");)o=n,n=n.parent;if(o.loc.start.line===o.loc.end.line||t.getCommentsInside(o).some(a=>a.type==="Line"))return;let c=t.getText(o).replace(/\s*\n\s*/g," ").replace(/\s+/g," ").replace(/\(\s+/g,"(").replace(/\s+\)/g,")").replace(/,\s*\)/,")").replace(/\s+\?\./g,"?.").replace(/\?\.\s+/g,"?.");e.report({fix:a=>a.replaceText(o,c),message:"Simple function call with arrow function should be on a single line",node:s})}}},meta:{docs:{description:"Simplify simple function calls with arrow function to single line"},fixable:"code",schema:[],type:"layout"}},Be={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>s?s.type==="Literal"||s.type==="Identifier"?!0:s.type==="MemberExpression"?s.object.type==="Identifier"&&s.property.type==="Identifier"&&!s.computed:s.type==="TemplateLiteral"&&s.expressions.length===0?s.loc.start.line===s.loc.end.line:s.type==="UnaryExpression"?I(s.argument):!1:!1,C=s=>s?s.type==="Literal"||s.type==="Identifier"||s.type==="MemberExpression"||s.type==="UnaryExpression"||s.type==="TemplateLiteral"&&s.expressions.length===0&&s.loc.start.line===s.loc.end.line:!1,y=s=>{let g=[],i=s;for(;i&&i.type==="CallExpression"&&(g.unshift(i),i.callee&&i.callee.type==="MemberExpression");)i=i.callee.object;return g};return{CallExpression(s){let{arguments:g,callee:i}=s,r=!(s.parent&&s.parent.type==="MemberExpression"&&s.parent.parent&&s.parent.parent.type==="CallExpression"&&s.parent.parent.callee===s.parent);if(r&&i&&i.type==="MemberExpression"){let u=y(s);if(u.length>=2&&u[0].loc.start.line!==s.loc.end.line){let x=u.every(T=>!(T.arguments.length>1||T.arguments.length===1&&!C(T.arguments[0])));if(x){let T=t.getText(s),m=T.replace(/\s*\n\s*/g,"").replace(/\s{2,}/g," "),E=t.lines[s.loc.start.line-1],A=E.match(/^(\s*)/)[1].length,S=E.slice(A,E.indexOf(T.split(`
31
34
  `)[0].trim()));if(A+S.length+m.length<=120){e.report({fix:$=>$.replaceText(s,m),message:"Method chain with single simple arguments should be on one line",node:s});return}}if(!x){let T=!1;for(let m=1;m<u.length;m++){let E=t.getLastToken(u[m-1]),A=t.getTokenAfter(u[m].callee.property,S=>S.value==="(");if(E.loc.end.line!==A.loc.start.line){T=!0;break}}if(T){let E=t.lines[s.loc.start.line-1].match(/^(\s*)/)[1].length,A=E+4;for(let w=1;w<u.length;w++){let L=t.getLastToken(u[w-1]),R=t.getTokenAfter(u[w].callee.property,P=>P.value==="(");if(L.loc.end.line!==R.loc.start.line){A=t.lines[u[w].callee.property.loc.start.line-1].match(/^(\s*)/)[1].length;break}}let S=E-A,k="",$=s.range[0];for(let w=1;w<u.length;w++){let L=t.getLastToken(u[w-1]),R=t.getTokenAfter(u[w].callee.property,P=>P.value==="(");if(L.loc.end.line!==R.loc.start.line){k+=t.text.slice($,L.range[1]);let P=t.getTokenBefore(u[w].callee.property);k+=P.value+u[w].callee.property.name,$=R.range[0]}}if(k+=t.text.slice($,s.range[1]),S!==0){let w=k.split(`
32
35
  `);w.length>1&&(k=w[0]+`
33
36
  `+w.slice(1).map(L=>{let R=L.match(/^(\s*)/)[1].length,P=Math.max(0,R+S);return" ".repeat(P)+L.trimStart()}).join(`
@@ -52,9 +55,9 @@ ${n} }`)},message:"Destructured properties in array callback should each be o
52
55
  `+b),message:"First props type property must be on a new line when there are multiple properties",node:k})}if(c.length>1&&S){let k=c[c.length-1];S.loc.start.line===k.loc.end.line&&e.report({fix:$=>$.replaceTextRange([k.range[1],S.range[0]],`
53
56
  `+u),message:"Closing brace must be on its own line when there are multiple properties",node:S})}if(c.length===1&&x&&S){let k=c[0];if(x.loc.end.line!==S.loc.start.line){let $=t.getText(k);$=$.replace(/[,;]\s*$/,""),e.report({fix:v=>v.replaceTextRange([x.range[0],S.range[1]],`{ ${$} }`),message:"Single props type property should be on a single line",node:o})}}if(c.forEach((k,$)=>{let v=t.getText(k);if(k.type==="TSPropertySignature"&&k.optional){let p=t.getFirstToken(k),d=t.getTokenAfter(p);d&&d.value==="?"&&t.getText().slice(p.range[1],d.range[0])!==""&&e.report({fix:L=>L.replaceTextRange([p.range[1],d.range[0]],""),message:'No space allowed before "?" in optional property',node:k})}if(v.trimEnd().endsWith(";")&&e.report({fix:p=>{let d=v.lastIndexOf(";"),w=k.range[0]+d;return p.replaceTextRange([w,w+1],",")},message:"Props type properties must end with comma (,) not semicolon (;)",node:k}),c.length>1&&$>0){let p=c[$-1];k.loc.start.line===p.loc.end.line&&e.report({fix:d=>{let w=t.getTokenAfter(p);for(;w&&w.value!==","&&w.range[0]<k.range[0];)w=t.getTokenAfter(w);let L=w&&w.value===","?w.range[1]:p.range[1];return d.replaceTextRange([L,k.range[0]],`
54
57
  `+b)},message:"Each props type property must be on its own line when there are multiple properties",node:k}),k.loc.start.line-p.loc.end.line>1&&e.report({fix:d=>{let L=t.getText().slice(p.range[1],k.range[0]).replace(/\n\s*\n/g,`
55
- `);return d.replaceTextRange([p.range[1],k.range[0]],L)},message:"No empty lines allowed between props type properties",node:k})}}),c.length>1){let k=c[c.length-1];t.getText(k).trimEnd().endsWith(",")||e.report({fix:v=>v.insertTextAfter(k,","),message:"Last props type property must have trailing comma",node:k})}if(c.length===1){let k=c[0],$=t.getText(k);$.trimEnd().endsWith(",")&&e.report({fix:v=>{let p=$.lastIndexOf(","),d=k.range[0]+p;return v.removeRange([d,d+1])},message:"Single props type property should not have trailing comma",node:k})}}},s=g=>{if(!g.returnType||!g.returnType.typeAnnotation)return;let i=g.returnType,r=i.typeAnnotation;if(!C(g)&&r.type==="TSTypeLiteral"){e.report({message:"Function return type must be a type reference (interface, type, or built-in type), not an inline object type. Define the return type separately.",node:r});return}let o;if(g.params.length>0){let a=g.params[g.params.length-1];o=t.getTokenAfter(a,u=>u.value===")")}else{let u=t.getFirstToken(g);for(;u&&u.value!=="(";)u=t.getTokenAfter(u);u&&(o=t.getTokenAfter(u,b=>b.value===")"))}if(!o)return;let n=t.getFirstToken(i);if(!n||n.value!==":")return;let h=t.getFirstToken(r);if(!h)return;let f=t.getText().slice(o.range[1],n.range[0]),c=t.getText().slice(n.range[1],h.range[0]);(f!==""||c!==" ")&&e.report({fix:a=>a.replaceTextRange([o.range[1],h.range[0]],": "),message:'Return type annotation must have no space before colon and one space after: "): TypeName"',node:i})};return{ArrowFunctionExpression(g){y(g),s(g)},FunctionDeclaration(g){y(g),s(g)},FunctionExpression(g){y(g),s(g)}}},meta:{docs:{description:"Enforce inline type annotation for React component props and return types with proper formatting"},fixable:"code",schema:[],type:"suggestion"}},Je={create(e){let t=g=>g.parent&&g.parent.type==="VariableDeclarator"&&g.parent.id&&g.parent.id.type==="Identifier"?g.parent.id.name:g.id&&g.id.type==="Identifier"?g.id.name:null,I=g=>g&&/^[A-Z]/.test(g),C=g=>g&&g.endsWith("Icon"),y=g=>{let i=g.body;if(!i)return!1;if(i.type==="JSXElement")return i.openingElement&&i.openingElement.name&&i.openingElement.name.name==="svg";if(i.type==="ParenthesizedExpression"&&i.expression&&i.expression.type==="JSXElement")return i.expression.openingElement&&i.expression.openingElement.name&&i.expression.openingElement.name.name==="svg";if(i.type==="BlockStatement"){let r=i.body.filter(l=>l.type==="ReturnStatement"&&l.argument);if(r.length===1){let l=r[0].argument;if(l.type==="JSXElement")return l.openingElement&&l.openingElement.name&&l.openingElement.name.name==="svg";if(l.type==="ParenthesizedExpression"&&l.expression&&l.expression.type==="JSXElement")return l.expression.openingElement&&l.expression.openingElement.name&&l.expression.openingElement.name.name==="svg"}}return!1},s=g=>{let i=t(g);if(!I(i))return;let r=y(g),l=C(i);r&&!l&&e.report({message:`Component "${i}" returns an SVG element and should end with "Icon" suffix (e.g., "${i}Icon")`,node:g.parent&&g.parent.type==="VariableDeclarator"?g.parent.id:g.id||g}),l&&!r&&e.report({message:`Component "${i}" has "Icon" suffix but doesn't return an SVG element. Either rename it or make it return an SVG.`,node:g.parent&&g.parent.type==="VariableDeclarator"?g.parent.id:g.id||g})};return{ArrowFunctionExpression:s,FunctionDeclaration:s,FunctionExpression:s}},meta:{docs:{description:"Enforce SVG components to have 'Icon' suffix and vice versa"},fixable:null,schema:[],type:"suggestion"}},Xe={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/"),C={atoms:"",components:"",constants:"Constants",contexts:"Context",data:"Data",layouts:"Layout",pages:"Page",providers:"Provider",reducers:"Reducer",schemas:"Schema",services:"Service",strings:"Strings",theme:"Theme",themes:"Theme",views:"View"},y=new Set(["atoms","components","layouts","pages","views"]),s=new Set(["constants","data","reducers","schemas","services","strings"]),g=S=>S.split("-").map(k=>k.charAt(0).toUpperCase()+k.slice(1)).join(""),i=S=>S.charAt(0).toLowerCase()+S.slice(1),r=Object.keys(C).join("|"),l=()=>{let S=new RegExp(`\\/(${r})\\/(.+)\\.(jsx?|tsx?)$`),k=I.match(S);if(!k)return null;let $=k[1],v=C[$],d=k[2].split("/"),w=d[d.length-1],L=d.slice(0,-1);return{fileName:w,folder:$,intermediateFolders:L,suffix:v}},o=new Set(["shared","common","ui","base","general","core"]),n=S=>{let{fileName:k,folder:$,intermediateFolders:v,suffix:p}=S;if(k==="index"&&v.length===0)return null;let d=v.filter(R=>!o.has(R)),w;if(k==="index"){if(w=[...d].reverse(),w.length===0)return null}else w=[k,...[...d].reverse()];let L=w.map(g).join("")+p;return s.has($)?i(L):L},h=S=>S.parent&&S.parent.type==="VariableDeclarator"&&S.parent.id&&S.parent.id.type==="Identifier"?{name:S.parent.id.name,identifierNode:S.parent.id}:S.id&&S.id.type==="Identifier"?{name:S.id.name,identifierNode:S.id}:null,f=S=>S&&/^[A-Z]/.test(S),c=S=>{let k=S.body;return k?k.type==="JSXElement"||k.type==="JSXFragment"||k.type==="ParenthesizedExpression"&&k.expression&&(k.expression.type==="JSXElement"||k.expression.type==="JSXFragment")?!0:k.type==="BlockStatement"?k.body.some(v=>{if(v.type==="ReturnStatement"&&v.argument){let p=v.argument;return p.type==="JSXElement"||p.type==="JSXFragment"||p.type==="ParenthesizedExpression"&&p.expression&&(p.expression.type==="JSXElement"||p.expression.type==="JSXFragment")}return!1}):!1:!1},a=(S,k,$,v)=>p=>{let d=e.sourceCode?e.sourceCode.getScope(S):e.getScope(),w=(H,F)=>{let M=H.variables.find(j=>j.name===F);return M||(H.upper?w(H.upper,F):null)},L=w(d,k);if(!L)return p.replaceText(v,$);let R=[],P=new Set;return L.defs.forEach(H=>{let F=`${H.name.range[0]}-${H.name.range[1]}`;P.has(F)||(P.add(F),R.push(p.replaceText(H.name,$)))}),L.references.forEach(H=>{let F=`${H.identifier.range[0]}-${H.identifier.range[1]}`;P.has(F)||(P.add(F),R.push(p.replaceText(H.identifier,$)))}),R},u=(S,k,$,v)=>$?`"${S}" in "${k}" folder must be named "${v}" (expected "${$}" suffix with chained folder names)`:`"${S}" in "${k}" folder must be named "${v}" (expected chained folder names)`,b=(S,k)=>{let $=Object.entries(C).filter(([v,p])=>v!==k&&p&&S.endsWith(p)).sort((v,p)=>p[1].length-v[1].length)[0];return $?$[0]:null},x=S=>S&&/^[a-z]/.test(S),T=(S,k)=>{let $=S.length,v=k.length;if(Math.abs($-v)>2)return 3;let p=Array.from({length:$+1},()=>Array(v+1).fill(0));for(let d=0;d<=$;d++)p[d][0]=d;for(let d=0;d<=v;d++)p[0][d]=d;for(let d=1;d<=$;d++)for(let w=1;w<=v;w++)p[d][w]=S[d-1]===k[w-1]?p[d-1][w-1]:1+Math.min(p[d-1][w-1],p[d-1][w],p[d][w-1]);return p[$][v]},m=(S,k,$,v,p,d)=>{let L=d.fileName==="index"?"":g(d.fileName),P=[...d.intermediateFolders.filter(z=>!o.has(z))].reverse().map(g).join(""),H=L+P,F=H+$,M=i(F);if(S.endsWith(F)||S===M)return;let j,N=S.endsWith($)?S.slice(0,-$.length):S,D=N.charAt(0).toUpperCase()+N.slice(1);H.startsWith(D)||T(N,i(L))<=2?j=M:j=N+F,e.report({fix:a(p,S,j,v),message:`"${S}" in "${k}" folder must end with "${F}" (should be "${j}")`,node:v})},E=S=>{let k=l();if(!k)return;let $=h(S);if(!$)return;let{name:v,identifierNode:p}=$,{folder:d,suffix:w}=k;if(s.has(d)){if(!x(v)||!w)return;m(v,d,w,p,S,k);return}if(!f(v)){let R=S.parent&&S.parent.type==="VariableDeclarator"&&S.parent.parent;if(R&&R.parent&&R.parent.type==="ExportNamedDeclaration"&&x(v)){let H=n(k);H&&e.report({fix:a(S,v,H,p),message:`"${v}" in "${d}" folder should be PascalCase. Rename to "${H}"`,node:p})}return}if(y.has(d)&&!c(S))return;let L=n(k);if(L&&v!==L){let R=b(v,d);if(R){e.report({message:`"${v}" belongs in "${R}/" folder, not "${d}/". Move it to the correct folder.`,node:p});return}e.report({fix:a(S,v,L,p),message:u(v,d,w,L),node:p})}};return{ArrowFunctionExpression:E,FunctionDeclaration:E,FunctionExpression:E,VariableDeclarator:S=>{if(!S.id||S.id.type!=="Identifier"||S.init&&(S.init.type==="ArrowFunctionExpression"||S.init.type==="FunctionExpression"))return;let k=l();if(!k)return;let{folder:$,suffix:v}=k;if(y.has($))return;let p=S.id.name;if(s.has($)){if(!x(p)||!v)return;m(p,$,v,S.id,S,k);return}if(!f(p)){if(S.parent&&S.parent.parent&&S.parent.parent.type==="ExportNamedDeclaration"&&x(p)){let L=n(k);L&&e.report({fix:a(S,p,L,S.id),message:`"${p}" in "${$}" folder should be PascalCase. Rename to "${L}"`,node:S.id})}return}let d=n(k);if(d&&p!==d){let w=b(p,$);if(w){e.report({message:`"${p}" belongs in "${w}/" folder, not "${$}/". Move it to the correct folder.`,node:S.id});return}e.report({fix:a(S,p,d,S.id),message:u(p,$,v,d),node:S.id})}}}},meta:{docs:{description:"Enforce naming conventions based on folder location \u2014 suffix for views/layouts/pages/providers/reducers/contexts/themes, chained folder names for nested files"},fixable:"code",schema:[],type:"suggestion"}},ze={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/"),C=e.options[0]||{},y=["actions","apis","assets","atoms","components","config","configs","constants","contexts","data","enums","helpers","hooks","interfaces","layouts","lib","middlewares","molecules","organisms","pages","providers","reducers","redux","requests","routes","schemas","sections","services","store","strings","styles","theme","thunks","types","ui","utils","utilities","views","widgets"],s=C.moduleFolders||[...y,...C.extraModuleFolders||[]],i=(()=>{for(let T of s){let m=new RegExp(`(.*/${T})/`),E=I.match(m);if(E)return{folder:T,fullPath:E[1]}}return null})();if(!i){let T=I.replace(/.*\//,"").replace(/\.(jsx?|tsx?)$/,"");return s.includes(T)?{Program(m){e.report({message:`"${T}" should be a folder, not a standalone file. Use "${T}/" folder with an index file instead.`,node:m})}}:{}}let{folder:r,fullPath:l}=i,o;try{o=Me.readdirSync(l,{withFileTypes:!0})}catch{return{}}let n=/\.(tsx?|jsx?)$/,h=o.filter(T=>T.isFile()&&n.test(T.name)&&!T.name.startsWith("index.")),f=o.filter(T=>T.isDirectory());if(h.length===0&&f.length===0)return{};if(h.length<=1&&f.length===0)return{};let c=()=>{for(let T of f)try{let m=`${l}/${T.name}`;if(Me.readdirSync(m,{withFileTypes:!0}).filter(S=>S.isFile()&&n.test(S.name)).length>=2)return!0}catch{}return!1},a=h.length>0,u=f.length>0,b=a&&u,x=u?c():!1;return{Program(T){if(!a&&u&&!x){e.report({message:`Unnecessary wrapper folders in "${r}/". Each item has only one file, use direct files instead (e.g., ${r}/component.tsx).`,node:T});return}if(b&&x){!I.slice(l.length+1).includes("/")&&e.report({message:`Since some items in "${r}/" contain multiple files, all items should be wrapped in folders.`,node:T});return}b&&!x&&I.slice(l.length+1).includes("/")&&e.report({message:`Unnecessary wrapper folder. Each item in "${r}/" has only one file, use direct files instead.`,node:T})}}},meta:{docs:{description:"Enforce consistent folder structure (flat vs wrapped) in module folders like atoms, components, hooks, enums, views, layouts, and pages"},fixable:null,schema:[{additionalProperties:!1,properties:{extraModuleFolders:{items:{type:"string"},type:"array"},moduleFolders:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}},We={create(e){let C=(e.filename||e.getFilename()).replace(/\\/g,"/").split("/"),y=C[C.length-1],s=y.replace(/\.(jsx?|tsx?)$/,""),g=h=>h.endsWith("ies")?h.slice(0,-3)+"y":h.endsWith("ses")||h.endsWith("xes")||h.endsWith("zes")?h.slice(0,-2):h.endsWith("s")?h.slice(0,-1):h,i=C.indexOf("src");if(i===-1)return{};let r=C.slice(i+1,C.length-1);if(r.length===0)return{};let l=[];for(let h=1;h<r.length;h++){let f=r[h];for(let c=0;c<h;c++){let a=r[c],u=g(a),b=`-${u}`;f.endsWith(b)&&l.push({ancestorFolder:a,folderName:f,singular:u,suffix:b,suggestedName:f.slice(0,-b.length)})}}let o=null;if(s!=="index"&&r.length>=2){let h=r[r.length-1];s===h&&(o=h)}let n=null;if(s!=="index"&&!o)for(let h of r){let f=g(h),c=`-${f}`;if(s.endsWith(c)){n={folder:h,singular:f,suffix:c};break}}return l.length===0&&!n&&!o?{}:{Program(h){for(let f of l)e.report({message:`Folder name "${f.folderName}" has redundant suffix "${f.suffix}" \u2014 the "${f.ancestorFolder}/" ancestor folder already provides this context. Rename to "${f.suggestedName}".`,node:h});o&&e.report({message:`File name "${s}" is the same as its parent folder "${o}/". Use "index" instead (e.g., "${o}/index${y.match(/\.\w+$/)[0]}").`,node:h}),n&&e.report({message:`File name "${s}" has redundant suffix "${n.suffix}" \u2014 the "${n.folder}/" folder already provides this context. Rename to "${s.slice(0,-n.suffix.length)}".`,node:h})}}},meta:{docs:{description:"Disallow file and folder names that redundantly include the parent or ancestor folder name as a suffix"},fixable:null,schema:[],type:"suggestion"}};var Ve={create(e){let t=e.sourceCode||e.getSourceCode();return{BlockStatement:C=>{let{body:y}=C;if(y.length===0)return;let s=t.getFirstToken(C),g=t.getLastToken(C),i=y[0],r=y[y.length-1],l=" ".repeat(i.loc.start.column),o=" ".repeat(s.loc.start.column);s.loc.end.line===i.loc.start.line&&e.report({fix:n=>n.replaceTextRange([s.range[1],i.range[0]],`
58
+ `);return d.replaceTextRange([p.range[1],k.range[0]],L)},message:"No empty lines allowed between props type properties",node:k})}}),c.length>1){let k=c[c.length-1];t.getText(k).trimEnd().endsWith(",")||e.report({fix:v=>v.insertTextAfter(k,","),message:"Last props type property must have trailing comma",node:k})}if(c.length===1){let k=c[0],$=t.getText(k);$.trimEnd().endsWith(",")&&e.report({fix:v=>{let p=$.lastIndexOf(","),d=k.range[0]+p;return v.removeRange([d,d+1])},message:"Single props type property should not have trailing comma",node:k})}}},s=g=>{if(!g.returnType||!g.returnType.typeAnnotation)return;let i=g.returnType,r=i.typeAnnotation;if(!C(g)&&r.type==="TSTypeLiteral"){e.report({message:"Function return type must be a type reference (interface, type, or built-in type), not an inline object type. Define the return type separately.",node:r});return}let o;if(g.params.length>0){let a=g.params[g.params.length-1];o=t.getTokenAfter(a,u=>u.value===")")}else{let u=t.getFirstToken(g);for(;u&&u.value!=="(";)u=t.getTokenAfter(u);u&&(o=t.getTokenAfter(u,b=>b.value===")"))}if(!o)return;let n=t.getFirstToken(i);if(!n||n.value!==":")return;let h=t.getFirstToken(r);if(!h)return;let f=t.getText().slice(o.range[1],n.range[0]),c=t.getText().slice(n.range[1],h.range[0]);(f!==""||c!==" ")&&e.report({fix:a=>a.replaceTextRange([o.range[1],h.range[0]],": "),message:'Return type annotation must have no space before colon and one space after: "): TypeName"',node:i})};return{ArrowFunctionExpression(g){y(g),s(g)},FunctionDeclaration(g){y(g),s(g)},FunctionExpression(g){y(g),s(g)}}},meta:{docs:{description:"Enforce inline type annotation for React component props and return types with proper formatting"},fixable:"code",schema:[],type:"suggestion"}},Je={create(e){let t=g=>g.parent&&g.parent.type==="VariableDeclarator"&&g.parent.id&&g.parent.id.type==="Identifier"?g.parent.id.name:g.id&&g.id.type==="Identifier"?g.id.name:null,I=g=>g&&/^[A-Z]/.test(g),C=g=>g&&g.endsWith("Icon"),y=g=>{let i=g.body;if(!i)return!1;if(i.type==="JSXElement")return i.openingElement&&i.openingElement.name&&i.openingElement.name.name==="svg";if(i.type==="ParenthesizedExpression"&&i.expression&&i.expression.type==="JSXElement")return i.expression.openingElement&&i.expression.openingElement.name&&i.expression.openingElement.name.name==="svg";if(i.type==="BlockStatement"){let r=i.body.filter(l=>l.type==="ReturnStatement"&&l.argument);if(r.length===1){let l=r[0].argument;if(l.type==="JSXElement")return l.openingElement&&l.openingElement.name&&l.openingElement.name.name==="svg";if(l.type==="ParenthesizedExpression"&&l.expression&&l.expression.type==="JSXElement")return l.expression.openingElement&&l.expression.openingElement.name&&l.expression.openingElement.name.name==="svg"}}return!1},s=g=>{let i=t(g);if(!I(i))return;let r=y(g),l=C(i);r&&!l&&e.report({message:`Component "${i}" returns an SVG element and should end with "Icon" suffix (e.g., "${i}Icon")`,node:g.parent&&g.parent.type==="VariableDeclarator"?g.parent.id:g.id||g}),l&&!r&&e.report({message:`Component "${i}" has "Icon" suffix but doesn't return an SVG element. Either rename it or make it return an SVG.`,node:g.parent&&g.parent.type==="VariableDeclarator"?g.parent.id:g.id||g})};return{ArrowFunctionExpression:s,FunctionDeclaration:s,FunctionExpression:s}},meta:{docs:{description:"Enforce SVG components to have 'Icon' suffix and vice versa"},fixable:null,schema:[],type:"suggestion"}},Xe={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/"),C={atoms:"",components:"",constants:"Constants",contexts:"Context",data:"Data",layouts:"Layout",pages:"Page",providers:"Provider",reducers:"Reducer",schemas:"Schema",services:"Service",strings:"Strings",theme:"Theme",themes:"Theme",views:"View"},y=new Set(["atoms","components","layouts","pages","views"]),s=new Set(["constants","data","reducers","schemas","services","strings"]),g=S=>S.split("-").map(k=>k.charAt(0).toUpperCase()+k.slice(1)).join(""),i=S=>S.charAt(0).toLowerCase()+S.slice(1),r=Object.keys(C).join("|"),l=()=>{let S=new RegExp(`\\/(${r})\\/(.+)\\.(jsx?|tsx?)$`),k=I.match(S);if(!k)return null;let $=k[1],v=C[$],d=k[2].split("/"),w=d[d.length-1],L=d.slice(0,-1);return{fileName:w,folder:$,intermediateFolders:L,suffix:v}},o=new Set(["shared","common","ui","base","general","core"]),n=S=>{let{fileName:k,folder:$,intermediateFolders:v,suffix:p}=S;if(k==="index"&&v.length===0)return null;let d=v.filter(R=>!o.has(R)),w;if(k==="index"){if(w=[...d].reverse(),w.length===0)return null}else w=[k,...[...d].reverse()];let L=w.map(g).join("")+p;return s.has($)?i(L):L},h=S=>S.parent&&S.parent.type==="VariableDeclarator"&&S.parent.id&&S.parent.id.type==="Identifier"?{name:S.parent.id.name,identifierNode:S.parent.id}:S.id&&S.id.type==="Identifier"?{name:S.id.name,identifierNode:S.id}:null,f=S=>S&&/^[A-Z]/.test(S),c=S=>{let k=S.body;return k?k.type==="JSXElement"||k.type==="JSXFragment"||k.type==="ParenthesizedExpression"&&k.expression&&(k.expression.type==="JSXElement"||k.expression.type==="JSXFragment")?!0:k.type==="BlockStatement"?k.body.some(v=>{if(v.type==="ReturnStatement"&&v.argument){let p=v.argument;return p.type==="JSXElement"||p.type==="JSXFragment"||p.type==="ParenthesizedExpression"&&p.expression&&(p.expression.type==="JSXElement"||p.expression.type==="JSXFragment")}return!1}):!1:!1},a=(S,k,$,v)=>p=>{let d=e.sourceCode?e.sourceCode.getScope(S):e.getScope(),w=(H,F)=>{let M=H.variables.find(j=>j.name===F);return M||(H.upper?w(H.upper,F):null)},L=w(d,k);if(!L)return p.replaceText(v,$);let R=[],P=new Set;return L.defs.forEach(H=>{let F=`${H.name.range[0]}-${H.name.range[1]}`;P.has(F)||(P.add(F),R.push(p.replaceText(H.name,$)))}),L.references.forEach(H=>{let F=`${H.identifier.range[0]}-${H.identifier.range[1]}`;P.has(F)||(P.add(F),R.push(p.replaceText(H.identifier,$)))}),R},u=(S,k,$,v)=>$?`"${S}" in "${k}" folder must be named "${v}" (expected "${$}" suffix with chained folder names)`:`"${S}" in "${k}" folder must be named "${v}" (expected chained folder names)`,b=(S,k)=>{let $=Object.entries(C).filter(([v,p])=>v!==k&&p&&S.endsWith(p)).sort((v,p)=>p[1].length-v[1].length)[0];return $?$[0]:null},x=S=>S&&/^[a-z]/.test(S),T=(S,k)=>{let $=S.length,v=k.length;if(Math.abs($-v)>2)return 3;let p=Array.from({length:$+1},()=>Array(v+1).fill(0));for(let d=0;d<=$;d++)p[d][0]=d;for(let d=0;d<=v;d++)p[0][d]=d;for(let d=1;d<=$;d++)for(let w=1;w<=v;w++)p[d][w]=S[d-1]===k[w-1]?p[d-1][w-1]:1+Math.min(p[d-1][w-1],p[d-1][w],p[d][w-1]);return p[$][v]},m=(S,k,$,v,p,d)=>{let L=d.fileName==="index"?"":g(d.fileName),P=[...d.intermediateFolders.filter(z=>!o.has(z))].reverse().map(g).join(""),H=L+P,F=H+$,M=i(F);if(S.endsWith(F)||S===M)return;let j,N=S.endsWith($)?S.slice(0,-$.length):S,D=N.charAt(0).toUpperCase()+N.slice(1);H.startsWith(D)||T(N,i(L))<=2?j=M:j=N+F,e.report({fix:a(p,S,j,v),message:`"${S}" in "${k}" folder must end with "${F}" (should be "${j}")`,node:v})},E=S=>{let k=l();if(!k)return;let $=h(S);if(!$)return;let{name:v,identifierNode:p}=$,{folder:d,suffix:w}=k;if(s.has(d)){if(!w)return;if(x(v))m(v,d,w,p,S,k);else if(f(v)){let R=i(v);e.report({fix:a(S,v,R,p),message:`"${v}" in "${d}" folder should be camelCase. Rename to "${R}"`,node:p})}return}if(!f(v)){let R=S.parent&&S.parent.type==="VariableDeclarator"&&S.parent.parent;if(R&&R.parent&&R.parent.type==="ExportNamedDeclaration"&&x(v)){let H=n(k);H&&e.report({fix:a(S,v,H,p),message:`"${v}" in "${d}" folder should be PascalCase. Rename to "${H}"`,node:p})}return}if(y.has(d)&&!c(S))return;let L=n(k);if(L&&v!==L){let R=b(v,d);if(R){e.report({message:`"${v}" belongs in "${R}/" folder, not "${d}/". Move it to the correct folder.`,node:p});return}e.report({fix:a(S,v,L,p),message:u(v,d,w,L),node:p})}};return{ArrowFunctionExpression:E,FunctionDeclaration:E,FunctionExpression:E,VariableDeclarator:S=>{if(!S.id||S.id.type!=="Identifier"||S.init&&(S.init.type==="ArrowFunctionExpression"||S.init.type==="FunctionExpression"))return;let k=l();if(!k)return;let{folder:$,suffix:v}=k;if(y.has($))return;let p=S.id.name;if(s.has($)){if(!v)return;if(x(p))m(p,$,v,S.id,S,k);else if(f(p)){let w=i(p);e.report({fix:a(S,p,w,S.id),message:`"${p}" in "${$}" folder should be camelCase. Rename to "${w}"`,node:S.id})}return}if(!f(p)){if(S.parent&&S.parent.parent&&S.parent.parent.type==="ExportNamedDeclaration"&&x(p)){let L=n(k);L&&e.report({fix:a(S,p,L,S.id),message:`"${p}" in "${$}" folder should be PascalCase. Rename to "${L}"`,node:S.id})}return}let d=n(k);if(d&&p!==d){let w=b(p,$);if(w){e.report({message:`"${p}" belongs in "${w}/" folder, not "${$}/". Move it to the correct folder.`,node:S.id});return}e.report({fix:a(S,p,d,S.id),message:u(p,$,v,d),node:S.id})}}}},meta:{docs:{description:"Enforce naming conventions based on folder location \u2014 suffix for views/layouts/pages/providers/reducers/contexts/themes, chained folder names for nested files"},fixable:"code",schema:[],type:"suggestion"}},ze={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/"),C=e.options[0]||{},y=["actions","apis","assets","atoms","components","config","configs","constants","contexts","data","enums","helpers","hooks","interfaces","layouts","lib","middlewares","molecules","organisms","pages","providers","reducers","redux","requests","routes","schemas","sections","services","store","strings","styles","theme","thunks","types","ui","utils","utilities","views","widgets"],s=C.moduleFolders||[...y,...C.extraModuleFolders||[]],i=(()=>{for(let T of s){let m=new RegExp(`(.*/${T})/`),E=I.match(m);if(E)return{folder:T,fullPath:E[1]}}return null})();if(!i){let T=I.replace(/.*\//,"").replace(/\.(jsx?|tsx?)$/,"");return s.includes(T)?{Program(m){e.report({message:`"${T}" should be a folder, not a standalone file. Use "${T}/" folder with an index file instead.`,node:m})}}:{}}let{folder:r,fullPath:l}=i,o;try{o=Me.readdirSync(l,{withFileTypes:!0})}catch{return{}}let n=/\.(tsx?|jsx?)$/,h=o.filter(T=>T.isFile()&&n.test(T.name)&&!T.name.startsWith("index.")),f=o.filter(T=>T.isDirectory());if(h.length===0&&f.length===0)return{};if(h.length<=1&&f.length===0)return{};let c=()=>{for(let T of f)try{let m=`${l}/${T.name}`;if(Me.readdirSync(m,{withFileTypes:!0}).filter(S=>S.isFile()&&n.test(S.name)).length>=2)return!0}catch{}return!1},a=h.length>0,u=f.length>0,b=a&&u,x=u?c():!1;return{Program(T){if(!a&&u&&!x){e.report({message:`Unnecessary wrapper folders in "${r}/". Each item has only one file, use direct files instead (e.g., ${r}/component.tsx).`,node:T});return}if(b&&x){!I.slice(l.length+1).includes("/")&&e.report({message:`Since some items in "${r}/" contain multiple files, all items should be wrapped in folders.`,node:T});return}b&&!x&&I.slice(l.length+1).includes("/")&&e.report({message:`Unnecessary wrapper folder. Each item in "${r}/" has only one file, use direct files instead.`,node:T})}}},meta:{docs:{description:"Enforce consistent folder structure (flat vs wrapped) in module folders like atoms, components, hooks, enums, views, layouts, and pages"},fixable:null,schema:[{additionalProperties:!1,properties:{extraModuleFolders:{items:{type:"string"},type:"array"},moduleFolders:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}},We={create(e){let C=(e.filename||e.getFilename()).replace(/\\/g,"/").split("/"),y=C[C.length-1],s=y.replace(/\.(jsx?|tsx?)$/,""),g=h=>h.endsWith("ies")?h.slice(0,-3)+"y":h.endsWith("ses")||h.endsWith("xes")||h.endsWith("zes")?h.slice(0,-2):h.endsWith("s")?h.slice(0,-1):h,i=C.indexOf("src");if(i===-1)return{};let r=C.slice(i+1,C.length-1);if(r.length===0)return{};let l=[];for(let h=1;h<r.length;h++){let f=r[h];for(let c=0;c<h;c++){let a=r[c],u=g(a),b=`-${u}`;f.endsWith(b)&&l.push({ancestorFolder:a,folderName:f,singular:u,suffix:b,suggestedName:f.slice(0,-b.length)})}}let o=null;if(s!=="index"&&r.length>=2){let h=r[r.length-1];s===h&&(o=h)}let n=null;if(s!=="index"&&!o)for(let h of r){let f=g(h),c=`-${f}`;if(s.endsWith(c)){n={folder:h,singular:f,suffix:c};break}}return l.length===0&&!n&&!o?{}:{Program(h){for(let f of l)e.report({message:`Folder name "${f.folderName}" has redundant suffix "${f.suffix}" \u2014 the "${f.ancestorFolder}/" ancestor folder already provides this context. Rename to "${f.suggestedName}".`,node:h});o&&e.report({message:`File name "${s}" is the same as its parent folder "${o}/". Use "index" instead (e.g., "${o}/index${y.match(/\.\w+$/)[0]}").`,node:h}),n&&e.report({message:`File name "${s}" has redundant suffix "${n.suffix}" \u2014 the "${n.folder}/" folder already provides this context. Rename to "${s.slice(0,-n.suffix.length)}".`,node:h})}}},meta:{docs:{description:"Disallow file and folder names that redundantly include the parent or ancestor folder name as a suffix"},fixable:null,schema:[],type:"suggestion"}};var Ue={create(e){let t=e.sourceCode||e.getSourceCode();return{BlockStatement:C=>{let{body:y}=C;if(y.length===0)return;let s=t.getFirstToken(C),g=t.getLastToken(C),i=y[0],r=y[y.length-1],l=" ".repeat(i.loc.start.column),o=" ".repeat(s.loc.start.column);s.loc.end.line===i.loc.start.line&&e.report({fix:n=>n.replaceTextRange([s.range[1],i.range[0]],`
56
59
  `+l),message:"Statement should be on its own line after opening brace",node:i}),g.loc.start.line===r.loc.end.line&&e.report({fix:n=>n.replaceTextRange([r.range[1],g.range[0]],`
57
- `+o),message:"Closing brace should be on its own line",node:g})}}},meta:{docs:{description:"Enforce newlines after opening brace and before closing brace in blocks"},fixable:"whitespace",schema:[],type:"layout"}},Ue={create(e){let t=e.sourceCode||e.getSourceCode(),I=(y,s)=>["Identifier","MemberExpression","UnaryExpression","Literal"].includes(y.type)||y.type==="CallExpression"&&y.arguments.length===0?!0:y.type==="LogicalExpression"?/\n\s*(\|\||&&)/.test(s)?!1:s.replace(/\s+/g," ").trim().length<=80:!1;return{IfStatement:y=>{let{consequent:s,test:g}=y,i=s.type==="BlockStatement",r=t.getFirstToken(y),l=t.getTokenAfter(r,c=>c.value==="("),o=t.getTokenAfter(g,c=>c.value===")");if(!l||!o)return;let n=i?t.getFirstToken(s):null;if(r.loc.end.line!==l.loc.start.line){e.report({fix:c=>c.replaceTextRange([r.range[1],l.range[0]]," "),message:"Opening parenthesis should be on the same line as 'if'",node:l});return}let h=l.loc.end.line!==o.loc.start.line,f=t.getText(g);if(h&&I(g,f)){let c=f.replace(/\s+/g," ").trim();e.report({fix:a=>a.replaceTextRange([l.range[1],o.range[0]],c),message:"If condition should be on a single line",node:g});return}n&&o.loc.end.line!==n.loc.start.line&&e.report({fix:c=>c.replaceTextRange([o.range[1],n.range[0]]," "),message:"Opening brace should be on the same line as closing parenthesis",node:n})}}},meta:{docs:{description:"Ensure if statement has proper formatting: if (...) {"},fixable:"whitespace",schema:[],type:"layout"}},_e={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>{if(s.type!=="IfStatement")return!1;let{consequent:g}=s;return g.type!=="BlockStatement"?!0:g.loc.start.line===g.loc.end.line},C=s=>{let{alternate:g}=s;if(!g||!I(s))return;let{consequent:i}=s,r=(i.type==="BlockStatement",t.getLastToken(i)),l=t.getTokenAfter(r,n=>n.value==="else");if(!l)return;l.loc.start.line-r.loc.end.line>1&&e.report({fix:n=>n.replaceTextRange([r.range[1],l.range[0]],`
60
+ `+o),message:"Closing brace should be on its own line",node:g})}}},meta:{docs:{description:"Enforce newlines after opening brace and before closing brace in blocks"},fixable:"whitespace",schema:[],type:"layout"}},Ve={create(e){let t=e.sourceCode||e.getSourceCode(),I=(y,s)=>["Identifier","MemberExpression","UnaryExpression","Literal"].includes(y.type)||y.type==="CallExpression"&&y.arguments.length===0?!0:y.type==="LogicalExpression"?/\n\s*(\|\||&&)/.test(s)?!1:s.replace(/\s+/g," ").trim().length<=80:!1;return{IfStatement:y=>{let{consequent:s,test:g}=y,i=s.type==="BlockStatement",r=t.getFirstToken(y),l=t.getTokenAfter(r,c=>c.value==="("),o=t.getTokenAfter(g,c=>c.value===")");if(!l||!o)return;let n=i?t.getFirstToken(s):null;if(r.loc.end.line!==l.loc.start.line){e.report({fix:c=>c.replaceTextRange([r.range[1],l.range[0]]," "),message:"Opening parenthesis should be on the same line as 'if'",node:l});return}let h=l.loc.end.line!==o.loc.start.line,f=t.getText(g);if(h&&I(g,f)){let c=f.replace(/\s+/g," ").trim();e.report({fix:a=>a.replaceTextRange([l.range[1],o.range[0]],c),message:"If condition should be on a single line",node:g});return}n&&o.loc.end.line!==n.loc.start.line&&e.report({fix:c=>c.replaceTextRange([o.range[1],n.range[0]]," "),message:"Opening brace should be on the same line as closing parenthesis",node:n})}}},meta:{docs:{description:"Ensure if statement has proper formatting: if (...) {"},fixable:"whitespace",schema:[],type:"layout"}},_e={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>{if(s.type!=="IfStatement")return!1;let{consequent:g}=s;return g.type!=="BlockStatement"?!0:g.loc.start.line===g.loc.end.line},C=s=>{let{alternate:g}=s;if(!g||!I(s))return;let{consequent:i}=s,r=(i.type==="BlockStatement",t.getLastToken(i)),l=t.getTokenAfter(r,n=>n.value==="else");if(!l)return;l.loc.start.line-r.loc.end.line>1&&e.report({fix:n=>n.replaceTextRange([r.range[1],l.range[0]],`
58
61
  `+" ".repeat(l.loc.start.column)),message:"No empty line allowed between single-line if and else",node:l})},y=s=>{let{body:g}=s;if(!(!g||!Array.isArray(g)))for(let i=0;i<g.length-1;i+=1){let r=g[i],l=g[i+1];if(r.type!=="IfStatement"||l.type!=="IfStatement")continue;let o=r;for(;o.alternate&&o.alternate.type==="IfStatement";)o=o.alternate;let n=o.alternate||o.consequent,h=n.type==="BlockStatement",f=l.consequent.type==="BlockStatement";(h||f)&&l.loc.start.line-n.loc.end.line===1&&e.report({fix:a=>a.insertTextAfter(n,`
59
62
  `),message:"Expected empty line between consecutive if statements with block bodies",node:l})}};return{BlockStatement:y,IfStatement:C,Program:y}},meta:{docs:{description:"Enforce proper spacing between if statements and if-else chains"},fixable:"whitespace",schema:[],type:"layout"}},qe={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxOperands!==void 0?I.maxOperands:3,y=2,s=c=>{let a=t.getTokenBefore(c),u=t.getTokenAfter(c);if(!a||!u)return!1;if(a.value==="("&&u.value===")"){if(c.parent.type==="IfStatement"&&c.parent.test===c){let b=t.getTokenBefore(a);if(b&&b.value==="if")return!1}return!0}return!1},g=c=>{let a=c.range[0],u=c.range[1],b=t.getTokenBefore(c),x=t.getTokenAfter(c);for(;b&&b.value==="("&&x&&x.value===")";){if(c.parent.type==="IfStatement"&&c.parent.test===c){let T=t.getTokenBefore(b);if(T&&T.value==="if")break}a=b.range[0],u=x.range[1],b=t.getTokenBefore(b),x=t.getTokenAfter(x)}return t.text.slice(a,u)},i=c=>{let a=[],u=b=>{b.type==="LogicalExpression"&&!s(b)?(u(b.left),u(b.right)):a.push(b)};return u(c),a},r=(c,a=0)=>{if(c.type!=="LogicalExpression")return a;let u=a;if(c.left.type==="LogicalExpression"){let b=s(c.left)?r(c.left,a+1):r(c.left,a);u=Math.max(u,b)}if(c.right.type==="LogicalExpression"){let b=s(c.right)?r(c.right,a+1):r(c.right,a);u=Math.max(u,b)}return u},l=(c,a=0,u=null)=>{if(c.type!=="LogicalExpression")return null;let b=null;if(c.left.type==="LogicalExpression"){let x=s(c.left),T=x?a+1:a;x&&T>y&&(b={node:c.left,depth:T,parent:c,side:"left"});let m=l(c.left,T,{node:c,side:"left"});m&&(!b||m.depth>b.depth)&&(b=m)}if(c.right.type==="LogicalExpression"){let x=s(c.right),T=x?a+1:a;if(x&&T>y){let E={node:c.right,depth:T,parent:c,side:"right"};(!b||E.depth>b.depth)&&(b=E)}let m=l(c.right,T,{node:c,side:"right"});m&&(!b||m.depth>b.depth)&&(b=m)}return b},o=c=>{if(c.type!=="LogicalExpression")return 1;let a=0,u=b=>{b.type==="LogicalExpression"&&!s(b)?(u(b.left),u(b.right)):a+=1};return u(c.left),u(c.right),a},n=c=>{if(c.type!=="LogicalExpression")return null;if(s(c)&&o(c)>C)return c;if(c.left.type==="LogicalExpression"){let a=n(c.left);if(a)return a}if(c.right.type==="LogicalExpression"){let a=n(c.right);if(a)return a}return null};return{IfStatement:c=>{let{test:a}=c;if(a.type!=="LogicalExpression")return;let u=i(a),b=t.getTokenBefore(a),x=t.getTokenAfter(a);if(!b||!x)return;let T=r(a);if(T>y){let v=l(a);if(v){let p=g(v.node),d=L=>{if(L.type==="LogicalExpression"){let R=d(L.left),P=d(L.right),H=L.operator==="&&"?"And":"Or";return`${R}${H}${P}`}return L.type==="Identifier"?L.name.charAt(0).toUpperCase()+L.name.slice(1):L.type==="BinaryExpression"||L.type==="CallExpression"||L.type==="MemberExpression"?"Expr":"Cond"},w=`is${d(v.node)}`;w.length>30&&(w="isNestedCondition"),e.report({fix:L=>{let R=[],P=c.loc.start.line,H=t.getIndexFromLoc({line:P,column:0}),M=t.lines[P-1].match(/^\s*/)[0];R.push(L.insertTextBeforeRange([H,H],`const ${w} = ${p};
60
63
  ${M}`));let j=t.getTokenBefore(v.node),N=t.getTokenAfter(v.node);return j&&N&&j.value==="("&&N.value===")"?R.push(L.replaceTextRange([j.range[0],N.range[1]],w)):R.push(L.replaceText(v.node,w)),R},message:`Condition nesting depth (${T}) exceeds maximum (${y}). Extract deeply nested condition to a variable.`,node:v.node});return}}let m=b.loc.start.line!==x.loc.end.line,E=v=>{if(v.type!=="BinaryExpression")return!1;let{left:p,right:d}=v;return!!(p.loc.end.line!==d.loc.start.line||E(p)||E(d))},A=v=>{if(v.type==="BinaryExpression"){let p=A(v.left),d=A(v.right);return`${p} ${v.operator} ${d}`}return t.getText(v)},S=n(a);if(S){let p=t.lines[c.loc.start.line-1].match(/^\s*/)[0],d=p+" ",w=(F,M=!1,j=d)=>{if(F.type==="LogicalExpression"&&(M||!s(F))){let N=w(F.left,!1,j),D=w(F.right,!1,j);return`${N}
@@ -72,17 +75,17 @@ ${M}${P.operator} ${D}
72
75
  ${H})`}return g(P)};return v.replaceTextRange([b.range[0],x.range[1]],`(
73
76
  ${w}${R(a,w)}
74
77
  ${d})`)},message:`If conditions with more than ${C} operands should be multiline, with each operand on its own line`,node:a})},Property:c=>{let{value:a}=c;if(!a||a.type!=="LogicalExpression")return;let u=i(a);if(u.length<2)return;let b=a.loc.start.line,x=a.loc.end.line,T=b!==x,m=k=>{if(k.type!=="BinaryExpression")return!1;let{left:$,right:v}=k;return!!($.loc.end.line!==v.loc.start.line||m($)||m(v))},E=k=>{if(k.type==="BinaryExpression"){let $=E(k.left),v=E(k.right);return`${$} ${k.operator} ${v}`}return t.getText(k)},A=n(a);if(u.length<=C&&!A){let k=u[0].loc.start.line,$=u.every(p=>p.loc.start.line===k),v=u.some(p=>m(p));(!$||v)&&e.report({fix:p=>{let d=w=>{if(w.type==="LogicalExpression"&&!s(w)){let L=d(w.left),R=d(w.right);return`${L} ${w.operator} ${R}`}return w.type==="BinaryExpression"&&m(w)?E(w):g(w)};return p.replaceText(a,d(a))},message:`Property conditions with \u2264${C} operands should be single line: condition: a && b && c. Multi-line only for >${C} operands`,node:a});return}let S=!T;if(T){for(let k=0;k<u.length-1;k+=1)if(u[k].loc.end.line===u[k+1].loc.start.line){S=!0;break}}S&&e.report({fix:k=>{let p=t.lines[c.loc.start.line-1].match(/^\s*/)[0]+" ",d=w=>{if(w.type==="LogicalExpression"&&!s(w)){let L=d(w.left),R=d(w.right);return`${L}
75
- ${p}${w.operator} ${R}`}return g(w)};return k.replaceText(a,d(a))},message:`Property conditions with more than ${C} operands should be multiline, with each operand on its own line`,node:a})}}},meta:{docs:{description:"Enforce multiline if/property conditions when exceeding threshold (default: >3 operands)"},fixable:"whitespace",schema:[{additionalProperties:!1,properties:{maxOperands:{default:3,description:"Maximum operands to keep on single line (default: 3). Also applies to nested groups.",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},Ze={create(e){let t=e.sourceCode||e.getSourceCode(),C=(e.options[0]||{}).maxOperands??3,y=2,s=p=>{let d=t.getTokenBefore(p),w=t.getTokenAfter(p);return!d||!w?!1:d.value==="("&&w.value===")"},g=p=>{let d=p.range[0],w=p.range[1],L=t.getTokenBefore(p),R=t.getTokenAfter(p);for(;L&&L.value==="("&&R&&R.value===")";)d=L.range[0],w=R.range[1],L=t.getTokenBefore(L),R=t.getTokenAfter(R);return t.text.slice(d,w)},i=p=>{let d=[],w=L=>{L.type==="LogicalExpression"&&!s(L)?(w(L.left),w(L.right)):d.push(L)};return w(p),d},r=(p,d=0)=>{if(p.type!=="LogicalExpression")return d;let w=d;if(p.left.type==="LogicalExpression"){let L=s(p.left)?r(p.left,d+1):r(p.left,d);w=Math.max(w,L)}if(p.right.type==="LogicalExpression"){let L=s(p.right)?r(p.right,d+1):r(p.right,d);w=Math.max(w,L)}return w},l=(p,d=0)=>{if(p.type!=="LogicalExpression")return null;let w=null;if(p.left.type==="LogicalExpression"){let L=s(p.left),R=L?d+1:d;L&&R>y&&(w={node:p.left,depth:R,parent:p,side:"left"});let P=l(p.left,R);P&&(!w||P.depth>w.depth)&&(w=P)}if(p.right.type==="LogicalExpression"){let L=s(p.right),R=L?d+1:d;if(L&&R>y){let H={node:p.right,depth:R,parent:p,side:"right"};(!w||H.depth>w.depth)&&(w=H)}let P=l(p.right,R);P&&(!w||P.depth>w.depth)&&(w=P)}return w},o=p=>{if(p.type==="LogicalExpression"){let d=o(p.left),w=o(p.right),L=p.operator==="&&"?"And":"Or";return`${d}${L}${w}`}return p.type==="Identifier"?p.name.charAt(0).toUpperCase()+p.name.slice(1):p.type==="BinaryExpression"||p.type==="CallExpression"||p.type==="MemberExpression"?"Expr":"Cond"},n=p=>{if(p.type!=="LogicalExpression")return 1;let d=0,w=L=>{L.type==="LogicalExpression"&&!s(L)?(w(L.left),w(L.right)):d+=1};return w(p.left),w(p.right),d},h=p=>{if(p.type!=="LogicalExpression")return null;if(s(p)&&n(p)>C)return p;if(p.left.type==="LogicalExpression"){let d=h(p.left);if(d)return d}if(p.right.type==="LogicalExpression"){let d=h(p.right);if(d)return d}return null},f=p=>{if(p.type!=="BinaryExpression")return!1;let{left:d,right:w}=p;return!!(d.loc.end.line!==w.loc.start.line||f(d)||f(w))},c=p=>{if(p.type==="BinaryExpression"){let d=c(p.left),w=c(p.right);return`${d} ${p.operator} ${w}`}return t.getText(p)},a=p=>{if(p.type!=="LogicalExpression")return!1;let d=t.getTokenAfter(p.left,w=>w.value==="||"||w.value==="&&");if(d){let w=t.getTokenAfter(d);if(w&&d.loc.end.line<w.loc.start.line)return!0}return!!(a(p.left)||a(p.right))},u=p=>{if(p.type==="Identifier"||p.type==="MemberExpression"||p.type==="UnaryExpression"||p.type==="BinaryExpression"||p.type==="CallExpression")return!0;if(p.type==="LogicalExpression"){let d=i(p).length,w=h(p);return d<=C&&!w}return!1},b=p=>{let d=t.getText(p.test).replace(/\s+/g," ").trim(),w=g(p.consequent).replace(/\s+/g," ").trim(),L=g(p.alternate).replace(/\s+/g," ").trim();return`${d} ? ${w} : ${L}`},x=p=>t.lines[p.loc.start.line-1].match(/^\s*/)[0].length,T=p=>p?p.type==="JSXElement"||p.type==="JSXFragment"?!0:p.type==="ParenthesizedExpression"?T(p.expression):p.type==="ConditionalExpression"?T(p.consequent)||T(p.alternate):p.type==="LogicalExpression"?T(p.left)||T(p.right):!1:!1,m=p=>p.type==="ObjectExpression"&&p.properties.length>=2||p.type==="ArrayExpression"&&p.elements.length>=3,E=p=>T(p.consequent)||T(p.alternate),A=p=>{let d=w=>w.type==="ConditionalExpression"&&s(w)?i(w.test).length>C:!1;return d(p.consequent)||d(p.alternate)},S=p=>{let d=t.getTokenAfter(p.test,L=>L.value==="?"),w=t.getTokenAfter(p.consequent,L=>L.value===":");return!!(d&&p.consequent.loc.start.line!==d.loc.start.line||w&&p.alternate.loc.start.line!==w.loc.start.line)},k=p=>{let d=p.loc.start.line===p.loc.end.line,w=S(p);if(p.consequent.type==="ConditionalExpression"&&!s(p.consequent)||p.alternate.type==="ConditionalExpression"&&!s(p.alternate)||m(p.consequent)||m(p.alternate)||E(p)||A(p)||d&&!w)return!1;let R=b(p);return e.report({fix:P=>P.replaceText(p,R),message:`Ternary with \u2264${C} operands should be on a single line`,node:p}),!0},$=p=>{let{test:d}=p,w=i(d),L=d.loc.start.line,R=d.loc.end.line,P=L!==R,H=h(d);if(H){let j=p.parent,N="";j&&j.loc&&(N=t.lines[j.loc.start.line-1].match(/^\s*/)[0]);let D=N+" ",z=(J,U=!1,V=D)=>{if(J.type==="LogicalExpression"&&(U||!s(J))){let W=z(J.left,!1,V),G=z(J.right,!1,V);return`${W}
76
- ${V}${J.operator} ${G}`}if(J.type==="LogicalExpression"&&s(J)&&n(J)>C){let G=V+" ",le=X=>{if(X.type==="LogicalExpression"&&!s(X)){let Z=le(X.left),Q=le(X.right);return`${Z}
78
+ ${p}${w.operator} ${R}`}return g(w)};return k.replaceText(a,d(a))},message:`Property conditions with more than ${C} operands should be multiline, with each operand on its own line`,node:a})}}},meta:{docs:{description:"Enforce multiline if/property conditions when exceeding threshold (default: >3 operands)"},fixable:"whitespace",schema:[{additionalProperties:!1,properties:{maxOperands:{default:3,description:"Maximum operands to keep on single line (default: 3). Also applies to nested groups.",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},Ze={create(e){let t=e.sourceCode||e.getSourceCode(),C=(e.options[0]||{}).maxOperands??3,y=2,s=p=>{let d=t.getTokenBefore(p),w=t.getTokenAfter(p);return!d||!w?!1:d.value==="("&&w.value===")"},g=p=>{let d=p.range[0],w=p.range[1],L=t.getTokenBefore(p),R=t.getTokenAfter(p);for(;L&&L.value==="("&&R&&R.value===")";)d=L.range[0],w=R.range[1],L=t.getTokenBefore(L),R=t.getTokenAfter(R);return t.text.slice(d,w)},i=p=>{let d=[],w=L=>{L.type==="LogicalExpression"&&!s(L)?(w(L.left),w(L.right)):d.push(L)};return w(p),d},r=(p,d=0)=>{if(p.type!=="LogicalExpression")return d;let w=d;if(p.left.type==="LogicalExpression"){let L=s(p.left)?r(p.left,d+1):r(p.left,d);w=Math.max(w,L)}if(p.right.type==="LogicalExpression"){let L=s(p.right)?r(p.right,d+1):r(p.right,d);w=Math.max(w,L)}return w},l=(p,d=0)=>{if(p.type!=="LogicalExpression")return null;let w=null;if(p.left.type==="LogicalExpression"){let L=s(p.left),R=L?d+1:d;L&&R>y&&(w={node:p.left,depth:R,parent:p,side:"left"});let P=l(p.left,R);P&&(!w||P.depth>w.depth)&&(w=P)}if(p.right.type==="LogicalExpression"){let L=s(p.right),R=L?d+1:d;if(L&&R>y){let H={node:p.right,depth:R,parent:p,side:"right"};(!w||H.depth>w.depth)&&(w=H)}let P=l(p.right,R);P&&(!w||P.depth>w.depth)&&(w=P)}return w},o=p=>{if(p.type==="LogicalExpression"){let d=o(p.left),w=o(p.right),L=p.operator==="&&"?"And":"Or";return`${d}${L}${w}`}return p.type==="Identifier"?p.name.charAt(0).toUpperCase()+p.name.slice(1):p.type==="BinaryExpression"||p.type==="CallExpression"||p.type==="MemberExpression"?"Expr":"Cond"},n=p=>{if(p.type!=="LogicalExpression")return 1;let d=0,w=L=>{L.type==="LogicalExpression"&&!s(L)?(w(L.left),w(L.right)):d+=1};return w(p.left),w(p.right),d},h=p=>{if(p.type!=="LogicalExpression")return null;if(s(p)&&n(p)>C)return p;if(p.left.type==="LogicalExpression"){let d=h(p.left);if(d)return d}if(p.right.type==="LogicalExpression"){let d=h(p.right);if(d)return d}return null},f=p=>{if(p.type!=="BinaryExpression")return!1;let{left:d,right:w}=p;return!!(d.loc.end.line!==w.loc.start.line||f(d)||f(w))},c=p=>{if(p.type==="BinaryExpression"){let d=c(p.left),w=c(p.right);return`${d} ${p.operator} ${w}`}return t.getText(p)},a=p=>{if(p.type!=="LogicalExpression")return!1;let d=t.getTokenAfter(p.left,w=>w.value==="||"||w.value==="&&");if(d){let w=t.getTokenAfter(d);if(w&&d.loc.end.line<w.loc.start.line)return!0}return!!(a(p.left)||a(p.right))},u=p=>{if(p.type==="Identifier"||p.type==="MemberExpression"||p.type==="UnaryExpression"||p.type==="BinaryExpression"||p.type==="CallExpression")return!0;if(p.type==="LogicalExpression"){let d=i(p).length,w=h(p);return d<=C&&!w}return!1},b=p=>{let d=t.getText(p.test).replace(/\s+/g," ").trim(),w=g(p.consequent).replace(/\s+/g," ").trim(),L=g(p.alternate).replace(/\s+/g," ").trim();return`${d} ? ${w} : ${L}`},x=p=>t.lines[p.loc.start.line-1].match(/^\s*/)[0].length,T=p=>p?p.type==="JSXElement"||p.type==="JSXFragment"?!0:p.type==="ParenthesizedExpression"?T(p.expression):p.type==="ConditionalExpression"?T(p.consequent)||T(p.alternate):p.type==="LogicalExpression"?T(p.left)||T(p.right):!1:!1,m=p=>p.type==="ObjectExpression"&&p.properties.length>=2||p.type==="ArrayExpression"&&p.elements.length>=3,E=p=>T(p.consequent)||T(p.alternate),A=p=>{let d=w=>w.type==="ConditionalExpression"&&s(w)?i(w.test).length>C:!1;return d(p.consequent)||d(p.alternate)},S=p=>{let d=t.getTokenAfter(p.test,L=>L.value==="?"),w=t.getTokenAfter(p.consequent,L=>L.value===":");return!!(d&&p.consequent.loc.start.line!==d.loc.start.line||w&&p.alternate.loc.start.line!==w.loc.start.line)},k=p=>{let d=p.loc.start.line===p.loc.end.line,w=S(p);if(p.consequent.type==="ConditionalExpression"&&!s(p.consequent)||p.alternate.type==="ConditionalExpression"&&!s(p.alternate)||m(p.consequent)||m(p.alternate)||E(p)||A(p)||d&&!w)return!1;let R=b(p);return e.report({fix:P=>P.replaceText(p,R),message:`Ternary with \u2264${C} operands should be on a single line`,node:p}),!0},$=p=>{let{test:d}=p,w=i(d),L=d.loc.start.line,R=d.loc.end.line,P=L!==R,H=h(d);if(H){let j=p.parent,N="";j&&j.loc&&(N=t.lines[j.loc.start.line-1].match(/^\s*/)[0]);let D=N+" ",z=(J,V=!1,U=D)=>{if(J.type==="LogicalExpression"&&(V||!s(J))){let W=z(J.left,!1,U),G=z(J.right,!1,U);return`${W}
79
+ ${U}${J.operator} ${G}`}if(J.type==="LogicalExpression"&&s(J)&&n(J)>C){let G=U+" ",le=X=>{if(X.type==="LogicalExpression"&&!s(X)){let Z=le(X.left),Q=le(X.right);return`${Z}
77
80
  ${G}${X.operator} ${Q}`}return g(X)},B=le(J.left),O=le(J.right);return`(
78
81
  ${G}${B}
79
82
  ${G}${J.operator} ${O}
80
- ${V})`}return g(J)},q=(J,U)=>{if(J===U){let V=z(J,!0);return`(
81
- ${D}${V}
82
- ${N})`}if(J.type==="LogicalExpression"&&!s(J)){let V=q(J.left,U),W=q(J.right,U);return`${V} ${J.operator} ${W}`}if(J.type==="LogicalExpression"&&s(J)){let V=(W,G)=>W===G?!0:W.type==="LogicalExpression"?V(W.left,G)||V(W.right,G):!1;if(V(J,U))return`(${q(J,U)})`}return g(J)},Y=(J=>{let U=[],V=W=>{W.type==="LogicalExpression"&&!s(W)?(V(W.left),V(W.right)):U.push(W)};return J.type==="LogicalExpression"&&(V(J.left),V(J.right)),U})(H);if(!Y.every((J,U)=>U===0?!0:J.loc.start.line!==Y[U-1].loc.start.line)){let J=q(d,H),U=g(p.consequent).replace(/\s+/g," ").trim(),V=g(p.alternate).replace(/\s+/g," ").trim();e.report({fix:W=>W.replaceText(p,`${J} ? ${U} : ${V}`),message:`Nested condition with >${C} operands should be formatted multiline`,node:H});return}}if(w.length<=C){if(h(d))return;let N=m(p.consequent)||m(p.alternate);if(E(p))return;let D=p.consequent.type==="ConditionalExpression"&&!s(p.consequent)||p.alternate.type==="ConditionalExpression"&&!s(p.alternate);if(N||D||A(p))return;let z=p.loc.start.line===p.loc.end.line,q=S(p);if(z&&!q)return;let _=b(p);e.report({fix:Y=>Y.replaceText(p,_),message:`Ternary with \u2264${C} operands should be on a single line`,node:p});return}let F=!P,M=p.parent;if(P){for(let j=0;j<w.length-1;j+=1)if(w[j].loc.end.line===w[j+1].loc.start.line){F=!0;break}if(!F&&a(d)&&(F=!0),!F){let j=t.getTokenAfter(d,N=>N.value==="?");j&&j.loc.start.line===d.loc.end.line&&(F=!0)}if(!F){let j=t.getTokenAfter(d,N=>N.value==="?");j&&j.loc.start.line>d.loc.end.line+1&&(F=!0)}if(!F){let j=t.getTokenAfter(p.consequent,N=>N.value===":");j&&j.loc.start.line>p.consequent.loc.end.line+1&&(F=!0)}if(!F&&S(p)&&(F=!0),!F){let j=t.getTokenAfter(d,D=>D.value==="?"),N=t.getTokenAfter(p.consequent,D=>D.value===":");j&&N&&j.loc.start.line===N.loc.start.line&&(F=!0)}if(!F&&M&&M.type==="Property"&&M.value===p){let j=M.key.loc.end.line;w[0].loc.start.line!==j&&(F=!0)}}F&&e.report({fix:j=>{let N,D=!1,z="";if(M&&M.type==="Property"&&M.value===p){let V=M.key.loc.end.line;w[0].loc.start.line!==V&&(D=!0,z=t.getText(M.key)+": ",N=t.lines[M.loc.start.line-1].match(/^\s*/)[0])}N||(N=t.lines[p.loc.start.line-1].match(/^\s*/)[0]);let q=N+" ",_=V=>{if(V.type==="LogicalExpression"&&!s(V)){let W=_(V.left),G=_(V.right);return`${W}
83
- ${q}${V.operator} ${G}`}return g(V)},Y=t.getText(p.consequent),ne=t.getText(p.alternate),U=`${_(d)}
83
+ ${U})`}return g(J)},q=(J,V)=>{if(J===V){let U=z(J,!0);return`(
84
+ ${D}${U}
85
+ ${N})`}if(J.type==="LogicalExpression"&&!s(J)){let U=q(J.left,V),W=q(J.right,V);return`${U} ${J.operator} ${W}`}if(J.type==="LogicalExpression"&&s(J)){let U=(W,G)=>W===G?!0:W.type==="LogicalExpression"?U(W.left,G)||U(W.right,G):!1;if(U(J,V))return`(${q(J,V)})`}return g(J)},Y=(J=>{let V=[],U=W=>{W.type==="LogicalExpression"&&!s(W)?(U(W.left),U(W.right)):V.push(W)};return J.type==="LogicalExpression"&&(U(J.left),U(J.right)),V})(H);if(!Y.every((J,V)=>V===0?!0:J.loc.start.line!==Y[V-1].loc.start.line)){let J=q(d,H),V=g(p.consequent).replace(/\s+/g," ").trim(),U=g(p.alternate).replace(/\s+/g," ").trim();e.report({fix:W=>W.replaceText(p,`${J} ? ${V} : ${U}`),message:`Nested condition with >${C} operands should be formatted multiline`,node:H});return}}if(w.length<=C){if(h(d))return;let N=m(p.consequent)||m(p.alternate);if(E(p))return;let D=p.consequent.type==="ConditionalExpression"&&!s(p.consequent)||p.alternate.type==="ConditionalExpression"&&!s(p.alternate);if(N||D||A(p))return;let z=p.loc.start.line===p.loc.end.line,q=S(p);if(z&&!q)return;let _=b(p);e.report({fix:Y=>Y.replaceText(p,_),message:`Ternary with \u2264${C} operands should be on a single line`,node:p});return}let F=!P,M=p.parent;if(P){for(let j=0;j<w.length-1;j+=1)if(w[j].loc.end.line===w[j+1].loc.start.line){F=!0;break}if(!F&&a(d)&&(F=!0),!F){let j=t.getTokenAfter(d,N=>N.value==="?");j&&j.loc.start.line===d.loc.end.line&&(F=!0)}if(!F){let j=t.getTokenAfter(d,N=>N.value==="?");j&&j.loc.start.line>d.loc.end.line+1&&(F=!0)}if(!F){let j=t.getTokenAfter(p.consequent,N=>N.value===":");j&&j.loc.start.line>p.consequent.loc.end.line+1&&(F=!0)}if(!F&&S(p)&&(F=!0),!F){let j=t.getTokenAfter(d,D=>D.value==="?"),N=t.getTokenAfter(p.consequent,D=>D.value===":");j&&N&&j.loc.start.line===N.loc.start.line&&(F=!0)}if(!F&&M&&M.type==="Property"&&M.value===p){let j=M.key.loc.end.line;w[0].loc.start.line!==j&&(F=!0)}}F&&e.report({fix:j=>{let N,D=!1,z="";if(M&&M.type==="Property"&&M.value===p){let U=M.key.loc.end.line;w[0].loc.start.line!==U&&(D=!0,z=t.getText(M.key)+": ",N=t.lines[M.loc.start.line-1].match(/^\s*/)[0])}N||(N=t.lines[p.loc.start.line-1].match(/^\s*/)[0]);let q=N+" ",_=U=>{if(U.type==="LogicalExpression"&&!s(U)){let W=_(U.left),G=_(U.right);return`${W}
86
+ ${q}${U.operator} ${G}`}return g(U)},Y=t.getText(p.consequent),ne=t.getText(p.alternate),V=`${_(d)}
84
87
  ${q}? ${Y}
85
- ${q}: ${ne}`;return D?j.replaceTextRange([M.key.range[0],p.range[1]],`${z}${U}`):j.replaceText(p,U)},message:`Ternary conditions with more than ${C} operands should be multiline, with each operand on its own line`,node:d})},v=p=>{let d=p.parent;for(;d&&d.type==="ParenthesizedExpression";)d=d.parent;return d&&d.type==="ConditionalExpression"?d.consequent===p||d.alternate===p||p.parent.type==="ParenthesizedExpression"&&(d.consequent===p.parent||d.alternate===p.parent):!1};return{ConditionalExpression(p){let{test:d}=p;if(!v(p)){if(d.type==="LogicalExpression"){let w=r(d);if(w>y){let L=l(d);if(L){let R=g(L.node),P=`is${o(L.node)}`;P.length>30&&(P="isNestedCondition"),e.report({fix:H=>{let F=[],M=p;for(;M.parent&&M.parent.type!=="Program"&&M.parent.type!=="BlockStatement";)M=M.parent;let j=M.loc.start.line,N=t.getIndexFromLoc({line:j,column:0}),z=t.lines[j-1].match(/^\s*/)[0];F.push(H.insertTextBeforeRange([N,N],`const ${P} = ${R};
88
+ ${q}: ${ne}`;return D?j.replaceTextRange([M.key.range[0],p.range[1]],`${z}${V}`):j.replaceText(p,V)},message:`Ternary conditions with more than ${C} operands should be multiline, with each operand on its own line`,node:d})},v=p=>{let d=p.parent;for(;d&&d.type==="ParenthesizedExpression";)d=d.parent;return d&&d.type==="ConditionalExpression"?d.consequent===p||d.alternate===p||p.parent.type==="ParenthesizedExpression"&&(d.consequent===p.parent||d.alternate===p.parent):!1};return{ConditionalExpression(p){let{test:d}=p;if(!v(p)){if(d.type==="LogicalExpression"){let w=r(d);if(w>y){let L=l(d);if(L){let R=g(L.node),P=`is${o(L.node)}`;P.length>30&&(P="isNestedCondition"),e.report({fix:H=>{let F=[],M=p;for(;M.parent&&M.parent.type!=="Program"&&M.parent.type!=="BlockStatement";)M=M.parent;let j=M.loc.start.line,N=t.getIndexFromLoc({line:j,column:0}),z=t.lines[j-1].match(/^\s*/)[0];F.push(H.insertTextBeforeRange([N,N],`const ${P} = ${R};
86
89
  ${z}`));let q=t.getTokenBefore(L.node),_=t.getTokenAfter(L.node);return q&&_&&q.value==="("&&_.value===")"?F.push(H.replaceTextRange([q.range[0],_.range[1]],P)):F.push(H.replaceText(L.node,P)),F},message:`Ternary condition nesting depth (${w}) exceeds maximum (${y}). Extract deeply nested condition to a variable.`,node:L.node});return}}}u(d)&&k(p)||d.type==="LogicalExpression"&&$(p)}}}},meta:{docs:{description:"Enforce consistent ternary formatting based on condition operand count: \u2264maxOperands collapses to single line, >maxOperands expands to multiline"},fixable:"code",schema:[{additionalProperties:!1,properties:{maxOperands:{default:3,description:"Maximum condition operands to keep ternary on single line (default: 3). Also applies to nested groups.",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},Ke={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxOperands!==void 0?I.maxOperands:3,y=o=>{let n=t.getTokenBefore(o),h=t.getTokenAfter(o);return!n||!h?!1:n.value==="("&&h.value===")"},s=o=>{let n=[],h=f=>{f.type==="LogicalExpression"&&!y(f)?(h(f.left),h(f.right)):n.push(f)};return h(o),n},g=(o,n)=>{let f=t.getTokensBetween(o,n).find(c=>c.value==="||"||c.value==="&&"||c.value==="??"||c.value==="|"||c.value==="&");return f?f.value:"||"},i=o=>o.loc.start.line!==o.loc.end.line,r=o=>{let n=o.parent;for(;n;){if(n.type==="IfStatement"&&n.test===o||n.type==="ConditionalExpression"&&n.test===o)return!0;if(n.type.includes("Statement")||n.type.includes("Declaration"))return!1;n=n.parent}return!1};return{LogicalExpression:o=>{if(o.parent.type==="LogicalExpression"&&!y(o)||r(o))return;let n=s(o);if(n.length<=C){if(i(o)){if(n.some(f=>f.loc.start.line!==f.loc.end.line))return;e.report({fix(f){let c=[t.getText(n[0])];for(let a=1;a<n.length;a++){let u=g(n[a-1],n[a]);c.push(` ${u} ${t.getText(n[a])}`)}return f.replaceText(o,c.join(""))},message:`Logical expression with ${n.length} operands should be on a single line (max for multiline: ${C})`,node:o})}return}if(i(o)){let h=!0;for(let f=1;f<n.length;f++)if(n[f].loc.start.line===n[f-1].loc.end.line){h=!1;break}if(h)return}e.report({fix(h){let f=t.getText(n[0]),c=t.getFirstToken(n[0]),a=t.text.lastIndexOf(`
87
90
  `,c.range[0])+1,b=t.text.slice(a,c.range[0]).match(/^(\s*)/),x=b?b[1]:"",T=[f];for(let E=1;E<n.length;E++){let A=g(n[E-1],n[E]),S=t.getText(n[E]);T.push(`${x} ${A} ${S}`)}let m=T.join(`
88
91
  `);return h.replaceText(o,m)},message:`Logical expression with ${n.length} operands should be on multiple lines (max: ${C})`,node:o})}}},meta:{docs:{description:"Enforce single line for \u2264maxOperands, multiline for >maxOperands logical expressions"},fixable:"code",schema:[{additionalProperties:!1,properties:{maxOperands:{default:3,description:"Maximum operands to keep on single line (default: 3)",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},Ge={create(e){let t=e.sourceCode||e.getSourceCode(),I=y=>["IfStatement","ForStatement","ForInStatement","ForOfStatement","WhileStatement","DoWhileStatement","TryStatement","SwitchStatement","WithStatement"].includes(y.type),C=y=>{if(y.type==="IfStatement"&&y.alternate)return C(y.alternate);if(y.type==="TryStatement"){if(y.finalizer)return y.finalizer.loc.end.line;if(y.handler)return y.handler.loc.end.line}return y.loc.end.line};return{"BlockStatement:exit"(y){let s=y.parent;if(!s||!I(s)||s.type==="IfStatement"&&s.consequent===y&&s.alternate||s.type==="TryStatement"&&(s.block===y||s.handler?.body===y)&&(s.handler||s.finalizer)&&(s.block===y&&(s.handler||s.finalizer)||s.handler?.body===y&&s.finalizer))return;let g=s.parent;if(!g||g.type!=="BlockStatement")return;let i=g.body.indexOf(s);if(i===-1||i===g.body.length-1)return;let r=g.body[i+1];if(s.type==="IfStatement"&&r.type==="IfStatement")return;let l=C(s);r.loc.start.line-l<2&&e.report({fix:n=>{let h=t.getLastToken(s);return n.insertTextAfter(h,`
@@ -217,11 +220,11 @@ ${c}"`},r=(f,c,a)=>f.length+c>C||a>y,l=(f,c)=>{if(!/\n/.test(f))return!1;let a=c
217
220
  ${c} ${f.split(`
218
221
  `).join(`
219
222
  `+c+" ")}
220
- ${c})${x}`),message:"Multi-line JSX in object property must be wrapped in parentheses",node:s})}return}if(s.type==="ConditionalExpression"){let r=t.getText(s).replace(/\s*\n\s*/g," ").trim();if(s.loc.start.line!==s.loc.end.line&&r.length<=80){e.report({fix:h=>h.replaceText(s,r),message:"Short ternary expression should be on a single line",node:s});return}let o=t.getTokenAfter(s.test,h=>h.value==="?"),n=t.getTokenAfter(s.consequent,h=>h.value===":");if(o){let h=t.getTokenAfter(o);if(h&&o.loc.end.line<h.loc.start.line&&r.length<=80){e.report({fix:f=>f.replaceText(s,r),message:"Ternary operator '?' should not be at end of line",node:o});return}}if(n){let h=t.getTokenAfter(n);if(h&&n.loc.end.line<h.loc.start.line&&r.length<=80){e.report({fix:f=>f.replaceText(s,r),message:"Ternary operator ':' should not be at end of line",node:n});return}}return}if(s.loc.start.line>y.loc.end.line){if((s.type==="ObjectExpression"||s.type==="ArrayExpression")&&s.loc.start.line!==s.loc.end.line)return;let i=t.getTokenAfter(y);if(i&&i.value==="(")return;e.report({fix:r=>r.replaceTextRange([y.range[1],s.range[0]]," "),message:"Property value should be on the same line as the colon",node:s})}}}},meta:{docs:{description:"Enforce property value on same line as colon with proper spacing"},fixable:"whitespace",schema:[],type:"layout"}},Bt={create(e){let t=e.sourceCode||e.getSourceCode();return{Property(I){let{key:C}=I;if(C.type!=="Literal"||typeof C.value!="string")return;let y=C.value,s=y.trim();y!==s&&s.length>0&&e.report({fix:g=>g.replaceText(C,`"${s}"`),message:`String property key should not have extra spaces inside quotes: "${s}" not "${y}"`,node:C})}}},meta:{docs:{description:"Enforce no extra spaces inside string property keys"},fixable:"code",schema:[],type:"layout"}};var Ht={create(e){let t={CALLBACK:12,CONTEXT_HOOK:8,CUSTOM_HOOK:9,DERIVED_STATE:10,EFFECT:14,HANDLER_FUNCTION:13,MEMO:11,PROPS_DESTRUCTURE:1,PROPS_DESTRUCTURE_BODY:2,REDUCER:5,REF:3,RETURN:15,ROUTER_HOOK:7,SELECTOR_DISPATCH:6,STATE:4,UNKNOWN:99},I={1:"props destructure",2:"destructured variables from props",3:"useRef",4:"useState",5:"useReducer",6:"useSelector/useDispatch",7:"router hooks",8:"context hooks",9:"custom hooks",10:"derived state/computed variables",11:"useMemo",12:"useCallback",13:"handler functions",14:"useEffect/useLayoutEffect",15:"return statement",99:"unknown"},C=new Set(["useState"]),y=new Set(["useRef"]),s=new Set(["useReducer"]),g=new Set(["useEffect","useLayoutEffect"]),i=new Set(["useMemo"]),r=new Set(["useCallback"]),l=new Set(["useSelector","useDispatch","useStore"]),o=new Set(["useNavigate","useLocation","useParams","useSearchParams","useRouter","usePathname","useMatch","useMatches","useRouteLoaderData","useNavigation","useResolvedPath","useHref","useInRouterContext","useNavigationType","useOutlet","useOutletContext","useRouteError","useRoutes","useBlocker"]),n=new Set(["useContext","useToast","useTheme","useAuth","useModal","useDialog","useNotification","useI18n","useTranslation","useIntl","useForm","useFormContext"]),h=k=>{if(!k)return!1;if(k.type==="JSXElement"||k.type==="JSXFragment")return!0;if(k.type==="BlockStatement"){for(let $ of k.body)if($.type==="ReturnStatement"&&$.argument&&h($.argument))return!0}return k.type==="ConditionalExpression"?h(k.consequent)||h(k.alternate):k.type==="LogicalExpression"?h(k.left)||h(k.right):k.type==="ParenthesizedExpression"?h(k.expression):!1},f=k=>{if(k.parent){if(k.parent.type==="VariableDeclarator"&&k.parent.id&&k.parent.id.type==="Identifier")return k.parent.id.name;if(k.id&&k.id.type==="Identifier")return k.id.name}return null},c=k=>{let $=f(k);if($&&/^[A-Z]/.test($)){let v=k.body;return h(v)}return!1},a=k=>{let $=f(k);return $&&/^use[A-Z]/.test($)?!(k.body.type!=="BlockStatement"||h(k.body)):!1},u=k=>k.type!=="CallExpression"?null:k.callee.type==="Identifier"?k.callee.name:k.callee.type==="MemberExpression"&&k.callee.property.type==="Identifier"?k.callee.property.name:null,b=k=>{let $=u(k);return $&&/^use[A-Z]/.test($)},x=k=>k&&(k.type==="ArrowFunctionExpression"||k.type==="FunctionExpression"),T=k=>{if(k.type==="VariableDeclaration"){let $=k.declarations[0];if($&&$.init&&x($.init))return $.init.type!=="CallExpression"}return k.type==="FunctionDeclaration"},m=(k,$=new Set)=>{if(k.type==="ReturnStatement")return t.RETURN;if(k.type==="ExpressionStatement"&&k.expression.type==="CallExpression"){let v=u(k.expression);if(v){if(g.has(v))return t.EFFECT;if(b(k.expression))return t.CUSTOM_HOOK}return t.UNKNOWN}if(k.type==="VariableDeclaration"){let v=k.declarations;for(let p of v)if(p.init){if(p.init.type==="CallExpression"){let d=u(p.init);if(d){if(C.has(d))return t.STATE;if(y.has(d))return t.REF;if(s.has(d))return t.REDUCER;if(l.has(d))return t.SELECTOR_DISPATCH;if(o.has(d))return t.ROUTER_HOOK;if(n.has(d))return t.CONTEXT_HOOK;if(i.has(d))return t.MEMO;if(r.has(d))return t.CALLBACK;if(b(p.init))return t.CUSTOM_HOOK}}if(x(p.init))return t.HANDLER_FUNCTION}for(let p of v)if(p.id.type==="ObjectPattern"&&p.init){if(p.init.type==="Identifier"&&$.has(p.init.name))return t.PROPS_DESTRUCTURE_BODY;if(p.init.type==="MemberExpression"){let d=p.init;for(;d.type==="MemberExpression";)d=d.object;if(d.type==="Identifier"&&$.has(d.name))return t.PROPS_DESTRUCTURE_BODY}if(p.init.type==="Identifier"&&p.init.name==="props")return t.PROPS_DESTRUCTURE}for(let p of v)if(p.init&&p.init.type==="CallExpression"){let d=p.init.callee;if(d&&d.type==="Identifier"&&!b(p.init))return t.HANDLER_FUNCTION}return t.DERIVED_STATE}return k.type==="FunctionDeclaration"?t.HANDLER_FUNCTION:t.UNKNOWN},E=(k,$)=>{let v=k.body,p=e.sourceCode||e.getSourceCode();if(v.type!=="BlockStatement")return;let d=v.body;if(d.length===0)return;let w=new Set;for(let B of k.params)if(B.type==="Identifier")w.add(B.name);else if(B.type==="ObjectPattern")for(let O of B.properties)O.type==="Property"&&O.value?O.value.type==="Identifier"?w.add(O.value.name):O.value.type==="AssignmentPattern"&&O.value.left.type==="Identifier"&&w.add(O.value.left.name):O.type==="RestElement"&&O.argument.type==="Identifier"&&w.add(O.argument.name);else if(B.type==="AssignmentPattern"&&B.left){if(B.left.type==="Identifier")w.add(B.left.name);else if(B.left.type==="ObjectPattern")for(let O of B.left.properties)O.type==="Property"&&O.value&&(O.value.type==="Identifier"?w.add(O.value.name):O.value.type==="AssignmentPattern"&&O.value.left.type==="Identifier"&&w.add(O.value.left.name))}let L=B=>B.type==="VariableDeclaration"||B.type==="FunctionDeclaration"||B.type==="ExpressionStatement"||B.type==="ReturnStatement",R=B=>{let O=new Set;if(B.type==="VariableDeclaration"){for(let X of B.declarations)if(X.id.type==="Identifier")O.add(X.id.name);else if(X.id.type==="ObjectPattern")for(let Z of X.id.properties)Z.type==="Property"&&Z.value.type==="Identifier"?O.add(Z.value.name):Z.type==="RestElement"&&Z.argument.type==="Identifier"&&O.add(Z.argument.name);else if(X.id.type==="ArrayPattern")for(let Z of X.id.elements)Z&&Z.type==="Identifier"&&O.add(Z.name)}else B.type==="FunctionDeclaration"&&B.id&&O.add(B.id.name);return O},P=(B,O=new Set)=>(B&&(B.type==="Identifier"?O.add(B.name):B.type==="MemberExpression"?P(B.object,O):B.type==="CallExpression"?(P(B.callee,O),B.arguments.forEach(X=>P(X,O))):B.type==="BinaryExpression"||B.type==="LogicalExpression"?(P(B.left,O),P(B.right,O)):B.type==="ConditionalExpression"?(P(B.test,O),P(B.consequent,O),P(B.alternate,O)):B.type==="UnaryExpression"?P(B.argument,O):B.type==="ArrayExpression"?B.elements.forEach(X=>P(X,O)):B.type==="ObjectExpression"?B.properties.forEach(X=>{X.type==="Property"&&P(X.value,O)}):B.type==="TemplateLiteral"?B.expressions.forEach(X=>P(X,O)):(B.type==="ChainExpression"||B.type==="TSAsExpression"||B.type==="TSNonNullExpression")&&P(B.expression,O)),O),H=B=>{let O=new Set;if(B.type==="VariableDeclaration")for(let X of B.declarations)X.init&&P(X.init,O);return O},F=d.filter(L);if(F.length<2)return;let M=new Map,j=new Map;for(let B=0;B<d.length;B++){let O=d[B],X=R(O);for(let Z of X)j.set(Z,B)}for(let B=0;B<d.length;B++){let O=d[B],X=R(O),Z=H(O),Q=L(O)?m(O,w):t.UNKNOWN;M.set(B,{category:Q,declared:X,dependencies:Z,index:B,statement:O})}let N=new Map;for(let B=0;B<d.length;B++){let O=M.get(B),X=new Set;for(let Z of O.dependencies){let Q=j.get(Z);Q!==void 0&&Q!==B&&X.add(Q)}N.set(B,X)}let D=!1,z=!1,q=0,_=null,Y=null,ne=null,J=null,U=null;for(let B of F){let O=m(B,w);O!==t.UNKNOWN&&(O<q&&!D&&(D=!0,_=B,Y=O,ne=q),q=O)}for(let B=0;B<d.length;B++){let O=N.get(B)||new Set;for(let X of O)if(X>B){z=!0,J=d[B];let Z=M.get(X);for(let Q of Z.declared)if(M.get(B).dependencies.has(Q)){U=Q;break}break}if(z)break}if(!D&&!z)return;let W=(()=>{let B=[],O=new Set,X=new Set,Z=K=>{if(O.has(K)||X.has(K))return;X.add(K);let re=N.get(K)||new Set;for(let ee of re)Z(ee);X.delete(K),O.add(K),B.push(K)},Q=new Map;for(let K=0;K<d.length;K++){let re=M.get(K),ee=re.category;if(ee===t.UNKNOWN){for(let oe=K+1;oe<d.length;oe++){let ue=M.get(oe);if(ue.category!==t.UNKNOWN){ee=ue.category;break}}ee===t.UNKNOWN&&(ee=t.RETURN)}let ae=N.get(K)||new Set,ce=ee;for(let oe of ae){let ge=M.get(oe).category;ge===t.UNKNOWN&&(ge=t.DERIVED_STATE),ge>ce&&(ce=ge)}let se=Math.max(ee,ce);Q.has(se)||Q.set(se,[]),Q.get(se).push({deps:ae,effectiveCategory:ee,index:K,originalCategory:re.category})}let he=[...Q.keys()].sort((K,re)=>K-re),xe=[];for(let K of he){let re=Q.get(K),ee=new Set,ae=[],ce=se=>{if(!ee.has(se.index)){ee.add(se.index);for(let oe of se.deps){let ue=re.find(ge=>ge.index===oe);ue&&!ee.has(oe)&&ce(ue)}ae.push(se.index)}};re.sort((se,oe)=>se.index-oe.index);for(let se of re)ce(se);xe.push(...ae)}return xe})();if(!W.some((B,O)=>B!==O))return;let le=B=>{let X=p.lines[d[0].loc.start.line-1].match(/^\s*/)[0],Z="",Q=null;for(let K=0;K<W.length;K++){let re=W[K],ee=M.get(re),ae=ee.category!==t.UNKNOWN?ee.category:null;Q!==null&&ae!==null&&ae!==Q&&(Z+=`
223
+ ${c})${x}`),message:"Multi-line JSX in object property must be wrapped in parentheses",node:s})}return}if(s.type==="ConditionalExpression"){let r=t.getText(s).replace(/\s*\n\s*/g," ").trim();if(s.loc.start.line!==s.loc.end.line&&r.length<=80){e.report({fix:h=>h.replaceText(s,r),message:"Short ternary expression should be on a single line",node:s});return}let o=t.getTokenAfter(s.test,h=>h.value==="?"),n=t.getTokenAfter(s.consequent,h=>h.value===":");if(o){let h=t.getTokenAfter(o);if(h&&o.loc.end.line<h.loc.start.line&&r.length<=80){e.report({fix:f=>f.replaceText(s,r),message:"Ternary operator '?' should not be at end of line",node:o});return}}if(n){let h=t.getTokenAfter(n);if(h&&n.loc.end.line<h.loc.start.line&&r.length<=80){e.report({fix:f=>f.replaceText(s,r),message:"Ternary operator ':' should not be at end of line",node:n});return}}return}if(s.loc.start.line>y.loc.end.line){if((s.type==="ObjectExpression"||s.type==="ArrayExpression")&&s.loc.start.line!==s.loc.end.line)return;let i=t.getTokenAfter(y);if(i&&i.value==="(")return;e.report({fix:r=>r.replaceTextRange([y.range[1],s.range[0]]," "),message:"Property value should be on the same line as the colon",node:s})}}}},meta:{docs:{description:"Enforce property value on same line as colon with proper spacing"},fixable:"whitespace",schema:[],type:"layout"}},Bt={create(e){let t=e.sourceCode||e.getSourceCode();return{Property(I){let{key:C}=I;if(C.type!=="Literal"||typeof C.value!="string")return;let y=C.value,s=y.trim();y!==s&&s.length>0&&e.report({fix:g=>g.replaceText(C,`"${s}"`),message:`String property key should not have extra spaces inside quotes: "${s}" not "${y}"`,node:C})}}},meta:{docs:{description:"Enforce no extra spaces inside string property keys"},fixable:"code",schema:[],type:"layout"}};var Ht={create(e){let t={CALLBACK:12,CONTEXT_HOOK:8,CUSTOM_HOOK:9,DERIVED_STATE:10,EFFECT:14,HANDLER_FUNCTION:13,MEMO:11,PROPS_DESTRUCTURE:1,PROPS_DESTRUCTURE_BODY:2,REDUCER:5,REF:3,RETURN:15,ROUTER_HOOK:7,SELECTOR_DISPATCH:6,STATE:4,UNKNOWN:99},I={1:"props destructure",2:"destructured variables from props",3:"useRef",4:"useState",5:"useReducer",6:"useSelector/useDispatch",7:"router hooks",8:"context hooks",9:"custom hooks",10:"derived state/computed variables",11:"useMemo",12:"useCallback",13:"handler functions",14:"useEffect/useLayoutEffect",15:"return statement",99:"unknown"},C=new Set(["useState"]),y=new Set(["useRef"]),s=new Set(["useReducer"]),g=new Set(["useEffect","useLayoutEffect"]),i=new Set(["useMemo"]),r=new Set(["useCallback"]),l=new Set(["useSelector","useDispatch","useStore"]),o=new Set(["useNavigate","useLocation","useParams","useSearchParams","useRouter","usePathname","useMatch","useMatches","useRouteLoaderData","useNavigation","useResolvedPath","useHref","useInRouterContext","useNavigationType","useOutlet","useOutletContext","useRouteError","useRoutes","useBlocker"]),n=new Set(["useContext","useToast","useTheme","useAuth","useModal","useDialog","useNotification","useI18n","useTranslation","useIntl","useForm","useFormContext"]),h=k=>{if(!k)return!1;if(k.type==="JSXElement"||k.type==="JSXFragment")return!0;if(k.type==="BlockStatement"){for(let $ of k.body)if($.type==="ReturnStatement"&&$.argument&&h($.argument))return!0}return k.type==="ConditionalExpression"?h(k.consequent)||h(k.alternate):k.type==="LogicalExpression"?h(k.left)||h(k.right):k.type==="ParenthesizedExpression"?h(k.expression):!1},f=k=>{if(k.parent){if(k.parent.type==="VariableDeclarator"&&k.parent.id&&k.parent.id.type==="Identifier")return k.parent.id.name;if(k.id&&k.id.type==="Identifier")return k.id.name}return null},c=k=>{let $=f(k);if($&&/^[A-Z]/.test($)){let v=k.body;return h(v)}return!1},a=k=>{let $=f(k);return $&&/^use[A-Z]/.test($)?!(k.body.type!=="BlockStatement"||h(k.body)):!1},u=k=>k.type!=="CallExpression"?null:k.callee.type==="Identifier"?k.callee.name:k.callee.type==="MemberExpression"&&k.callee.property.type==="Identifier"?k.callee.property.name:null,b=k=>{let $=u(k);return $&&/^use[A-Z]/.test($)},x=k=>k&&(k.type==="ArrowFunctionExpression"||k.type==="FunctionExpression"),T=k=>{if(k.type==="VariableDeclaration"){let $=k.declarations[0];if($&&$.init&&x($.init))return $.init.type!=="CallExpression"}return k.type==="FunctionDeclaration"},m=(k,$=new Set)=>{if(k.type==="ReturnStatement")return t.RETURN;if(k.type==="ExpressionStatement"&&k.expression.type==="CallExpression"){let v=u(k.expression);if(v){if(g.has(v))return t.EFFECT;if(b(k.expression))return t.CUSTOM_HOOK}return t.UNKNOWN}if(k.type==="VariableDeclaration"){let v=k.declarations;for(let p of v)if(p.init){if(p.init.type==="CallExpression"){let d=u(p.init);if(d){if(C.has(d))return t.STATE;if(y.has(d))return t.REF;if(s.has(d))return t.REDUCER;if(l.has(d))return t.SELECTOR_DISPATCH;if(o.has(d))return t.ROUTER_HOOK;if(n.has(d))return t.CONTEXT_HOOK;if(i.has(d))return t.MEMO;if(r.has(d))return t.CALLBACK;if(b(p.init))return t.CUSTOM_HOOK}}if(x(p.init))return t.HANDLER_FUNCTION}for(let p of v)if(p.id.type==="ObjectPattern"&&p.init){if(p.init.type==="Identifier"&&$.has(p.init.name))return t.PROPS_DESTRUCTURE_BODY;if(p.init.type==="MemberExpression"){let d=p.init;for(;d.type==="MemberExpression";)d=d.object;if(d.type==="Identifier"&&$.has(d.name))return t.PROPS_DESTRUCTURE_BODY}if(p.init.type==="Identifier"&&p.init.name==="props")return t.PROPS_DESTRUCTURE}for(let p of v)if(p.init&&p.init.type==="CallExpression"){let d=p.init.callee;if(d&&d.type==="Identifier"&&!b(p.init))return t.HANDLER_FUNCTION}return t.DERIVED_STATE}return k.type==="FunctionDeclaration"?t.HANDLER_FUNCTION:t.UNKNOWN},E=(k,$)=>{let v=k.body,p=e.sourceCode||e.getSourceCode();if(v.type!=="BlockStatement")return;let d=v.body;if(d.length===0)return;let w=new Set;for(let B of k.params)if(B.type==="Identifier")w.add(B.name);else if(B.type==="ObjectPattern")for(let O of B.properties)O.type==="Property"&&O.value?O.value.type==="Identifier"?w.add(O.value.name):O.value.type==="AssignmentPattern"&&O.value.left.type==="Identifier"&&w.add(O.value.left.name):O.type==="RestElement"&&O.argument.type==="Identifier"&&w.add(O.argument.name);else if(B.type==="AssignmentPattern"&&B.left){if(B.left.type==="Identifier")w.add(B.left.name);else if(B.left.type==="ObjectPattern")for(let O of B.left.properties)O.type==="Property"&&O.value&&(O.value.type==="Identifier"?w.add(O.value.name):O.value.type==="AssignmentPattern"&&O.value.left.type==="Identifier"&&w.add(O.value.left.name))}let L=B=>B.type==="VariableDeclaration"||B.type==="FunctionDeclaration"||B.type==="ExpressionStatement"||B.type==="ReturnStatement",R=B=>{let O=new Set;if(B.type==="VariableDeclaration"){for(let X of B.declarations)if(X.id.type==="Identifier")O.add(X.id.name);else if(X.id.type==="ObjectPattern")for(let Z of X.id.properties)Z.type==="Property"&&Z.value.type==="Identifier"?O.add(Z.value.name):Z.type==="RestElement"&&Z.argument.type==="Identifier"&&O.add(Z.argument.name);else if(X.id.type==="ArrayPattern")for(let Z of X.id.elements)Z&&Z.type==="Identifier"&&O.add(Z.name)}else B.type==="FunctionDeclaration"&&B.id&&O.add(B.id.name);return O},P=(B,O=new Set)=>(B&&(B.type==="Identifier"?O.add(B.name):B.type==="MemberExpression"?P(B.object,O):B.type==="CallExpression"?(P(B.callee,O),B.arguments.forEach(X=>P(X,O))):B.type==="BinaryExpression"||B.type==="LogicalExpression"?(P(B.left,O),P(B.right,O)):B.type==="ConditionalExpression"?(P(B.test,O),P(B.consequent,O),P(B.alternate,O)):B.type==="UnaryExpression"?P(B.argument,O):B.type==="ArrayExpression"?B.elements.forEach(X=>P(X,O)):B.type==="ObjectExpression"?B.properties.forEach(X=>{X.type==="Property"&&P(X.value,O)}):B.type==="TemplateLiteral"?B.expressions.forEach(X=>P(X,O)):(B.type==="ChainExpression"||B.type==="TSAsExpression"||B.type==="TSNonNullExpression")&&P(B.expression,O)),O),H=B=>{let O=new Set;if(B.type==="VariableDeclaration")for(let X of B.declarations)X.init&&P(X.init,O);return O},F=d.filter(L);if(F.length<2)return;let M=new Map,j=new Map;for(let B=0;B<d.length;B++){let O=d[B],X=R(O);for(let Z of X)j.set(Z,B)}for(let B=0;B<d.length;B++){let O=d[B],X=R(O),Z=H(O),Q=L(O)?m(O,w):t.UNKNOWN;M.set(B,{category:Q,declared:X,dependencies:Z,index:B,statement:O})}let N=new Map;for(let B=0;B<d.length;B++){let O=M.get(B),X=new Set;for(let Z of O.dependencies){let Q=j.get(Z);Q!==void 0&&Q!==B&&X.add(Q)}N.set(B,X)}let D=!1,z=!1,q=0,_=null,Y=null,ne=null,J=null,V=null;for(let B of F){let O=m(B,w);O!==t.UNKNOWN&&(O<q&&!D&&(D=!0,_=B,Y=O,ne=q),q=O)}for(let B=0;B<d.length;B++){let O=N.get(B)||new Set;for(let X of O)if(X>B){z=!0,J=d[B];let Z=M.get(X);for(let Q of Z.declared)if(M.get(B).dependencies.has(Q)){V=Q;break}break}if(z)break}if(!D&&!z)return;let W=(()=>{let B=[],O=new Set,X=new Set,Z=K=>{if(O.has(K)||X.has(K))return;X.add(K);let re=N.get(K)||new Set;for(let ee of re)Z(ee);X.delete(K),O.add(K),B.push(K)},Q=new Map;for(let K=0;K<d.length;K++){let re=M.get(K),ee=re.category;if(ee===t.UNKNOWN){for(let oe=K+1;oe<d.length;oe++){let ue=M.get(oe);if(ue.category!==t.UNKNOWN){ee=ue.category;break}}ee===t.UNKNOWN&&(ee=t.RETURN)}let ae=N.get(K)||new Set,ce=ee;for(let oe of ae){let ge=M.get(oe).category;ge===t.UNKNOWN&&(ge=t.DERIVED_STATE),ge>ce&&(ce=ge)}let se=Math.max(ee,ce);Q.has(se)||Q.set(se,[]),Q.get(se).push({deps:ae,effectiveCategory:ee,index:K,originalCategory:re.category})}let he=[...Q.keys()].sort((K,re)=>K-re),xe=[];for(let K of he){let re=Q.get(K),ee=new Set,ae=[],ce=se=>{if(!ee.has(se.index)){ee.add(se.index);for(let oe of se.deps){let ue=re.find(ge=>ge.index===oe);ue&&!ee.has(oe)&&ce(ue)}ae.push(se.index)}};re.sort((se,oe)=>se.index-oe.index);for(let se of re)ce(se);xe.push(...ae)}return xe})();if(!W.some((B,O)=>B!==O))return;let le=B=>{let X=p.lines[d[0].loc.start.line-1].match(/^\s*/)[0],Z="",Q=null;for(let K=0;K<W.length;K++){let re=W[K],ee=M.get(re),ae=ee.category!==t.UNKNOWN?ee.category:null;Q!==null&&ae!==null&&ae!==Q&&(Z+=`
221
224
  `);let ce=p.getText(ee.statement);Z+=X+ce.trim()+`
222
- `,ae!==null&&(Q=ae)}let he=d[0],xe=d[d.length-1];return B.replaceTextRange([he.range[0],xe.range[1]],Z.trimEnd())};z&&J?e.report({data:{type:$?"hook":"component",varName:U||"variable"},fix:le,message:'"{{varName}}" is used before it is declared. Reorder statements so dependencies are declared first in {{type}}',node:J}):D&&_&&e.report({data:{current:I[Y],previous:I[ne],type:$?"hook":"component"},fix:le,message:'"{{current}}" should come before "{{previous}}" in {{type}}. Order: refs \u2192 state \u2192 redux \u2192 router \u2192 context \u2192 custom hooks \u2192 derived \u2192 useMemo \u2192 useCallback \u2192 handlers \u2192 useEffect \u2192 return',node:_})},A=(k,$)=>{let v=e.sourceCode||e.getSourceCode(),p=k;for(;p.parent;)p=p.parent;if(p.type!=="Program")return;let d=k.body;if(d.type!=="BlockStatement")return;let w=f(k);for(let L of p.body)if(L.type==="VariableDeclaration")for(let R of L.declarations){if(!R.init||!R.id||R.id.type!=="Identifier")continue;let P=R.id.name;if(!(R.init.type==="Literal"&&(typeof R.init.value=="number"||typeof R.init.value=="string"||typeof R.init.value=="boolean"))||/^[A-Z][A-Z0-9_]*$/.test(P))continue;let F=v.getText(k);if(new RegExp(`\\b${P}\\b`).test(F)){let j=N=>{let D=[],z=v.getText(R),q=L.kind;if(L.declarations.length===1){let U=v.getTokenAfter(L),V=L.range[1],W=v.text.slice(L.range[1],L.range[1]+2),G=W.startsWith(`
225
+ `,ae!==null&&(Q=ae)}let he=d[0],xe=d[d.length-1];return B.replaceTextRange([he.range[0],xe.range[1]],Z.trimEnd())};z&&J?e.report({data:{type:$?"hook":"component",varName:V||"variable"},fix:le,message:'"{{varName}}" is used before it is declared. Reorder statements so dependencies are declared first in {{type}}',node:J}):D&&_&&e.report({data:{current:I[Y],previous:I[ne],type:$?"hook":"component"},fix:le,message:'"{{current}}" should come before "{{previous}}" in {{type}}. Order: refs \u2192 state \u2192 redux \u2192 router \u2192 context \u2192 custom hooks \u2192 derived \u2192 useMemo \u2192 useCallback \u2192 handlers \u2192 useEffect \u2192 return',node:_})},A=(k,$)=>{let v=e.sourceCode||e.getSourceCode(),p=k;for(;p.parent;)p=p.parent;if(p.type!=="Program")return;let d=k.body;if(d.type!=="BlockStatement")return;let w=f(k);for(let L of p.body)if(L.type==="VariableDeclaration")for(let R of L.declarations){if(!R.init||!R.id||R.id.type!=="Identifier")continue;let P=R.id.name;if(!(R.init.type==="Literal"&&(typeof R.init.value=="number"||typeof R.init.value=="string"||typeof R.init.value=="boolean"))||/^[A-Z][A-Z0-9_]*$/.test(P))continue;let F=v.getText(k);if(new RegExp(`\\b${P}\\b`).test(F)){let j=N=>{let D=[],z=v.getText(R),q=L.kind;if(L.declarations.length===1){let V=v.getTokenAfter(L),U=L.range[1],W=v.text.slice(L.range[1],L.range[1]+2),G=W.startsWith(`
223
226
  `)?L.range[1]+1:W.startsWith(`\r
224
- `)?L.range[1]+2:L.range[1];D.push(N.removeRange([L.range[0],G]))}else{let U=L.declarations.indexOf(R);if(U===L.declarations.length-1){let W=L.declarations[U-1];D.push(N.removeRange([W.range[1],R.range[1]]))}else{let W=L.declarations[U+1];D.push(N.removeRange([R.range[0],W.range[0]]))}}let _=d.body,Y=" ";_.length>0&&(Y=v.lines[_[0].loc.start.line-1].match(/^\s*/)[0]);let ne=0;for(let U=0;U<_.length;U++){let V=_[U];if(V.type==="VariableDeclaration"){let W=V.declarations[0];if(W&&W.init){if(W.init.type==="CallExpression"){let G=W.init.callee,le=G.type==="Identifier"?G.name:G.type==="MemberExpression"&&G.property.type==="Identifier"?G.property.name:"";if(/^use[A-Z]/.test(le)){ne=U+1;continue}}if(W.init.type==="ArrowFunctionExpression"||W.init.type==="FunctionExpression")break;ne=U+1}}else if(V.type==="FunctionDeclaration")break}let J=`${Y}${q} ${z};
227
+ `)?L.range[1]+2:L.range[1];D.push(N.removeRange([L.range[0],G]))}else{let V=L.declarations.indexOf(R);if(V===L.declarations.length-1){let W=L.declarations[V-1];D.push(N.removeRange([W.range[1],R.range[1]]))}else{let W=L.declarations[V+1];D.push(N.removeRange([R.range[0],W.range[0]]))}}let _=d.body,Y=" ";_.length>0&&(Y=v.lines[_[0].loc.start.line-1].match(/^\s*/)[0]);let ne=0;for(let V=0;V<_.length;V++){let U=_[V];if(U.type==="VariableDeclaration"){let W=U.declarations[0];if(W&&W.init){if(W.init.type==="CallExpression"){let G=W.init.callee,le=G.type==="Identifier"?G.name:G.type==="MemberExpression"&&G.property.type==="Identifier"?G.property.name:"";if(/^use[A-Z]/.test(le)){ne=V+1;continue}}if(W.init.type==="ArrowFunctionExpression"||W.init.type==="FunctionExpression")break;ne=V+1}}else if(U.type==="FunctionDeclaration")break}let J=`${Y}${q} ${z};
225
228
 
226
229
  `;return ne===0&&_.length>0?D.push(N.insertTextBefore(_[0],J)):ne<_.length?D.push(N.insertTextBefore(_[ne],J)):_.length>0&&D.push(N.insertTextAfter(_[_.length-1],`
227
230
 
@@ -270,7 +273,7 @@ ${h})`;e.report({fix:u=>u.replaceTextRange([g.range[0],i.range[1]],a),message:"F
270
273
  `);return T.replaceTextRange([x.range[1],a.range[0]],E)},message:"No empty lines allowed between enum members",node:a})}}),i.length>1){let a=t.getText(f),u=a.trimEnd(),b=t.getTokenAfter(f),x=u.endsWith(",")||b&&b.value===",",T=u.endsWith(";"),m=n&&n.loc.start.line===f.loc.end.line;if(T){let E=a.lastIndexOf(";"),A=f.range[0]+E;m?e.report({fix:S=>S.replaceTextRange([A,n.range[0]],`,
271
274
  `+l),message:"Last enum member must end with comma and closing brace must be on its own line",node:f}):e.report({fix:S=>S.replaceTextRange([A,A+1],","),message:"Enum members must end with comma (,) not semicolon (;)",node:f})}else!x&&m?e.report({fix:E=>E.replaceTextRange([f.range[1],n.range[0]],`,
272
275
  `+l),message:"Last enum member must have trailing comma and closing brace must be on its own line",node:f}):x?m&&e.report({fix:E=>E.replaceTextRange([f.range[1],n.range[0]],`
273
- `+l),message:"Closing brace must be on its own line",node:n}):e.report({fix:E=>E.insertTextAfter(f,","),message:"Last enum member must have trailing comma",node:f})}}}},meta:{docs:{description:"Enforce enum naming (PascalCase + Enum suffix), UPPER_CASE members, proper formatting, and trailing commas"},fixable:"code",schema:[],type:"suggestion"}},Vt={create(e){let t=e.sourceCode||e.getSourceCode(),I=/^[A-Z][a-zA-Z0-9]*$/,C=/^[a-z][a-zA-Z0-9]*$/,y=s=>/^[A-Z][A-Z0-9_]*$/.test(s)?s.toLowerCase().replace(/_([a-z0-9])/g,(g,i)=>i.toUpperCase()):/_/.test(s)?s.toLowerCase().replace(/_([a-z0-9])/g,(g,i)=>i.toUpperCase()):/^[A-Z]/.test(s)?s[0].toLowerCase()+s.slice(1):s;return{TSInterfaceDeclaration(s){let g=s.id.name;I.test(g)?g.endsWith("Interface")||e.report({fix(a){return a.replaceText(s.id,`${g}Interface`)},message:`Interface name "${g}" must end with "Interface" suffix. Use "${g}Interface" instead of "${g}"`,node:s.id}):e.report({message:`Interface name "${g}" must be PascalCase`,node:s.id});let i=t.getFirstToken(s.body);i&&i.loc.start.line!==s.id.loc.end.line&&e.report({fix:a=>a.replaceTextRange([s.id.range[1],i.range[0]]," "),message:"Opening brace must be on the same line as interface name",node:i});let r=s.body.body;if(r.length===0)return;let o=t.lines[s.loc.start.line-1].match(/^\s*/)[0],n=o+" ",h=t.getLastToken(s.body),f=r[0];f.loc.start.line-i.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([i.range[1],f.range[0]],`
276
+ `+l),message:"Closing brace must be on its own line",node:n}):e.report({fix:E=>E.insertTextAfter(f,","),message:"Last enum member must have trailing comma",node:f})}}}},meta:{docs:{description:"Enforce enum naming (PascalCase + Enum suffix), UPPER_CASE members, proper formatting, and trailing commas"},fixable:"code",schema:[],type:"suggestion"}},Ut={create(e){let t=e.sourceCode||e.getSourceCode(),I=/^[A-Z][a-zA-Z0-9]*$/,C=/^[a-z][a-zA-Z0-9]*$/,y=s=>/^[A-Z][A-Z0-9_]*$/.test(s)?s.toLowerCase().replace(/_([a-z0-9])/g,(g,i)=>i.toUpperCase()):/_/.test(s)?s.toLowerCase().replace(/_([a-z0-9])/g,(g,i)=>i.toUpperCase()):/^[A-Z]/.test(s)?s[0].toLowerCase()+s.slice(1):s;return{TSInterfaceDeclaration(s){let g=s.id.name;I.test(g)?g.endsWith("Interface")||e.report({fix(a){return a.replaceText(s.id,`${g}Interface`)},message:`Interface name "${g}" must end with "Interface" suffix. Use "${g}Interface" instead of "${g}"`,node:s.id}):e.report({message:`Interface name "${g}" must be PascalCase`,node:s.id});let i=t.getFirstToken(s.body);i&&i.loc.start.line!==s.id.loc.end.line&&e.report({fix:a=>a.replaceTextRange([s.id.range[1],i.range[0]]," "),message:"Opening brace must be on the same line as interface name",node:i});let r=s.body.body;if(r.length===0)return;let o=t.lines[s.loc.start.line-1].match(/^\s*/)[0],n=o+" ",h=t.getLastToken(s.body),f=r[0];f.loc.start.line-i.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([i.range[1],f.range[0]],`
274
277
  `+n),message:"No empty line after opening brace in interface",node:f});let c=r[r.length-1];if(h.loc.start.line-c.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([c.range[1],h.range[0]],`
275
278
  `+o),message:"No empty line before closing brace in interface",node:c}),r.length===1){let a=r[0],u=i.loc.end.line!==h.loc.start.line,b=a.typeAnnotation?.typeAnnotation,x=b?.type==="TSTypeLiteral",T=x&&b.members?.length>=2,m=x&&b.members?.length===1,E=b?.type==="TSFunctionType"&&b.loc.start.line!==b.loc.end.line;if(u&&!T&&!E){let S;if(m){let $=b.members[0],v=t.getText($).trim();(v.endsWith(",")||v.endsWith(";"))&&(v=v.slice(0,-1));let p=a.key.name,d=a.optional?"?":"";S=`${p}${d}: { ${v} }`}else S=t.getText(a).trim(),(S.endsWith(",")||S.endsWith(";"))&&(S=S.slice(0,-1));let k=`{ ${S} }`;e.report({fix:$=>$.replaceTextRange([i.range[0],h.range[1]],k),message:"Single property interface should be on one line without trailing punctuation",node:s});return}let A=t.getText(a);if(A.trimEnd().endsWith(",")||A.trimEnd().endsWith(";")){let S=Math.max(A.lastIndexOf(","),A.lastIndexOf(";"));e.report({fix:k=>k.removeRange([a.range[0]+S,a.range[0]+S+1]),message:"Single property interface should not have trailing punctuation",node:a})}return}if(f.loc.start.line===i.loc.end.line&&e.report({fix:a=>a.replaceTextRange([i.range[1],f.range[0]],`
276
279
  `+n),message:"First interface property must be on a new line when there are multiple properties",node:f}),r.forEach((a,u)=>{if(a.type==="TSPropertySignature"&&a.key&&a.key.type==="Identifier"){let x=a.key.name;if(!C.test(x)){let T=y(x);e.report({fix:m=>m.replaceText(a.key,T),message:`Interface property "${x}" must be camelCase. Use "${T}" instead.`,node:a.key})}}if(a.type==="TSPropertySignature"&&a.typeAnnotation?.typeAnnotation?.type==="TSTypeLiteral"){let x=a.typeAnnotation.typeAnnotation;if(x.members&&x.members.length===1){let T=t.getFirstToken(x),m=t.getLastToken(x);if(T.loc.end.line!==m.loc.start.line){let A=x.members[0],S=t.getText(A).trim();(S.endsWith(",")||S.endsWith(";"))&&(S=S.slice(0,-1)),e.report({fix:k=>k.replaceTextRange([T.range[0],m.range[1]],`{ ${S} }`),message:"Single property nested object type should be on one line",node:x})}}}if(a.type==="TSPropertySignature"&&a.optional){let x=t.getFirstToken(a),T=t.getTokenAfter(x);T&&T.value==="?"&&t.getText().slice(x.range[1],T.range[0])!==""&&e.report({fix:E=>E.replaceTextRange([x.range[1],T.range[0]],""),message:'No space allowed before "?" in optional property',node:a})}if(!(u===r.length-1)||r.length===1){let x=t.getText(a);x.trimEnd().endsWith(";")&&e.report({fix(T){let m=x.lastIndexOf(";"),E=a.range[0]+m;return T.replaceTextRange([E,E+1],",")},message:"Interface properties must end with comma (,) not semicolon (;)",node:a})}if(r.length>1&&u>0){let x=r[u-1];a.loc.start.line===x.loc.end.line&&e.report({fix:T=>{let m=t.getTokenAfter(x);for(;m&&m.value!==","&&m.range[0]<a.range[0];)m=t.getTokenAfter(m);let E=m&&m.value===","?m.range[1]:x.range[1];return T.replaceTextRange([E,a.range[0]],`
@@ -278,4 +281,4 @@ ${h})`;e.report({fix:u=>u.replaceTextRange([g.range[0],i.range[1]],a),message:"F
278
281
  `);return T.replaceTextRange([x.range[1],a.range[0]],E)},message:"No empty lines allowed between interface properties",node:a})}}),r.length>1){let a=t.getText(c),u=a.trimEnd(),b=t.getTokenAfter(c),x=u.endsWith(",")||b&&b.value===",",T=u.endsWith(";"),m=h.loc.start.line===c.loc.end.line;if(T){let E=a.lastIndexOf(";"),A=c.range[0]+E;m?e.report({fix:S=>S.replaceTextRange([A,h.range[0]],`,
279
282
  `+o),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([A,A+1],","),message:"Interface properties must end with comma (,) not semicolon (;)",node:c})}else!x&&m?e.report({fix:E=>E.replaceTextRange([c.range[1],h.range[0]],`,
280
283
  `+o),message:"Last interface property must have trailing comma and closing brace must be on its own line",node:c}):x?m&&e.report({fix:E=>E.replaceTextRange([c.range[1],h.range[0]],`
281
- `+o),message:"Closing brace must be on its own line",node:h}):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"}},Ut={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/"),C=s=>new RegExp(`/${s}/[^/]+\\.(ts|tsx)$`).test(I),y=()=>/\.(ts|tsx)$/.test(I);return{TSInterfaceDeclaration(s){y()&&(C("interfaces")||e.report({message:'Interfaces must be declared in files inside the "interfaces" folder',node:s.id||s}))},TSEnumDeclaration(s){y()&&(C("enums")||e.report({message:'Enums must be declared in files inside the "enums" folder',node:s.id||s}))},TSTypeAliasDeclaration(s){y()&&(C("types")||e.report({message:'Type aliases must be declared in files inside the "types" folder',node:s.id||s}))}}},meta:{docs:{description:"Enforce that interfaces are in interfaces folder, enums in enums folder, and types in types folder"},schema:[],type:"suggestion"}};var _t={create(e){let t=e.sourceCode||e.getSourceCode(),I=/^[a-z][a-zA-Z0-9]*$/,C=/^[A-Z][a-zA-Z0-9]*$/,y=/^use[A-Z][a-zA-Z0-9]*$/,s=/^[A-Z][A-Z0-9_]*$/,g=m=>/^[A-Z][A-Z0-9_]*$/.test(m)?m.toLowerCase().replace(/_([a-z0-9])/g,(E,A)=>A.toUpperCase()):/_/.test(m)?m.toLowerCase().replace(/_([a-z0-9])/g,(E,A)=>A.toUpperCase()):/^[A-Z]/.test(m)?m[0].toLowerCase()+m.slice(1):m,i=m=>{let A=(t.getScope?t.getScope(m):e.getScope()).variables.find(S=>S.name===m.name);return A?A.references.map(S=>S.identifier):[]},r=["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=m=>{if(!m||m.type!=="CallExpression")return!1;let{callee:E}=m;if(E.type==="CallExpression"){let A=E.callee;if(A.type==="Identifier"&&A.name==="styled"||A.type==="MemberExpression"&&A.object.name==="styled")return!0}return!1},o=m=>{if(m.type!=="CallExpression")return!1;let{callee:E}=m;return E.type==="Identifier"&&E.name==="styled"},n=m=>{if(!m)return!1;if(m.type==="ArrowFunctionExpression"||m.type==="FunctionExpression")return!0;if(m.type==="CallExpression"&&m.callee){let E=m.callee.name||m.callee.property&&m.callee.property.name;return["memo","forwardRef","lazy","createContext"].includes(E)}return!1},h=m=>{if(!m.init)return!1;let E=m.id.name;if(/^[A-Z]/.test(E)&&n(m.init)||/^[A-Z]/.test(E)&&m.init.type==="MemberExpression"&&m.init.object.type==="Identifier"&&/^[A-Z]/.test(m.init.object.name))return!0;if(/^[A-Z]/.test(E)&&m.init.type==="ConditionalExpression"){let{consequent:A,alternate:S}=m.init,k=$=>$.type==="Identifier"&&/^[A-Z]/.test($.name)||$.type==="Literal"&&typeof $.value=="string"||$.type==="MemberExpression"&&$.object.type==="Identifier"&&/^[A-Z]/.test($.object.name);if(k(A)||k(S))return!0}return!1},f=m=>{if(!m.init)return!1;let E=m.id.name;return E.startsWith("use")&&/^use[A-Z]/.test(E)&&n(m.init)},c=["Icon","Component","FormComponent","Layout","Wrapper","Container","Provider"],a=(m,E)=>{if(m.type==="Identifier"){let A=m.name;if(A.startsWith("_")||s.test(A)||r.includes(A)||c.includes(A))return;I.test(A)||e.report({message:`${E} "${A}" should be camelCase`,node:m})}else m.type==="ObjectPattern"?m.properties.forEach(A=>{A.type==="Property"?a(A.value,E):A.type==="RestElement"&&a(A.argument,E)}):m.type==="ArrayPattern"?m.elements.forEach(A=>{A&&a(A,E)}):m.type==="AssignmentPattern"?a(m.left,E):m.type==="RestElement"&&a(m.argument,E)},u=m=>{if(m.id.type!=="Identifier"){a(m.id,"Variable");return}let E=m.id.name;if(l(m.init)){C.test(E)||e.report({message:`Styled component "${E}" should be PascalCase (e.g., StyledCard instead of styledCard)`,node:m.id});return}if(E.startsWith("_")||h(m))return;let A=["Component","Icon","Layout","Wrapper","Container","Provider","View","Screen","Page"];if(C.test(E)&&A.some(k=>E.endsWith(k)))return;if(f(m)){y.test(E)||e.report({message:`Hook "${E}" should start with "use" followed by PascalCase (e.g., useEventsList)`,node:m.id});return}if(!([/^[A-Z][a-zA-Z]*Data$/,/^[A-Z][a-zA-Z]*Config$/,/^Routes$/].some(k=>k.test(E))&&m.init&&(m.init.type==="ArrayExpression"||m.init.type==="ObjectExpression"||m.init.type==="CallExpression"))&&!I.test(E)){let k=g(E),$=i(m.id);e.report({fix:v=>{let p=[];return $.forEach(d=>{p.push(v.replaceText(d,k))}),p},message:`Variable "${E}" should be camelCase (e.g., ${k} instead of ${E})`,node:m.id})}},b=m=>{if(m.computed||m.key.type!=="Identifier")return;let E=m.key.name;if(!(E.startsWith("_")||r.includes(E))){if(m.value&&m.value.type==="Identifier"){let A=m.value.name;if(C.test(A)&&C.test(E))return}if(!c.includes(E)&&!E.startsWith("Mui")&&!I.test(E)){let A=g(E);e.report({fix:S=>S.replaceText(m.key,A),message:`Property "${E}" should be camelCase (e.g., ${A} instead of ${E})`,node:m.key})}}},x=m=>{m.params.forEach(E=>a(E,"Parameter"))};return{ArrowFunctionExpression:x,CallExpression:m=>{o(m)||m.arguments.forEach(E=>{if(E.type==="Identifier"){let A=E.name;if(A.startsWith("_")||s.test(A)||r.includes(A)||c.includes(A)||C.test(A))return;if(!I.test(A)){let S=g(A);e.report({fix(k){let $=t.getScope?t.getScope(E):e.getScope(),v=$.variables.find(w=>w.name===A)||$.upper&&$.upper.variables.find(w=>w.name===A);if(!v)return k.replaceText(E,S);let p=[],d=new Set;return v.references.forEach(w=>{let L=`${w.identifier.range[0]}-${w.identifier.range[1]}`;d.has(L)||(d.add(L),p.push(k.replaceText(w.identifier,S)))}),p},message:`Argument "${A}" should be camelCase (e.g., ${S} instead of ${A})`,node:E})}}})},FunctionDeclaration:x,FunctionExpression:x,Property:b,VariableDeclarator:u}},meta:{docs:{description:"Enforce naming conventions: camelCase for variables/properties/params/arguments, PascalCase for components, useXxx for hooks"},fixable:"code",schema:[],type:"suggestion"}};var Mn={meta:{name:"eslint-plugin-code-style",version:"2.0.14"},rules:{"array-callback-destructure":Se,"array-items-per-line":Ee,"array-objects-on-new-lines":we,"arrow-function-block-body":ve,"arrow-function-simple-jsx":Ce,"arrow-function-simplify":Ae,"curried-arrow-same-line":$e,"function-arguments-format":Le,"nested-call-closing-brackets":Ie,"no-empty-lines-in-function-calls":Re,"opening-brackets-same-line":Pe,"simple-call-single-line":Fe,"single-argument-on-one-line":Be,"comment-format":Oe,"component-props-destructure":Ne,"component-props-inline-type":De,"folder-based-naming-convention":Xe,"folder-structure-consistency":ze,"no-redundant-folder-suffix":We,"svg-icon-naming-convention":Je,"react-code-order":Ht,"block-statement-newlines":Ve,"empty-line-after-block":Ge,"if-else-spacing":_e,"if-statement-format":Ue,"logical-expression-multiline":Ke,"multiline-if-conditions":qe,"no-empty-lines-in-switch-cases":Ye,"ternary-condition-multiline":Ze,"class-method-definition-format":je,"class-naming-convention":He,"function-call-spacing":Qe,"function-declaration-style":et,"function-naming-convention":tt,"function-object-destructure":st,"function-params-per-line":nt,"no-empty-lines-in-function-params":rt,"hook-callback-format":it,"hook-deps-per-line":at,"use-state-naming-convention":ot,"absolute-imports-only":lt,"export-format":ct,"import-format":pt,"import-source-spacing":ft,"index-export-style":gt,"index-exports-only":mt,"inline-export-declaration":dt,"module-index-exports":ut,"classname-dynamic-at-end":St,"classname-multiline":Ct,"classname-no-extra-spaces":wt,"classname-order":vt,"jsx-children-on-new-line":yt,"jsx-closing-bracket-spacing":ht,"jsx-element-child-new-line":xt,"jsx-logical-expression-simplify":Tt,"jsx-parentheses-position":bt,"jsx-prop-naming-convention":kt,"jsx-simple-element-one-line":Et,"jsx-string-value-trim":At,"jsx-ternary-format":$t,"no-empty-lines-in-jsx":Lt,"no-empty-lines-in-objects":It,"object-property-per-line":Rt,"object-property-value-brace":Pt,"object-property-value-format":Ft,"string-property-spacing":Bt,"assignment-value-same-line":jt,"member-expression-bracket-spacing":Ot,"enum-format":Wt,"enum-type-enforcement":Nt,"interface-format":Vt,"no-inline-type-definitions":Jt,"prop-naming-convention":Dt,"type-annotation-spacing":zt,"type-format":Xt,"typescript-definition-location":Ut,"no-hardcoded-strings":Mt,"variable-naming-convention":_t}};export{Mn as default};
284
+ `+o),message:"Closing brace must be on its own line",node:h}):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"}},Vt={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/"),C=s=>new RegExp(`/${s}/[^/]+\\.(ts|tsx)$`).test(I),y=()=>/\.(ts|tsx)$/.test(I);return{TSInterfaceDeclaration(s){y()&&(C("interfaces")||e.report({message:'Interfaces must be declared in files inside the "interfaces" folder',node:s.id||s}))},TSEnumDeclaration(s){y()&&(C("enums")||e.report({message:'Enums must be declared in files inside the "enums" folder',node:s.id||s}))},TSTypeAliasDeclaration(s){y()&&(C("types")||e.report({message:'Type aliases must be declared in files inside the "types" folder',node:s.id||s}))}}},meta:{docs:{description:"Enforce that interfaces are in interfaces folder, enums in enums folder, and types in types folder"},schema:[],type:"suggestion"}};var _t={create(e){let t=e.sourceCode||e.getSourceCode(),I=/^[a-z][a-zA-Z0-9]*$/,C=/^[A-Z][a-zA-Z0-9]*$/,y=/^use[A-Z][a-zA-Z0-9]*$/,s=/^[A-Z][A-Z0-9_]*$/,g=m=>/^[A-Z][A-Z0-9_]*$/.test(m)?m.toLowerCase().replace(/_([a-z0-9])/g,(E,A)=>A.toUpperCase()):/_/.test(m)?m.toLowerCase().replace(/_([a-z0-9])/g,(E,A)=>A.toUpperCase()):/^[A-Z]/.test(m)?m[0].toLowerCase()+m.slice(1):m,i=m=>{let A=(t.getScope?t.getScope(m):e.getScope()).variables.find(S=>S.name===m.name);return A?A.references.map(S=>S.identifier):[]},r=["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=m=>{if(!m||m.type!=="CallExpression")return!1;let{callee:E}=m;if(E.type==="CallExpression"){let A=E.callee;if(A.type==="Identifier"&&A.name==="styled"||A.type==="MemberExpression"&&A.object.name==="styled")return!0}return!1},o=m=>{if(m.type!=="CallExpression")return!1;let{callee:E}=m;return E.type==="Identifier"&&E.name==="styled"},n=m=>{if(!m)return!1;if(m.type==="ArrowFunctionExpression"||m.type==="FunctionExpression")return!0;if(m.type==="CallExpression"&&m.callee){let E=m.callee.name||m.callee.property&&m.callee.property.name;return["memo","forwardRef","lazy","createContext"].includes(E)}return!1},h=m=>{if(!m.init)return!1;let E=m.id.name;if(/^[A-Z]/.test(E)&&n(m.init)||/^[A-Z]/.test(E)&&m.init.type==="MemberExpression"&&m.init.object.type==="Identifier"&&/^[A-Z]/.test(m.init.object.name))return!0;if(/^[A-Z]/.test(E)&&m.init.type==="ConditionalExpression"){let{consequent:A,alternate:S}=m.init,k=$=>$.type==="Identifier"&&/^[A-Z]/.test($.name)||$.type==="Literal"&&typeof $.value=="string"||$.type==="MemberExpression"&&$.object.type==="Identifier"&&/^[A-Z]/.test($.object.name);if(k(A)||k(S))return!0}return!1},f=m=>{if(!m.init)return!1;let E=m.id.name;return E.startsWith("use")&&/^use[A-Z]/.test(E)&&n(m.init)},c=["Icon","Component","FormComponent","Layout","Wrapper","Container","Provider"],a=(m,E)=>{if(m.type==="Identifier"){let A=m.name;if(A.startsWith("_")||s.test(A)||r.includes(A)||c.includes(A))return;I.test(A)||e.report({message:`${E} "${A}" should be camelCase`,node:m})}else m.type==="ObjectPattern"?m.properties.forEach(A=>{A.type==="Property"?a(A.value,E):A.type==="RestElement"&&a(A.argument,E)}):m.type==="ArrayPattern"?m.elements.forEach(A=>{A&&a(A,E)}):m.type==="AssignmentPattern"?a(m.left,E):m.type==="RestElement"&&a(m.argument,E)},u=m=>{if(m.id.type!=="Identifier"){a(m.id,"Variable");return}let E=m.id.name;if(l(m.init)){C.test(E)||e.report({message:`Styled component "${E}" should be PascalCase (e.g., StyledCard instead of styledCard)`,node:m.id});return}if(E.startsWith("_")||h(m))return;let A=["Component","Icon","Layout","Wrapper","Container","Provider","View","Screen","Page"];if(C.test(E)&&A.some(k=>E.endsWith(k)))return;if(f(m)){y.test(E)||e.report({message:`Hook "${E}" should start with "use" followed by PascalCase (e.g., useEventsList)`,node:m.id});return}if(!([/^[A-Z][a-zA-Z]*Data$/,/^[A-Z][a-zA-Z]*Config$/,/^Routes$/].some(k=>k.test(E))&&m.init&&(m.init.type==="ArrayExpression"||m.init.type==="ObjectExpression"||m.init.type==="CallExpression"))&&!I.test(E)){let k=g(E),$=i(m.id);e.report({fix:v=>{let p=[];return $.forEach(d=>{p.push(v.replaceText(d,k))}),p},message:`Variable "${E}" should be camelCase (e.g., ${k} instead of ${E})`,node:m.id})}},b=m=>{if(m.computed||m.key.type!=="Identifier")return;let E=m.key.name;if(!(E.startsWith("_")||r.includes(E))){if(m.value&&m.value.type==="Identifier"){let A=m.value.name;if(C.test(A)&&C.test(E))return}if(!c.includes(E)&&!E.startsWith("Mui")&&!I.test(E)){let A=g(E);e.report({fix:S=>S.replaceText(m.key,A),message:`Property "${E}" should be camelCase (e.g., ${A} instead of ${E})`,node:m.key})}}},x=m=>{m.params.forEach(E=>a(E,"Parameter"))};return{ArrowFunctionExpression:x,CallExpression:m=>{o(m)||m.arguments.forEach(E=>{if(E.type==="Identifier"){let A=E.name;if(A.startsWith("_")||s.test(A)||r.includes(A)||c.includes(A)||C.test(A))return;if(!I.test(A)){let S=g(A);e.report({fix(k){let $=t.getScope?t.getScope(E):e.getScope(),v=$.variables.find(w=>w.name===A)||$.upper&&$.upper.variables.find(w=>w.name===A);if(!v)return k.replaceText(E,S);let p=[],d=new Set;return v.references.forEach(w=>{let L=`${w.identifier.range[0]}-${w.identifier.range[1]}`;d.has(L)||(d.add(L),p.push(k.replaceText(w.identifier,S)))}),p},message:`Argument "${A}" should be camelCase (e.g., ${S} instead of ${A})`,node:E})}}})},FunctionDeclaration:x,FunctionExpression:x,Property:b,VariableDeclarator:u}},meta:{docs:{description:"Enforce naming conventions: camelCase for variables/properties/params/arguments, PascalCase for components, useXxx for hooks"},fixable:"code",schema:[],type:"suggestion"}};var Mn={meta:{name:"eslint-plugin-code-style",version:"2.0.16"},rules:{"array-callback-destructure":Se,"array-items-per-line":Ee,"array-objects-on-new-lines":we,"arrow-function-block-body":ve,"arrow-function-simple-jsx":Ce,"arrow-function-simplify":Ae,"curried-arrow-same-line":$e,"function-arguments-format":Le,"nested-call-closing-brackets":Ie,"no-empty-lines-in-function-calls":Re,"opening-brackets-same-line":Pe,"simple-call-single-line":Fe,"single-argument-on-one-line":Be,"comment-format":Oe,"component-props-destructure":Ne,"component-props-inline-type":De,"folder-based-naming-convention":Xe,"folder-structure-consistency":ze,"no-redundant-folder-suffix":We,"svg-icon-naming-convention":Je,"react-code-order":Ht,"block-statement-newlines":Ue,"empty-line-after-block":Ge,"if-else-spacing":_e,"if-statement-format":Ve,"logical-expression-multiline":Ke,"multiline-if-conditions":qe,"no-empty-lines-in-switch-cases":Ye,"ternary-condition-multiline":Ze,"class-method-definition-format":je,"class-naming-convention":He,"function-call-spacing":Qe,"function-declaration-style":et,"function-naming-convention":tt,"function-object-destructure":st,"function-params-per-line":nt,"no-empty-lines-in-function-params":rt,"hook-callback-format":it,"hook-deps-per-line":at,"use-state-naming-convention":ot,"absolute-imports-only":lt,"export-format":ct,"import-format":pt,"import-source-spacing":ft,"index-export-style":gt,"index-exports-only":mt,"inline-export-declaration":dt,"module-index-exports":ut,"classname-dynamic-at-end":St,"classname-multiline":Ct,"classname-no-extra-spaces":wt,"classname-order":vt,"jsx-children-on-new-line":yt,"jsx-closing-bracket-spacing":ht,"jsx-element-child-new-line":xt,"jsx-logical-expression-simplify":Tt,"jsx-parentheses-position":bt,"jsx-prop-naming-convention":kt,"jsx-simple-element-one-line":Et,"jsx-string-value-trim":At,"jsx-ternary-format":$t,"no-empty-lines-in-jsx":Lt,"no-empty-lines-in-objects":It,"object-property-per-line":Rt,"object-property-value-brace":Pt,"object-property-value-format":Ft,"string-property-spacing":Bt,"assignment-value-same-line":jt,"member-expression-bracket-spacing":Ot,"enum-format":Wt,"enum-type-enforcement":Nt,"interface-format":Ut,"no-inline-type-definitions":Jt,"prop-naming-convention":Dt,"type-annotation-spacing":zt,"type-format":Xt,"typescript-definition-location":Vt,"no-hardcoded-strings":Mt,"variable-naming-convention":_t}};export{Mn as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-code-style",
3
- "version": "2.0.14",
3
+ "version": "2.0.16",
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",