eslint-plugin-code-style 2.0.16 → 2.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +216 -216
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,284 +1,284 @@
|
|
|
1
|
-
var Ee={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxItems!==void 0?I.maxItems:3;return{ArrayExpression(y){let{elements:s}=y;if(s.length===0)return;if(y.parent&&y.parent.type==="CallExpression"&&y.parent.callee&&y.parent.callee.type==="Identifier"&&/^use[A-Z]/.test(y.parent.callee.name)){let
|
|
2
|
-
`+h),message:"No empty line after opening bracket",node:
|
|
3
|
-
`+h),message:"First array item should be on its own line",node:
|
|
4
|
-
`+h),message:"Each array item should be on its own line",node:u}):u.loc.start.line>a.loc.end.line+1&&
|
|
5
|
-
`+h),message:"No empty lines between array items",node:u})}let f=t.getTokenBefore(r);if(r.loc.start.line>o.loc.end.line+1){let
|
|
1
|
+
var Ee={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxItems!==void 0?I.maxItems:3;return{ArrayExpression(y){let{elements:s}=y;if(s.length===0)return;if(y.parent&&y.parent.type==="CallExpression"&&y.parent.callee&&y.parent.callee.type==="Identifier"&&/^use[A-Z]/.test(y.parent.callee.name)){let l=y.parent.arguments;if(l[l.length-1]===y)return}if(s.some(l=>l?l.type==="SpreadElement"||l.type==="ObjectExpression"||l.type==="ArrayExpression"||l.type==="ArrowFunctionExpression"||l.type==="FunctionExpression":!1))return;let i=t.getFirstToken(y),r=t.getLastToken(y);if(!i||!r)return;let c=s[0],o=s[s.length-1];if(!c||!o)return;if(y.parent&&y.parent.type==="Property"){let l=t.getTokenBefore(y);l&&l.value===":"&&i.loc.start.line!==l.loc.end.line&&e.report({fix:a=>a.replaceTextRange([l.range[1],i.range[0]]," "),message:"Array should start on same line as property key",node:i})}let n="";y.parent&&y.parent.type==="Property"?n=t.lines[y.parent.loc.start.line-1].match(/^\s*/)[0]:n=t.lines[y.loc.start.line-1].match(/^\s*/)[0];let h=n+" ";if(s.length<=C){if(!(y.loc.start.line!==y.loc.end.line)){let T=t.text.slice(i.range[1],c.range[0]),x=t.text.slice(o.range[1],r.range[0]),b=T.length>0,d=x.includes(" ");if(b||d){let E=s.filter(A=>A!==null).map(A=>t.getText(A)).join(", ");e.report({fix:A=>A.replaceText(y,`[${E}]`),message:"No spaces inside array brackets",node:y})}return}let u=`[${s.filter(T=>T!==null).map(T=>t.getText(T)).join(", ")}]`;u.length<=100&&e.report({fix:T=>T.replaceText(y,u),message:`Array with \u2264${C} simple items should be single line: [a, b, c]. Multi-line only for >${C} items or complex values`,node:y});return}c.loc.start.line>i.loc.end.line+1?e.report({fix:l=>l.replaceTextRange([i.range[1],c.range[0]],`
|
|
2
|
+
`+h),message:"No empty line after opening bracket",node:c}):i.loc.end.line===c.loc.start.line&&e.report({fix:l=>l.replaceTextRange([i.range[1],c.range[0]],`
|
|
3
|
+
`+h),message:"First array item should be on its own line",node:c});for(let l=0;l<s.length-1;l+=1){let a=s[l],u=s[l+1];if(!a||!u)continue;let T=t.getTokenAfter(a,x=>x.value===",");a.loc.end.line===u.loc.start.line?T&&e.report({fix:x=>x.replaceTextRange([T.range[1],u.range[0]],`
|
|
4
|
+
`+h),message:"Each array item should be on its own line",node:u}):u.loc.start.line>a.loc.end.line+1&&T&&e.report({fix:x=>x.replaceTextRange([T.range[1],u.range[0]],`
|
|
5
|
+
`+h),message:"No empty lines between array items",node:u})}let f=t.getTokenBefore(r);if(r.loc.start.line>o.loc.end.line+1){let l=f&&f.value===",";e.report({fix:a=>l?a.replaceTextRange([f.range[1],r.range[0]],`
|
|
6
6
|
`+n):a.replaceTextRange([o.range[1],r.range[0]],`,
|
|
7
|
-
`+n),message:"No empty line before closing bracket",node:r})}else if(r.loc.start.line===o.loc.end.line){let
|
|
7
|
+
`+n),message:"No empty line before closing bracket",node:r})}else if(r.loc.start.line===o.loc.end.line){let l=f&&f.value===",";e.report({fix:a=>l?a.replaceTextRange([f.range[1],r.range[0]],`
|
|
8
8
|
`+n):a.replaceTextRange([o.range[1],r.range[0]],`,
|
|
9
|
-
`+n),message:"Closing bracket should be on its own line",node:r})}}}},meta:{docs:{description:"Enforce array formatting based on item count (default: \u22643 on one line, >3 each on new line)"},fixable:"code",schema:[{additionalProperties:!1,properties:{maxItems:{default:3,description:"Maximum items to keep on single line (default: 3)",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},Se={create(e){let t=e.sourceCode||e.getSourceCode(),I=["map","filter","find","findIndex","findLast","findLastIndex","some","every","forEach","reduce","reduceRight","flatMap","sort","toSorted"],C=(y,s)=>{if(y.type!=="ObjectPattern")return;let g=y.properties.filter(f=>f.type==="Property");if(g.length<2)return;let i=g[0],r=g[g.length-1],
|
|
10
|
-
`);return f.replaceTextRange([
|
|
9
|
+
`+n),message:"Closing bracket should be on its own line",node:r})}}}},meta:{docs:{description:"Enforce array formatting based on item count (default: \u22643 on one line, >3 each on new line)"},fixable:"code",schema:[{additionalProperties:!1,properties:{maxItems:{default:3,description:"Maximum items to keep on single line (default: 3)",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},Se={create(e){let t=e.sourceCode||e.getSourceCode(),I=["map","filter","find","findIndex","findLast","findLastIndex","some","every","forEach","reduce","reduceRight","flatMap","sort","toSorted"],C=(y,s)=>{if(y.type!=="ObjectPattern")return;let g=y.properties.filter(f=>f.type==="Property");if(g.length<2)return;let i=g[0],r=g[g.length-1],c=t.getLastToken(y),n=t.lines[s.loc.start.line-1].match(/^\s*/)[0],h=n+" ";if(i.loc.start.line===r.loc.end.line){e.report({fix(f){let l=t.getFirstToken(y),a=g.map(u=>h+t.getText(u)).join(`,
|
|
10
|
+
`);return f.replaceTextRange([l.range[0],c.range[1]],`{
|
|
11
11
|
${a},
|
|
12
|
-
${n} }`)},message:"Destructured properties in array callback should each be on their own line when there are 2 or more properties",node:y});return}
|
|
13
|
-
`+n+" "):f.replaceTextRange([r.range[1],
|
|
14
|
-
`+n+" ")},message:"Closing brace should be on its own line in multiline destructuring",node:
|
|
15
|
-
`+o),message:"First object in array should start on a new line",node:g})}let i=t.getLastToken(I),r=C[C.length-1];if(r&&r.type==="ObjectExpression"){let
|
|
12
|
+
${n} }`)},message:"Destructured properties in array callback should each be on their own line when there are 2 or more properties",node:y});return}c.loc.start.line===r.loc.end.line&&e.report({fix(f){let l=t.getTokenBefore(c);return l.value===","?f.replaceTextRange([l.range[1],c.range[0]],`
|
|
13
|
+
`+n+" "):f.replaceTextRange([r.range[1],c.range[0]],`,
|
|
14
|
+
`+n+" ")},message:"Closing brace should be on its own line in multiline destructuring",node:c})};return{CallExpression(y){if(y.callee.type!=="MemberExpression")return;let s=y.callee.property&&y.callee.property.name;if(!I.includes(s))return;let g=y.arguments[0];g&&(g.type==="ArrowFunctionExpression"||g.type==="FunctionExpression")&&g.params.forEach(i=>{C(i,y)})}}},meta:{docs:{description:"Enforce multiline destructuring in array method callbacks (map, filter, find, etc.) when there are 2+ properties"},fixable:"code",schema:[],type:"layout"}},we={create(e){let t=e.sourceCode||e.getSourceCode();return{ArrayExpression(I){let C=I.elements;if(C.length===0||C.filter(c=>c&&c.type==="ObjectExpression").length===0||I.loc.start.line===I.loc.end.line)return;let s=t.getFirstToken(I),g=C[0];if(g&&g.type==="ObjectExpression"&&s.loc.end.line===g.loc.start.line){let c=t.getFirstToken(g),o=" ".repeat(s.loc.start.column+4);e.report({fix:n=>n.replaceTextRange([s.range[1],c.range[0]],`
|
|
15
|
+
`+o),message:"First object in array should start on a new line",node:g})}let i=t.getLastToken(I),r=C[C.length-1];if(r&&r.type==="ObjectExpression"){let c=t.getLastToken(r),o=t.getTokenAfter(c),n=o;if(o&&o.value===","&&(n=t.getTokenAfter(o)),c.loc.end.line===i.loc.start.line){let h=" ".repeat(s.loc.start.column);e.report({fix:f=>t.text.slice(r.range[1],i.range[0]).includes(",")?f.replaceTextRange([r.range[1],i.range[0]],`,
|
|
16
16
|
`+h):f.replaceTextRange([r.range[1],i.range[0]],`,
|
|
17
|
-
`+h),message:"Closing bracket should be on its own line after array of objects",node:i})}}for(let
|
|
18
|
-
`+f),message:"Each object in array should start on a new line",node:n})}}}}},meta:{docs:{description:"Enforce array of objects to have each object on a new line"},fixable:"code",schema:[],type:"layout"}};var ve={create(e){let t=e.sourceCode||e.getSourceCode(),I=y=>{let s=y.parent,g=0,i=15,r=!1,
|
|
19
|
-
`))return;if(s.type==="ConditionalExpression"||s.loc.start.line!==s.loc.end.line){let o=t.getFirstToken(s);e.report({fix:n=>n.replaceTextRange([g.range[1],o.range[0]]," "),message:"Arrow function body should start on same line as =>",node:s});return}let l=t.getText(s);e.report({fix:o=>o.replaceTextRange([g.range[1],s.range[1]],` ${l}`),message:"Arrow function body should start on same line as =>",node:s})}}},meta:{docs:{description:"Enforce parentheses for arrow functions in JSX props with multiline expressions (preserves implicit return)"},fixable:"code",schema:[],type:"layout"}},Ce={create(e){let t=e.sourceCode||e.getSourceCode(),I=y=>{if(y.type!=="JSXElement"&&y.type!=="JSXFragment"||y.type==="JSXElement"&&y.openingElement.attributes.length>1)return!1;if(y.type==="JSXElement")for(let g of y.openingElement.attributes){if(g.type==="JSXSpreadAttribute")return!1;if(g.value&&g.value.type==="JSXExpressionContainer"){let i=g.value.expression;if(i.type==="ObjectExpression"||i.type==="ArrayExpression"||i.type==="ArrowFunctionExpression"||i.type==="FunctionExpression")return!1}}let s=y.children.filter(g=>g.type==="JSXText"?g.value.trim().length>0:!0);if(s.length===0)return!0;if(s.length===1){let g=s[0];if(g.type==="JSXText")return!0;if(g.type==="JSXExpressionContainer"){let i=g.expression;if(i.type==="Identifier"||i.type==="MemberExpression"||i.type==="Literal")return!0}}return!1},C=y=>t.getText(y).replace(/>\s+</g,"><").replace(/>\s+\{/g,">{").replace(/\}\s+</g,"}<").replace(/\s+$/g,"").replace(/^\s+/g,"");return{ArrowFunctionExpression(y){let{body:s}=y,g=t.getTokenBefore(s);if(g&&g.value==="=>"&&s.range[0]===g.range[1]&&e.report({fix:f=>f.insertTextBefore(s," "),message:"Missing space after arrow (=>)",node:s}),s.type!=="JSXElement"&&s.type!=="JSXFragment"||g.loc.end.line===s.loc.start.line||!I(s))return;let i=C(s);if(g.loc.start.column+3+i.length>120)return;let o=t.getTokenBefore(s),n=t.getTokenAfter(s);o&&o.value==="("&&n&&n.value===")"?e.report({fix:f=>f.replaceTextRange([o.range[0],n.range[1]],i),message:"Simple JSX should be on same line as arrow function without parentheses",node:s}):e.report({fix:f=>{let c=t.getTokenBefore(s);return f.replaceTextRange([c.range[1],s.range[1]]," "+i)},message:"Simple JSX should be on same line as arrow function",node:s})}}},meta:{docs:{description:"Simplify arrow functions returning simple JSX to single line"},fixable:"code",schema:[],type:"layout"}},Ae={create(e){let t=e.sourceCode||e.getSourceCode(),I=r=>{let l=r.parent;return!!(l&&l.type==="JSXExpressionContainer"&&(l=l.parent,l&&l.type==="JSXAttribute"))},C=r=>{if(r.type!=="CallExpression")return!1;let{arguments:l,callee:o}=r;if(o.type!=="Identifier"&&o.type!=="MemberExpression")return!1;if(l.length===0)return!0;if(l.length===1){let n=l[0];if(n.type==="Identifier"||n.type==="Literal")return!0;if(n.type==="CallExpression")return C(n);if(n.type==="MemberExpression")return!0}return!1},y=r=>{if(r.type!=="CallExpression")return t.getText(r);let l=t.getText(r.callee),o=r.arguments.map(n=>n.type==="CallExpression"?y(n):t.getText(n)).join(", ");return`${l}(${o})`},s=r=>r?r.type==="Identifier"||r.type==="Literal"||r.type==="ThisExpression"?!0:r.type==="MemberExpression"?s(r.object)&&s(r.property):r.type==="UnaryExpression"?s(r.argument):r.type==="CallExpression"?r.arguments.length>2?!1:r.arguments.every(s):r.type==="ObjectExpression"||r.type==="ArrayExpression":!1;return{ArrowFunctionExpression:r=>{if(r.body.type!=="BlockStatement")return;let{body:l}=r.body;if(l.length!==1)return;let o=l[0];if(o.type==="ExpressionStatement"){let n=o.expression;if(n.loc.start.line===n.loc.end.line){let h=t.getText(n);e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single statement should use expression body: () => expression instead of () => { expression }",node:r.body});return}if(C(n)){let h=y(n);e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with simple nested call should be simplified to one line",node:r.body});return}if(n.type==="CallExpression"){let h=t.getText(n);e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single statement should use expression body",node:r.body})}return}if(o.type==="ReturnStatement"){let n=o.argument;if(!n)return;let h=t.getText(n);if(n.type==="ObjectExpression"){e.report({fix:f=>f.replaceText(r.body,`(${h})`),message:"Arrow function with single return should use expression body: () => value instead of () => { return value }",node:r.body});return}if(s(n)){e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single return should use expression body: () => value instead of () => { return value }",node:r.body});return}e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single return should use expression body: () => value instead of () => { return value }",node:r.body})}},JSXExpressionContainer:r=>{let l=r.expression;if(l.type!=="ArrowFunctionExpression"||l.body.type==="BlockStatement"||l.body.type!=="CallExpression")return;let o=l.body,n=o.arguments[o.arguments.length-1];if(!n||n.type!=="ObjectExpression"&&n.type!=="ArrayExpression"||n.loc.start.line===n.loc.end.line)return;let h=t.getLastToken(o),f=t.getLastToken(r);!h||!f||h.value!==")"||f.value!=="}"||h.loc.end.line!==f.loc.start.line&&e.report({fix:c=>c.replaceTextRange([h.range[1],f.range[0]],""),message:"JSX expression closing brace should be on same line as function call: )}",node:f})}}},meta:{docs:{description:"Simplify arrow functions with single return to expression body: () => { return x } becomes () => x"},fixable:"code",schema:[],type:"layout"}},$e={create(e){let t=e.sourceCode||e.getSourceCode();return{ArrowFunctionExpression(I){let{body:C}=I;if(C.type!=="ArrowFunctionExpression")return;let y=t.getTokenBefore(C,g=>g.value==="=>");if(!y)return;let s=t.getFirstToken(C);s&&y.loc.end.line!==s.loc.start.line&&e.report({fix:g=>g.replaceTextRange([y.range[1],s.range[0]]," "),message:"Curried arrow function should start on the same line as =>",node:C})}}},meta:{docs:{description:"Enforce curried arrow function to start on same line as =>"},fixable:"code",schema:[],type:"layout"}};var Te={absolute:10,block:10,contents:10,fixed:10,flex:10,grid:10,hidden:10,inline:10,"inline-block":10,"inline-flex":10,"inline-grid":10,relative:10,static:10,sticky:10,"bottom-":20,"inset-":20,"left-":20,"right-":20,"top-":20,"z-":25,"basis-":30,"flex-":30,"grid-cols-":30,"grid-rows-":30,"content-":40,"items-":40,"justify-":40,"place-":40,"self-":40,"col-":45,grow:45,"order-":45,"row-":45,shrink:45,"gap-":50,"-m-":60,"-mx-":60,"-my-":60,"m-":60,"mb-":60,"ml-":60,"mr-":60,"mt-":60,"mx-":60,"my-":60,"p-":70,"pb-":70,"pl-":70,"pr-":70,"pt-":70,"px-":70,"py-":70,"h-":80,"max-h-":80,"max-w-":80,"min-h-":80,"min-w-":80,"size-":80,"w-":80,"align-":90,antialiased:90,"break-":90,capitalize:90,"decoration-":90,"font-":90,"hyphens-":90,italic:90,"leading-":90,"line-clamp-":90,"list-":90,lowercase:90,"normal-case":90,"not-italic":90,ordinal:90,"text-":90,"tracking-":90,truncate:90,underline:90,uppercase:90,"whitespace-":90,"bg-":100,border:110,"border-":110,"divide-":110,"outline-":110,"ring-":110,rounded:110,"rounded-":110,blur:120,"blur-":120,"brightness-":120,"contrast-":120,"drop-shadow":120,grayscale:120,"hue-rotate-":120,invert:120,"opacity-":120,"saturate-":120,sepia:120,shadow:120,"shadow-":120,"animate-":130,"delay-":130,"duration-":130,"ease-":130,transition:130,"transition-":130,"-rotate-":140,"-scale-":140,"-skew-":140,"-translate-":140,"origin-":140,"rotate-":140,"scale-":140,"skew-":140,transform:140,"translate-":140,"accent-":150,"appearance-":150,"caret-":150,"cursor-":150,"pointer-events-":150,resize:150,"scroll-":150,"select-":150,"snap-":150,"touch-":150,"will-change-":150,"fill-":160,"stroke-":160,"sr-only":170},qt=[/^(flex|grid|block|inline|hidden|absolute|relative|fixed|sticky)$/,/^(items|justify|content|self|place)-(start|end|center|between|around|evenly|stretch|baseline)$/,/^(flex|grid)-(row|col|wrap|nowrap|grow|shrink)/,/^(col|row)-span-/,/^gap-/,/^order-/,/^-?[mp][xytblr]?-\d/,/^-?[mp][xytblr]?-\[/,/^[wh]-/,/^(min|max)-[wh]-/,/^size-/,/^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/,/^text-(left|center|right|justify)$/,/^text-\w+-\d{2,3}$/,/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)$/,/^font-(sans|serif|mono)$/,/^leading-/,/^tracking-/,/^(uppercase|lowercase|capitalize|normal-case)$/,/^(truncate|line-clamp-)/,/^(bg|text|border|ring|divide|outline|fill|stroke)-(transparent|current|inherit)$/,/^(bg|text|border|ring|divide|outline|fill|stroke)-\w+-\d{2,3}$/,/^(bg|text|border|ring|divide|outline|fill|stroke)-(white|black)$/,/^rounded(-|$)/,/^border(-|$)/,/^ring(-|$)/,/^outline(-|$)/,/^shadow(-|$)/,/^opacity-/,/^blur(-|$)/,/^transition(-|$)/,/^duration-/,/^ease-/,/^delay-/,/^animate-/,/^-?(rotate|scale|skew|translate)-/,/^origin-/,/^transform$/,/^(grayscale|sepia|invert|brightness|contrast|saturate|hue-rotate)(-|$)/,/^cursor-/,/^select-/,/^pointer-events-/,/^(sm|md|lg|xl|2xl):/,/^(hover|focus|active|disabled|group-hover):/,/^(dark|light):/],Zt=2,be=3,ke=80,de=e=>{if(!e||typeof e!="string")return!1;let t=e.trim().split(/\s+/).filter(Boolean);if(t.length===0)return!1;let I=0;for(let C of t){for(let y of qt)if(y.test(C)){I+=1;break}for(let y of Object.keys(Te))if(C===y.replace("-","")||C.startsWith(y)){I+=1;break}}return I>=Zt||t.length>0&&I/t.length>.5},Kt=e=>/class/i.test(e),te=(e,t)=>Kt(e||"")||de(t),me=e=>{if(/^(sm|md|lg|xl|2xl):/.test(e))return 200;if(/^(hover|focus|active|disabled|visited|first|last|odd|even|group-):/.test(e))return 210;if(/^dark:/.test(e))return 220;if(Te[e]!==void 0)return Te[e];for(let[t,I]of Object.entries(Te))if(t.endsWith("-")&&e.startsWith(t))return I;return 180},pe=e=>{if(!e||typeof e!="string")return e;let t=e.trim().split(/\s+/).filter(Boolean);return t.length<=1?e:[...t].sort((C,y)=>{let s=me(C),g=me(y);return s!==g?s-g:C.localeCompare(y)}).join(" ")},ye=e=>{if(!e||typeof e!="string")return!1;let t=e.trim().split(/\s+/).filter(Boolean).join(" "),I=pe(t);return t!==I};var Le={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.minArgs!==void 0?I.minArgs:2,y=I.skipHooks!==void 0?I.skipHooks:!0,s=I.skipSingleArg!==void 0?I.skipSingleArg:!0,g=["useEffect","useCallback","useMemo","useLayoutEffect","useImperativeHandle","useReducer","useRef","useState","useContext","useDebugValue","useDeferredValue","useTransition","useId","useSyncExternalStore","useInsertionEffect"],i=o=>o.callee.type==="Identifier"?g.includes(o.callee.name):!1,r=o=>o.some(n=>n.loc.start.line!==n.loc.end.line);return{CallExpression:o=>{if(y&&i(o))return;let n=o.arguments;if(n.length===0)return;if(s&&n.length===1){if(n[0].type==="ObjectExpression"||n[0].type==="ArrayExpression"||n[0].type==="ArrowFunctionExpression"||n[0].type==="FunctionExpression")return;if(n[0].type==="TemplateLiteral"){let E=t.getTokenAfter(o.callee,S=>S.value==="("),A=t.getLastToken(o);if(E&&A&&E.loc.end.line!==n[0].loc.start.line){let S=t.getText(n[0]),k=o.typeArguments||o.typeParameters,$=t.getText(o.callee);k&&($+=t.getText(k)),e.report({fix:v=>v.replaceText(o,`${$}(${S})`),message:"Single template literal argument should start on same line as function call",node:o})}else if(E&&A){let S=t.getTokenAfter(n[0]),k=[];if(S&&S.value===","&&k.push($=>$.remove(S)),A.loc.start.line!==n[0].loc.end.line){let $=S&&S.value===","?S:n[0];k.push(v=>v.replaceTextRange([$.range[1],A.range[0]],""))}k.length>0&&e.report({fix:$=>k.map(v=>v($)),message:"Single template literal argument should not have trailing comma or closing paren on separate line",node:o})}return}}let h=n.length>=C,f=r(n);if(!h&&!f)return;let c=t.getTokenAfter(o.callee,E=>E.value==="("),a=t.getLastToken(o);if(!c||!a||a.value!==")")return;let u=n[0],b=n[n.length-1],T=t.lines[o.loc.start.line-1].match(/^\s*/)[0],m=T+" ";c.loc.end.line===u.loc.start.line&&e.report({fix:E=>E.replaceTextRange([c.range[1],u.range[0]],`
|
|
20
|
-
`+
|
|
21
|
-
`+
|
|
22
|
-
`+
|
|
23
|
-
`+
|
|
17
|
+
`+h),message:"Closing bracket should be on its own line after array of objects",node:i})}}for(let c=1;c<C.length;c++){let o=C[c-1],n=C[c];if(!n||n.type!=="ObjectExpression"||!o)continue;let h=t.getTokenAfter(o);if(!(!h||h.value!==",")&&h.loc.end.line===n.loc.start.line){let f=" ".repeat(s.loc.start.column+4),l=t.getFirstToken(n);e.report({fix:a=>a.replaceTextRange([h.range[1],l.range[0]],`
|
|
18
|
+
`+f),message:"Each object in array should start on a new line",node:n})}}}}},meta:{docs:{description:"Enforce array of objects to have each object on a new line"},fixable:"code",schema:[],type:"layout"}};var ve={create(e){let t=e.sourceCode||e.getSourceCode(),I=y=>{let s=y.parent,g=0,i=15,r=!1,c=!1;for(;s&&g<i;){if(s.type==="JSXExpressionContainer"){let o=s.parent;if(o&&o.type==="JSXAttribute")return!0}if(s.type==="Property"&&s.key&&s.key.type==="Identifier"){let o=s.key.name;(o==="cell"||o==="header")&&(r=!0)}if(s.type==="ArrayExpression"&&(c=!0),r&&c)return!0;if(s.type==="Property"||s.type==="ObjectExpression"||s.type==="ArrayExpression"||s.type==="CallExpression"||s.type==="ArrowFunctionExpression"){s=s.parent,g+=1;continue}break}return!1};return{ArrowFunctionExpression:y=>{if(!I(y)||y.body.type==="BlockStatement")return;let s=y.body;if(s.type==="ObjectExpression")return;let g=t.getTokenBefore(s,o=>o.value==="=>");if(!g||s.loc.start.line===g.loc.start.line)return;let i=t.getTokenAfter(g);if(i&&i.value==="("||!t.getText().slice(g.range[1],s.range[0]).includes(`
|
|
19
|
+
`))return;if(s.type==="ConditionalExpression"||s.loc.start.line!==s.loc.end.line){let o=t.getFirstToken(s);e.report({fix:n=>n.replaceTextRange([g.range[1],o.range[0]]," "),message:"Arrow function body should start on same line as =>",node:s});return}let c=t.getText(s);e.report({fix:o=>o.replaceTextRange([g.range[1],s.range[1]],` ${c}`),message:"Arrow function body should start on same line as =>",node:s})}}},meta:{docs:{description:"Enforce parentheses for arrow functions in JSX props with multiline expressions (preserves implicit return)"},fixable:"code",schema:[],type:"layout"}},Ce={create(e){let t=e.sourceCode||e.getSourceCode(),I=y=>{if(y.type!=="JSXElement"&&y.type!=="JSXFragment"||y.type==="JSXElement"&&y.openingElement.attributes.length>1)return!1;if(y.type==="JSXElement")for(let g of y.openingElement.attributes){if(g.type==="JSXSpreadAttribute")return!1;if(g.value&&g.value.type==="JSXExpressionContainer"){let i=g.value.expression;if(i.type==="ObjectExpression"||i.type==="ArrayExpression"||i.type==="ArrowFunctionExpression"||i.type==="FunctionExpression")return!1}}let s=y.children.filter(g=>g.type==="JSXText"?g.value.trim().length>0:!0);if(s.length===0)return!0;if(s.length===1){let g=s[0];if(g.type==="JSXText")return!0;if(g.type==="JSXExpressionContainer"){let i=g.expression;if(i.type==="Identifier"||i.type==="MemberExpression"||i.type==="Literal")return!0}}return!1},C=y=>t.getText(y).replace(/>\s+</g,"><").replace(/>\s+\{/g,">{").replace(/\}\s+</g,"}<").replace(/\s+$/g,"").replace(/^\s+/g,"");return{ArrowFunctionExpression(y){let{body:s}=y,g=t.getTokenBefore(s);if(g&&g.value==="=>"&&s.range[0]===g.range[1]&&e.report({fix:f=>f.insertTextBefore(s," "),message:"Missing space after arrow (=>)",node:s}),s.type!=="JSXElement"&&s.type!=="JSXFragment"||g.loc.end.line===s.loc.start.line||!I(s))return;let i=C(s);if(g.loc.start.column+3+i.length>120)return;let o=t.getTokenBefore(s),n=t.getTokenAfter(s);o&&o.value==="("&&n&&n.value===")"?e.report({fix:f=>f.replaceTextRange([o.range[0],n.range[1]],i),message:"Simple JSX should be on same line as arrow function without parentheses",node:s}):e.report({fix:f=>{let l=t.getTokenBefore(s);return f.replaceTextRange([l.range[1],s.range[1]]," "+i)},message:"Simple JSX should be on same line as arrow function",node:s})}}},meta:{docs:{description:"Simplify arrow functions returning simple JSX to single line"},fixable:"code",schema:[],type:"layout"}},Ae={create(e){let t=e.sourceCode||e.getSourceCode(),I=r=>{let c=r.parent;return!!(c&&c.type==="JSXExpressionContainer"&&(c=c.parent,c&&c.type==="JSXAttribute"))},C=r=>{if(r.type!=="CallExpression")return!1;let{arguments:c,callee:o}=r;if(o.type!=="Identifier"&&o.type!=="MemberExpression")return!1;if(c.length===0)return!0;if(c.length===1){let n=c[0];if(n.type==="Identifier"||n.type==="Literal")return!0;if(n.type==="CallExpression")return C(n);if(n.type==="MemberExpression")return!0}return!1},y=r=>{if(r.type!=="CallExpression")return t.getText(r);let c=t.getText(r.callee),o=r.arguments.map(n=>n.type==="CallExpression"?y(n):t.getText(n)).join(", ");return`${c}(${o})`},s=r=>r?r.type==="Identifier"||r.type==="Literal"||r.type==="ThisExpression"?!0:r.type==="MemberExpression"?s(r.object)&&s(r.property):r.type==="UnaryExpression"?s(r.argument):r.type==="CallExpression"?r.arguments.length>2?!1:r.arguments.every(s):r.type==="ObjectExpression"||r.type==="ArrayExpression":!1;return{ArrowFunctionExpression:r=>{if(r.body.type!=="BlockStatement")return;let{body:c}=r.body;if(c.length!==1)return;let o=c[0];if(o.type==="ExpressionStatement"){let n=o.expression;if(n.loc.start.line===n.loc.end.line){let h=t.getText(n);e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single statement should use expression body: () => expression instead of () => { expression }",node:r.body});return}if(C(n)){let h=y(n);e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with simple nested call should be simplified to one line",node:r.body});return}if(n.type==="CallExpression"){let h=t.getText(n);e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single statement should use expression body",node:r.body})}return}if(o.type==="ReturnStatement"){let n=o.argument;if(!n)return;let h=t.getText(n);if(n.type==="ObjectExpression"){e.report({fix:f=>f.replaceText(r.body,`(${h})`),message:"Arrow function with single return should use expression body: () => value instead of () => { return value }",node:r.body});return}if(s(n)){e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single return should use expression body: () => value instead of () => { return value }",node:r.body});return}e.report({fix:f=>f.replaceText(r.body,h),message:"Arrow function with single return should use expression body: () => value instead of () => { return value }",node:r.body})}},JSXExpressionContainer:r=>{let c=r.expression;if(c.type!=="ArrowFunctionExpression"||c.body.type==="BlockStatement"||c.body.type!=="CallExpression")return;let o=c.body,n=o.arguments[o.arguments.length-1];if(!n||n.type!=="ObjectExpression"&&n.type!=="ArrayExpression"||n.loc.start.line===n.loc.end.line)return;let h=t.getLastToken(o),f=t.getLastToken(r);!h||!f||h.value!==")"||f.value!=="}"||h.loc.end.line!==f.loc.start.line&&e.report({fix:l=>l.replaceTextRange([h.range[1],f.range[0]],""),message:"JSX expression closing brace should be on same line as function call: )}",node:f})}}},meta:{docs:{description:"Simplify arrow functions with single return to expression body: () => { return x } becomes () => x"},fixable:"code",schema:[],type:"layout"}},$e={create(e){let t=e.sourceCode||e.getSourceCode();return{ArrowFunctionExpression(I){let{body:C}=I;if(C.type!=="ArrowFunctionExpression")return;let y=t.getTokenBefore(C,g=>g.value==="=>");if(!y)return;let s=t.getFirstToken(C);s&&y.loc.end.line!==s.loc.start.line&&e.report({fix:g=>g.replaceTextRange([y.range[1],s.range[0]]," "),message:"Curried arrow function should start on the same line as =>",node:C})}}},meta:{docs:{description:"Enforce curried arrow function to start on same line as =>"},fixable:"code",schema:[],type:"layout"}};var Te={absolute:10,block:10,contents:10,fixed:10,flex:10,grid:10,hidden:10,inline:10,"inline-block":10,"inline-flex":10,"inline-grid":10,relative:10,static:10,sticky:10,"bottom-":20,"inset-":20,"left-":20,"right-":20,"top-":20,"z-":25,"basis-":30,"flex-":30,"grid-cols-":30,"grid-rows-":30,"content-":40,"items-":40,"justify-":40,"place-":40,"self-":40,"col-":45,grow:45,"order-":45,"row-":45,shrink:45,"gap-":50,"-m-":60,"-mx-":60,"-my-":60,"m-":60,"mb-":60,"ml-":60,"mr-":60,"mt-":60,"mx-":60,"my-":60,"p-":70,"pb-":70,"pl-":70,"pr-":70,"pt-":70,"px-":70,"py-":70,"h-":80,"max-h-":80,"max-w-":80,"min-h-":80,"min-w-":80,"size-":80,"w-":80,"align-":90,antialiased:90,"break-":90,capitalize:90,"decoration-":90,"font-":90,"hyphens-":90,italic:90,"leading-":90,"line-clamp-":90,"list-":90,lowercase:90,"normal-case":90,"not-italic":90,ordinal:90,"text-":90,"tracking-":90,truncate:90,underline:90,uppercase:90,"whitespace-":90,"bg-":100,border:110,"border-":110,"divide-":110,"outline-":110,"ring-":110,rounded:110,"rounded-":110,blur:120,"blur-":120,"brightness-":120,"contrast-":120,"drop-shadow":120,grayscale:120,"hue-rotate-":120,invert:120,"opacity-":120,"saturate-":120,sepia:120,shadow:120,"shadow-":120,"animate-":130,"delay-":130,"duration-":130,"ease-":130,transition:130,"transition-":130,"-rotate-":140,"-scale-":140,"-skew-":140,"-translate-":140,"origin-":140,"rotate-":140,"scale-":140,"skew-":140,transform:140,"translate-":140,"accent-":150,"appearance-":150,"caret-":150,"cursor-":150,"pointer-events-":150,resize:150,"scroll-":150,"select-":150,"snap-":150,"touch-":150,"will-change-":150,"fill-":160,"stroke-":160,"sr-only":170},qt=[/^(flex|grid|block|inline|hidden|absolute|relative|fixed|sticky)$/,/^(items|justify|content|self|place)-(start|end|center|between|around|evenly|stretch|baseline)$/,/^(flex|grid)-(row|col|wrap|nowrap|grow|shrink)/,/^(col|row)-span-/,/^gap-/,/^order-/,/^-?[mp][xytblr]?-\d/,/^-?[mp][xytblr]?-\[/,/^[wh]-/,/^(min|max)-[wh]-/,/^size-/,/^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/,/^text-(left|center|right|justify)$/,/^text-\w+-\d{2,3}$/,/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)$/,/^font-(sans|serif|mono)$/,/^leading-/,/^tracking-/,/^(uppercase|lowercase|capitalize|normal-case)$/,/^(truncate|line-clamp-)/,/^(bg|text|border|ring|divide|outline|fill|stroke)-(transparent|current|inherit)$/,/^(bg|text|border|ring|divide|outline|fill|stroke)-\w+-\d{2,3}$/,/^(bg|text|border|ring|divide|outline|fill|stroke)-(white|black)$/,/^rounded(-|$)/,/^border(-|$)/,/^ring(-|$)/,/^outline(-|$)/,/^shadow(-|$)/,/^opacity-/,/^blur(-|$)/,/^transition(-|$)/,/^duration-/,/^ease-/,/^delay-/,/^animate-/,/^-?(rotate|scale|skew|translate)-/,/^origin-/,/^transform$/,/^(grayscale|sepia|invert|brightness|contrast|saturate|hue-rotate)(-|$)/,/^cursor-/,/^select-/,/^pointer-events-/,/^(sm|md|lg|xl|2xl):/,/^(hover|focus|active|disabled|group-hover):/,/^(dark|light):/],Zt=2,be=3,ke=80,de=e=>{if(!e||typeof e!="string")return!1;let t=e.trim().split(/\s+/).filter(Boolean);if(t.length===0)return!1;let I=0;for(let C of t){for(let y of qt)if(y.test(C)){I+=1;break}for(let y of Object.keys(Te))if(C===y.replace("-","")||C.startsWith(y)){I+=1;break}}return I>=Zt||t.length>0&&I/t.length>.5},Kt=e=>/class/i.test(e),te=(e,t)=>Kt(e||"")||de(t),me=e=>{if(/^(sm|md|lg|xl|2xl):/.test(e))return 200;if(/^(hover|focus|active|disabled|visited|first|last|odd|even|group-):/.test(e))return 210;if(/^dark:/.test(e))return 220;if(Te[e]!==void 0)return Te[e];for(let[t,I]of Object.entries(Te))if(t.endsWith("-")&&e.startsWith(t))return I;return 180},pe=e=>{if(!e||typeof e!="string")return e;let t=e.trim().split(/\s+/).filter(Boolean);return t.length<=1?e:[...t].sort((C,y)=>{let s=me(C),g=me(y);return s!==g?s-g:C.localeCompare(y)}).join(" ")},ye=e=>{if(!e||typeof e!="string")return!1;let t=e.trim().split(/\s+/).filter(Boolean).join(" "),I=pe(t);return t!==I};var Le={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.minArgs!==void 0?I.minArgs:2,y=I.skipHooks!==void 0?I.skipHooks:!0,s=I.skipSingleArg!==void 0?I.skipSingleArg:!0,g=["useEffect","useCallback","useMemo","useLayoutEffect","useImperativeHandle","useReducer","useRef","useState","useContext","useDebugValue","useDeferredValue","useTransition","useId","useSyncExternalStore","useInsertionEffect"],i=o=>o.callee.type==="Identifier"?g.includes(o.callee.name):!1,r=o=>o.some(n=>n.loc.start.line!==n.loc.end.line);return{CallExpression:o=>{if(y&&i(o))return;let n=o.arguments;if(n.length===0)return;if(s&&n.length===1){if(n[0].type==="ObjectExpression"||n[0].type==="ArrayExpression"||n[0].type==="ArrowFunctionExpression"||n[0].type==="FunctionExpression")return;if(n[0].type==="TemplateLiteral"){let E=t.getTokenAfter(o.callee,S=>S.value==="("),A=t.getLastToken(o);if(E&&A&&E.loc.end.line!==n[0].loc.start.line){let S=t.getText(n[0]),k=o.typeArguments||o.typeParameters,$=t.getText(o.callee);k&&($+=t.getText(k)),e.report({fix:v=>v.replaceText(o,`${$}(${S})`),message:"Single template literal argument should start on same line as function call",node:o})}else if(E&&A){let S=t.getTokenAfter(n[0]),k=[];if(S&&S.value===","&&k.push($=>$.remove(S)),A.loc.start.line!==n[0].loc.end.line){let $=S&&S.value===","?S:n[0];k.push(v=>v.replaceTextRange([$.range[1],A.range[0]],""))}k.length>0&&e.report({fix:$=>k.map(v=>v($)),message:"Single template literal argument should not have trailing comma or closing paren on separate line",node:o})}return}}let h=n.length>=C,f=r(n);if(!h&&!f)return;let l=t.getTokenAfter(o.callee,E=>E.value==="("),a=t.getLastToken(o);if(!l||!a||a.value!==")")return;let u=n[0],T=n[n.length-1],b=t.lines[o.loc.start.line-1].match(/^\s*/)[0],d=b+" ";l.loc.end.line===u.loc.start.line&&e.report({fix:E=>E.replaceTextRange([l.range[1],u.range[0]],`
|
|
20
|
+
`+d),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
|
+
`+d),message:"Each argument should be on its own line",node:S})}}if(a.loc.start.line===T.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
|
+
`+b):S.replaceTextRange([T.range[1],a.range[0]],`,
|
|
23
|
+
`+b),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 c=r;if(!c||c.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!==c.loc.start.line){e.report({fix:n=>n.replaceTextRange([i.range[1],c.range[0]],""),message:"Closing parentheses should be on the same line: ))",node:c});return}let o=t.getTokenAfter(c);o&&o.value==="||"&&c.loc.end.line!==o.loc.start.line&&e.report({fix:n=>n.replaceTextRange([c.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 l=t.getTokenAfter(h);(l&&l.value===","?l:h).loc.end.line!==f.loc.start.line&&e.report({fix:T=>T.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 c=t.getTokenAfter(i),o=i;c&&c.value===","&&(o=c),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 c=t.getText(r.key),o=t.getText(r.value);return`{ ${c}: ${o} }`};return{CallExpression:i=>{let r=i.arguments;if(r.length===0)return;let c=t.getTokenAfter(i.callee,f=>f.value==="("),o=t.getLastToken(i);if(!c||!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!==c.loc.end.line){let f=y(n)?s(n):t.getText(n);e.report({fix:l=>l.replaceTextRange([c.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-c.loc.end.line>1&&e.report({fix:f=>f.replaceTextRange([c.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
|
-
`+" ".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
|
|
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,
|
|
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){
|
|
28
|
-
`);e.report({fix:w=>[w.replaceTextRange([
|
|
29
|
-
`+
|
|
30
|
-
`+v+"}"),w.replaceTextRange([
|
|
31
|
-
`+
|
|
32
|
-
`)&&/\n\s*$/.test(S))return!1;let v=
|
|
33
|
-
`)&&/\n\s*$/.test(x))return;let
|
|
34
|
-
`)[0].trim()));if(A+S.length+
|
|
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 l=r[f],a=r[f+1];if(a.loc.start.line-l.loc.end.line>1){let u=t.getTokenAfter(l,T=>T.value===",");e.report({fix:T=>T.replaceTextRange([u.range[1],a.range[0]],`
|
|
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,T=>T.value==="=>"),u=t.getFirstToken(i.body);a&&u&&a.loc.end.line!==u.loc.start.line&&e.report({fix:T=>T.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 T=t.getFirstToken(i.body);u.loc.end.line!==T.loc.start.line&&e.report({fix:x=>x.replaceTextRange([u.range[1],T.range[1]],"{"),message:"Opening brace should be on the same line as opening paren: ({",node:T})}}}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:T=>T.replaceTextRange([a.range[1],r.range[0]]," "),message:"Arrow function should have space before =>",node:r})}let c=i.params;if(c.length!==1)return;let o=c[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),l=t.getTokenAfter(o);l&&l.value===","&&(l=t.getTokenAfter(l)),l&&l.value===")"&&f.loc.end.line!==l.loc.start.line&&e.report({fix:a=>a.replaceTextRange([f.range[1],l.range[0]],""),message:"Closing brace and parenthesis should be on the same line for destructured param",node:l})},CallExpression:i=>{let{callee:r}=i,c=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(c.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([c.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],l=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 T=t.getFirstToken(f);l.loc.end.line!==T.loc.start.line&&e.report({fix:d=>d.replaceTextRange([l.range[1],T.range[1]],"{"),message:"Opening parenthesis and brace should be on the same line",node:T});let x=t.getLastToken(f),b=t.getTokenAfter(f);b&&b.value===","&&(b=t.getTokenAfter(b)),b&&b.value===")"&&x.loc.end.line!==b.loc.start.line&&e.report({fix:d=>d.replaceTextRange([x.range[1],b.range[0]],""),message:"Closing brace and parenthesis should be on the same line",node:b});return}if(f.type==="ArrayExpression"&&h.length===1){let a=f.loc.start.line!==f.loc.end.line,u=t.getFirstToken(f);if(l.loc.end.line!==u.loc.start.line){e.report({fix:b=>b.replaceTextRange([l.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 b=f.elements[0],d=t.getFirstToken(b);u.loc.end.line!==d.loc.start.line&&e.report({fix:E=>E.replaceTextRange([u.range[1],d.range[1]],"{"),message:"Opening bracket and brace should be on the same line",node:d})}let T=t.getLastToken(f),x=t.getTokenAfter(f);x&&x.value===","&&(x=t.getTokenAfter(x)),x&&x.value===")"&&T.loc.end.line!==x.loc.start.line&&e.report({fix:b=>b.replaceTextRange([T.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(l.loc.end.line===f.loc.start.line){let a=" ".repeat(l.loc.start.column+4);e.report({fix:u=>u.replaceTextRange([l.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){l.loc.end.line!==f.loc.start.line&&e.report({fix:x=>x.replaceTextRange([l.range[1],f.range[0]],""),message:"Arrow function should start on the same line as opening parenthesis",node:f});return}let u=a[0],T=a[a.length-1];if(a.length===1&&u.type==="ObjectPattern"){let x=t.getTokenBefore(u);if(!x||x.value!=="(")return;if(l.loc.end.line!==x.loc.start.line){e.report({fix:S=>S.replaceTextRange([l.range[1],x.range[1]],"("),message:"Callback opening parenthesis should be on the same line as function call",node:x});return}let b=t.getFirstToken(u);if(x.loc.end.line!==b.loc.start.line){e.report({fix:S=>S.replaceTextRange([x.range[1],b.range[1]],"{"),message:"Opening parenthesis and brace should be on the same line for callback destructured param",node:b});return}let d=t.getTokenBefore(f.body),E=t.getTokenAfter(d),A=d.value==="=>"&&d.loc.end.line!==E.loc.start.line;if(u.properties.length>=2){let S=t.getLastToken(u);if(b.loc.start.line===S.loc.end.line&&A){let v=t.lines[l.loc.start.line-1].match(/^(\s*)/)[1],p=v+" ",m=u.properties.map(w=>p+t.getText(w)).join(`,
|
|
28
|
+
`);e.report({fix:w=>[w.replaceTextRange([b.range[0],S.range[1]],`{
|
|
29
|
+
`+m+`
|
|
30
|
+
`+v+"}"),w.replaceTextRange([d.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([d.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(l.loc.end.line!==x.loc.start.line){e.report({fix:b=>b.replaceTextRange([l.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:b=>b.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 b=x.loc.end.line!==u.loc.start.line,d=f.body,E=d&&d.loc.start.line!==d.loc.end.line;if(b||E)return;l.loc.end.line!==x.loc.start.line&&e.report({fix:A=>A.replaceTextRange([l.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 c=t.getFirstToken(i),o=t.getLastToken(i);if(r.type==="ObjectExpression"&&r.properties.length>=1){let f=t.getFirstToken(r);c.loc.end.line!==f.loc.start.line&&e.report({fix:a=>a.replaceTextRange([c.range[1],f.range[1]],"{"),message:"Opening braces should be on the same line for JSX object expression",node:f});let l=t.getLastToken(r);o.loc.start.line!==l.loc.end.line&&e.report({fix:a=>a.replaceTextRange([l.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"){c.loc.end.line!==r.loc.start.line&&e.report({fix:l=>l.replaceTextRange([c.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:l=>l.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(l=>l.type==="Identifier"||l.type==="MemberExpression")){let l=r.quasis,a=r.expressions,u="`",T=[];for(let S=0;S<l.length;S+=1){let k=l[S].value.raw.replace(/\s*\n\s*/g," ").trim();k&&T.push(k),S<a.length&&T.push("${"+t.getText(a[S])+"}")}u="`"+T.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,m=ke;if($.length+v>p||S.length>m)return;if(a.length===0){let L=`"${k}"`,R=r.loc.start.line!==r.loc.end.line,P=c.loc.end.line!==r.loc.start.line;(R||P)&&e.report({fix:H=>H.replaceTextRange([c.range[0],o.range[1]],L),message:"Short className should use a string literal on a single line",node:r});return}}let d=r.loc.start.line!==r.loc.end.line,E=c.loc.end.line!==r.loc.start.line,A=r.loc.end.line!==o.loc.start.line;(d||E||A)&&u.length<=80&&e.report({fix:S=>S.replaceTextRange([c.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(c.loc.end.line!==o.loc.start.line){let a=t.getText(r);e.report({fix:u=>u.replaceTextRange([c.range[1],o.range[0]],a),message:"Simple expression should be on single line in JSX attribute",node:r});return}let l=i.parent;if(l&&l.type==="JSXElement"){let a=l.children.filter(u=>!(u.type==="JSXText"&&/^\s*$/.test(u.value)));if(a.length===1&&a[0]===i){let u=l.openingElement,T=l.closingElement;if(T){let x=u.loc.end.line,b=T.loc.start.line;if(x!==b){let d=t.getText(u),E=t.getText(T),A=t.getText(i);d.length+A.length+E.length<=120&&e.report({fix:k=>k.replaceTextRange([u.range[1],T.range[0]],A),message:"JSX element with simple expression should be on single line",node:l})}}}}return}if(r.type==="ArrowFunctionExpression"){if(c.loc.end.line!==r.loc.start.line){e.report({fix:f=>f.replaceTextRange([c.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:l=>l.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,l=c.loc.end.line!==r.loc.start.line,a=r.loc.end.line!==o.loc.start.line;if((l||a)&&f){let x=t.getText(r);e.report({fix:b=>b.replaceTextRange([c.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,b=>b.value==="=>");if(x&&x.loc.end.line!==r.body.loc.start.line){let b=t.getText(r.body);e.report({fix:d=>d.replaceTextRange([x.range[1],o.range[0]]," "+b),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==="("){c.loc.end.line!==f.loc.start.line&&e.report({fix:a=>a.replaceTextRange([c.range[1],f.range[1]],"("),message:"Opening brace and parenthesis should be together for JSX expression",node:f});let l=t.getTokenAfter(r);l&&l.value===")"&&o.loc.start.line!==l.loc.end.line&&e.report({fix:a=>a.replaceTextRange([l.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=b=>b.type==="LogicalExpression"?f(b.left)+f(b.right):1,l=f(r),a=t.getText(r),u=r.loc.start.line!==r.loc.end.line;if(l<=2&&a.length<=80){let b=a.replace(/\s*\n\s*/g," ");if(u||c.loc.end.line!==r.loc.start.line||r.loc.end.line!==o.loc.start.line){e.report({fix:E=>E.replaceTextRange([c.range[1],o.range[0]],b),message:"Simple logical expression should be on a single line",node:r});return}let d=i.parent;if(d&&d.type==="JSXElement"){let E=d.children.filter(A=>!(A.type==="JSXText"&&/^\s*$/.test(A.value)));if(E.length===1&&E[0]===i){let A=d.openingElement,S=d.closingElement;if(S){let k=A.loc.end.line,$=S.loc.start.line;if(k!==$){let v=t.getText(A),p=t.getText(S),m="{"+b+"}";v.length+m.length+p.length<=120&&e.report({fix:L=>L.replaceTextRange([A.range[1],S.range[0]],m),message:"JSX element with simple logical expression should be on single line",node:d})}}}}return}if(l>=3&&u){if(c.loc.end.line!==r.loc.start.line){e.report({fix:b=>b.replaceTextRange([c.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 d=t.lines[c.loc.start.line-1].match(/^\s*/)[0];e.report({fix:E=>E.replaceTextRange([r.range[1],o.range[0]],`
|
|
31
|
+
`+d),message:"Closing brace should be on its own line for multiline logical expression",node:o})}return}if(c.loc.end.line!==r.loc.start.line){e.report({fix:b=>b.replaceTextRange([c.range[1],r.range[0]],""),message:"Opening brace and logical expression should be on the same line",node:r});return}let T=b=>{if(b.type!=="LogicalExpression"&&b.type!=="BinaryExpression")return!1;let{left:d,right:E}=b;if(b.loc.start.line!==b.loc.end.line){let A=t.getTokenAfter(d,S=>["&&","||","===","!==","==","!=",">","<",">=","<="].includes(S.value));if(A){let S=t.text.slice(d.range[1],A.range[0]);if(S.includes(`
|
|
32
|
+
`)&&/\n\s*$/.test(S))return!1;let v=d.loc.end.line,p=A.loc.start.line,m=E.loc.start.line;if(v!==p||p!==m){let w=t.getTokenBefore(b),L=t.getTokenAfter(b),R=w?.value==="("&&L?.value===")",P=t.getText(b).replace(/\s*\n\s*/g," ").trim();return e.report({fix:H=>R?H.replaceTextRange([w.range[0],L.range[1]],`(${P})`):H.replaceText(b,P),message:"Condition operands should be on the same line",node:b}),!0}}}return b.type==="LogicalExpression"?T(d)||T(E):!1};if(r.operator==="&&"&&T(r.left))return;let x=t.getTokenAfter(r.left,b=>b.value==="&&"||b.value==="||");if(x){let b=r.right.type==="JSXElement"||r.right.type==="JSXFragment"||r.right.type==="ConditionalExpression"||r.right.type==="ObjectExpression"||t.getTokenBefore(r.right)?.value==="(",d=t.getTokenAfter(r.left),E=d&&d.value===")",A=E?d.range[1]:r.left.range[1],S=E?d.loc.end.line:r.left.loc.end.line;if(b&&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 c=o=>{if(o.type!=="LogicalExpression")return;let{left:n,right:h,operator:f}=o;c(n),c(h);let l=t.getTokenAfter(n,x=>x.value==="||"||x.value==="&&");if(!l)return;let a=n.loc.end.line,u=l.loc.start.line,T=h.loc.start.line;if(a!==u||u!==T){let x=t.text.slice(n.range[1],l.range[0]);if(x.includes(`
|
|
33
|
+
`)&&/\n\s*$/.test(x))return;let d=t.getLastToken(n),E=t.getFirstToken(h);e.report({fix:A=>A.replaceTextRange([d.range[1],E.range[0]],` ${f} `),message:"Logical operator should be on the same line as both operands: ) || func(",node:l})}};c(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:c}=r;if(c.type==="BlockStatement"||!y(c))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 l=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,l),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(b=>!(b.arguments.length>1||b.arguments.length===1&&!C(b.arguments[0])));if(x){let b=t.getText(s),d=b.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(b.split(`
|
|
34
|
+
`)[0].trim()));if(A+S.length+d.length<=120){e.report({fix:$=>$.replaceText(s,d),message:"Method chain with single simple arguments should be on one line",node:s});return}}if(!x){let b=!1;for(let d=1;d<u.length;d++){let E=t.getLastToken(u[d-1]),A=t.getTokenAfter(u[d].callee.property,S=>S.value==="(");if(E.loc.end.line!==A.loc.start.line){b=!0;break}}if(b){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(`
|
|
35
35
|
`);w.length>1&&(k=w[0]+`
|
|
36
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(`
|
|
37
37
|
`))}let v=k.split(`
|
|
38
|
-
`)[0],p=t.lines[s.loc.start.line-1].slice(0,s.loc.start.column),
|
|
38
|
+
`)[0],p=t.lines[s.loc.start.line-1].slice(0,s.loc.start.column),m=t.getText(s);if(p.length+v.length<=120&&k!==m){e.report({fix:w=>w.replaceText(s,k),message:"Method chain should not have line breaks between calls",node:s});return}}}}}if(!r||g.length!==1)return;let c=g[0];if(!I(c)||s.loc.start.line===s.loc.end.line)return;let o=t.getTokenAfter(i,u=>u.value==="("),n=t.getLastToken(s);if(!o||!n||n.value!==")")return;let h=s.typeArguments||s.typeParameters,f=t.getText(i);h&&(f+=t.getText(h));let l=t.getText(c),a=`${f}(${l})`;a.length>120||e.report({fix:u=>u.replaceText(s,a),message:"Single simple argument should be on one line",node:s})}}},meta:{docs:{description:"Enforce single simple argument calls and method chains to be on one line"},fixable:"code",schema:[],type:"layout"}};var He={create(e){let t=e.sourceCode||e.getSourceCode(),I=new Map,C=(y,s)=>{let g=[],i=r=>{if(!(!r||typeof r!="object")){r.type==="Identifier"&&r.name===s&&g.push(r);for(let c in r){if(c==="parent"||c==="range"||c==="loc")continue;let o=r[c];Array.isArray(o)?o.forEach(n=>i(n)):o&&typeof o=="object"&&o.type&&i(o)}}};return i(y),g};return{ClassDeclaration(y){if(!y.id||!y.id.name)return;let s=y.id.name;s.endsWith("Class")||I.set(s,{classIdNode:y.id,newName:`${s}Class`})},"Program:exit"(y){I.forEach(({classIdNode:s,newName:g},i)=>{let r=C(y,i);e.report({fix:c=>{let o=[];return r.forEach(n=>{o.push(c.replaceText(n,g))}),o},message:`Class name "${i}" should end with "Class" suffix`,node:s})})}}},meta:{docs:{description:"Enforce class names end with 'Class' suffix"},fixable:"code",schema:[],type:"suggestion"}},je={create(e){let t=e.sourceCode||e.getSourceCode();return{ClassDeclaration(I){let C=I.body;if(!C)return;let y=t.getFirstToken(C);if(!y||y.value!=="{")return;let s=t.getTokenBefore(y);if(!s)return;if(s.loc.end.line!==y.loc.start.line){e.report({fix:i=>i.replaceTextRange([s.range[1],y.range[0]]," "),message:"Opening brace should be on the same line as class declaration",node:y});return}t.text.slice(s.range[1],y.range[0])!==" "&&e.report({fix:i=>i.replaceTextRange([s.range[1],y.range[0]]," "),message:"Expected single space before opening brace in class declaration",node:y})},MethodDefinition(I){let C=I.key,y=I.value;if(!C||!y)return;let s=I.computed?t.getTokenAfter(C,{filter:h=>h.value==="]"}):t.getLastToken(C);if(!s)return;let g=t.getTokenAfter(s);for(;g&&g.value!=="(";)g=t.getTokenAfter(g);if(!g||g.value!=="(")return;let i=t.getTokenBefore(g);if(i){let h=t.text.slice(i.range[1],g.range[0]);/\s/.test(h)&&e.report({fix:f=>f.replaceTextRange([i.range[1],g.range[0]],""),message:"No space between method name and opening parenthesis",node:g})}let r=y.body;if(!r||r.type!=="BlockStatement")return;let c=t.getFirstToken(r);if(!c||c.value!=="{")return;let o=t.getTokenBefore(c);if(!o)return;if(o.loc.end.line!==c.loc.start.line){e.report({fix:h=>h.replaceTextRange([o.range[1],c.range[0]]," "),message:"Opening brace should be on the same line as method signature",node:c});return}t.text.slice(o.range[1],c.range[0])!==" "&&e.report({fix:h=>h.replaceTextRange([o.range[1],c.range[0]]," "),message:"Expected single space before opening brace in method definition",node:c})}}},meta:{docs:{description:"Enforce consistent spacing in class and method definitions"},fixable:"whitespace",schema:[],type:"layout"}};var Oe={create(e){let t=e.sourceCode||e.getSourceCode();return{Program(I){let C=t.getAllComments();if(C.length===0)return;let y=t.getFirstToken(I);if(C.forEach(g=>{let{type:i,value:r}=g;if(i==="Block")if(!r.includes(`
|
|
39
39
|
`)){let n=r.trim();if(/^eslint-disable|^eslint-enable|^eslint-disable-next-line|^eslint-disable-line/.test(n))return;e.report({fix:f=>f.replaceText(g,`// ${n}`),loc:g.loc,message:"Single-line comments should use // syntax instead of /* */"})}else{let n=r.length>0&&!r.startsWith(" ")&&!r.startsWith("*")&&!r.startsWith(`
|
|
40
40
|
`),h=r.length>0&&!r.endsWith(" ")&&!r.endsWith("*")&&!r.endsWith(`
|
|
41
|
-
`);if(n||h){let f=r;n&&(f=" "+f),h&&(f=f+" "),e.report({fix:
|
|
41
|
+
`);if(n||h){let f=r;n&&(f=" "+f),h&&(f=f+" "),e.report({fix:l=>l.replaceText(g,`/*${f}*/`),loc:g.loc,message:"Block comment should have space after /* and before */"})}}else i==="Line"&&r.length>0&&!r.startsWith(" ")&&!r.startsWith("/")&&e.report({fix:n=>n.replaceText(g,`// ${r}`),loc:g.loc,message:"Line comment should have space after //"});let c=t.getTokenBefore(g,{includeComments:!1});c&&c.loc.end.line===g.loc.start.line&&g.range[0]-c.range[1]!==1&&e.report({fix:n=>n.replaceTextRange([c.range[1],g.range[0]]," "),loc:g.loc,message:"Inline comment should have exactly one space before it"})}),!y)return;let s=C.filter(g=>g.loc.end.line<y.loc.start.line||g.loc.start.line===1&&y.loc.start.line===1&&g.range[1]<y.range[0]);if(s.length>1)for(let g=0;g<s.length-1;g+=1){let i=s[g],r=s[g+1];r.loc.start.line-i.loc.end.line>1&&e.report({fix:o=>o.replaceTextRange([i.range[1],r.range[0]],`
|
|
42
42
|
`),loc:r.loc,message:"No blank lines allowed between top-of-file comments"})}if(s.length>0){let g=s[s.length-1];y.loc.start.line===g.loc.end.line+1?e.report({fix:i=>i.insertTextAfter(g,`
|
|
43
43
|
`),loc:y.loc,message:"Expected empty line between top-of-file comments and code"}):y.loc.start.line===g.loc.end.line&&e.report({fix:i=>i.insertTextBefore(y,`
|
|
44
44
|
|
|
45
|
-
`),loc:y.loc,message:"Code should be on a new line after top-of-file comments"})}}}},meta:{docs:{description:"Enforce comment spacing and formatting"},fixable:"whitespace",schema:[],type:"layout"}};import Me from"fs";var Ne={create(e){let t=e.sourceCode||e.getSourceCode(),I=i=>{if(!i)return!1;if(i.type==="JSXElement"||i.type==="JSXFragment")return!0;if(i.type==="BlockStatement"){for(let r of i.body)if(r.type==="ReturnStatement"&&r.argument&&I(r.argument))return!0}return i.type==="ConditionalExpression"?I(i.consequent)||I(i.alternate):i.type==="LogicalExpression"?I(i.left)||I(i.right):i.type==="ParenthesizedExpression"?I(i.expression):!1},C=i=>{let r=null;if(i.parent&&(i.parent.type==="VariableDeclarator"&&i.parent.id&&i.parent.id.type==="Identifier"?r=i.parent.id.name:i.id&&i.id.type==="Identifier"&&(r=i.id.name)),r&&/^[A-Z]/.test(r)){let
|
|
46
|
-
`)?
|
|
47
|
-
`)&&(
|
|
48
|
-
`+
|
|
49
|
-
`+x),message:"Closing brace must be on its own line when there are multiple properties",node:E})}if(u.length===1&&
|
|
50
|
-
`+
|
|
51
|
-
`);return v.replaceTextRange([$.range[1],A.range[0]],
|
|
52
|
-
`+x),message:"No empty line before closing brace in props type",node:E})}}return}if(o.type==="TSTypeReference"){if(r){let
|
|
53
|
-
`+
|
|
54
|
-
`+u),message:"No empty line before closing brace in props type",node:k})}if(
|
|
55
|
-
`+
|
|
56
|
-
`+u),message:"Closing brace must be on its own line when there are multiple properties",node:S})}if(
|
|
57
|
-
`+
|
|
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]],`
|
|
59
|
-
`+
|
|
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),
|
|
61
|
-
`+" ".repeat(
|
|
62
|
-
`),message:"Expected empty line between consecutive if statements with block bodies",node:
|
|
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 (${
|
|
45
|
+
`),loc:y.loc,message:"Code should be on a new line after top-of-file comments"})}}}},meta:{docs:{description:"Enforce comment spacing and formatting"},fixable:"whitespace",schema:[],type:"layout"}};import Me from"fs";var Ne={create(e){let t=e.sourceCode||e.getSourceCode(),I=i=>{if(!i)return!1;if(i.type==="JSXElement"||i.type==="JSXFragment")return!0;if(i.type==="BlockStatement"){for(let r of i.body)if(r.type==="ReturnStatement"&&r.argument&&I(r.argument))return!0}return i.type==="ConditionalExpression"?I(i.consequent)||I(i.alternate):i.type==="LogicalExpression"?I(i.left)||I(i.right):i.type==="ParenthesizedExpression"?I(i.expression):!1},C=i=>{let r=null;if(i.parent&&(i.parent.type==="VariableDeclarator"&&i.parent.id&&i.parent.id.type==="Identifier"?r=i.parent.id.name:i.id&&i.id.type==="Identifier"&&(r=i.id.name)),r&&/^[A-Z]/.test(r)){let c=i.body;return I(c)}return!1},y=(i,r)=>{let c=[],o=n=>{if(!(!n||typeof n!="object")){if(n.type==="MemberExpression"&&!n.computed&&n.object.type==="Identifier"&&n.object.name===r){let h=n.property.name;c.push({node:n,property:h})}for(let h of Object.keys(n)){if(h==="parent")continue;let f=n[h];Array.isArray(f)?f.forEach(o):f&&typeof f=="object"&&f.type&&o(f)}}};return o(i),c},s=(i,r)=>{let c=[];if(i.type!=="BlockStatement")return c;for(let o of i.body)if(o.type==="VariableDeclaration"){for(let n of o.declarations)if(n.id.type==="ObjectPattern"&&n.init&&n.init.type==="Identifier"&&n.init.name===r){let h=[];for(let f of n.id.properties)if(f.type==="Property"&&f.key.type==="Identifier"){let l=f.key.name,a=f.value.type==="Identifier"?f.value.name:null,u=f.value.type==="AssignmentPattern",T=null;u&&f.value.right&&(T=t.getText(f.value.right)),h.push({default:T,hasAlias:l!==a&&!u,key:l,value:u?f.value.left.name:a})}else f.type==="RestElement"&&f.argument.type==="Identifier"&&h.push({isRest:!0,key:f.argument.name,value:f.argument.name});c.push({declarator:n,props:h,statement:o,statementHasOnlyThisDeclarator:o.declarations.length===1})}}return c},g=i=>{if(!C(i))return;let r=i.params;if(r.length===0)return;let c=r[0];if(c.type==="Identifier"){let o=c.name,n=y(i.body,o),h=s(i.body,o),f=[...new Set(n.map(d=>d.property))],l=[];h.forEach(d=>{d.props.forEach(E=>{l.push(E)})});let a=[],u=(d,E=[])=>{if(!(!d||typeof d!="object")&&!E.includes(d)){d.type==="Identifier"&&d.name===o&&a.push(d);for(let A of Object.keys(d)){if(A==="parent")continue;let S=d[A];Array.isArray(S)?S.forEach(k=>u(k,E)):S&&typeof S=="object"&&S.type&&u(S,E)}}};u(i.body);let T=n.length+h.length,b=(f.length>0||l.length>0)&&a.length===T;e.report({fix:b?d=>{let E=[],A=[];f.forEach(v=>{A.some(p=>p.key===v)||A.push({key:v,simple:!0})}),l.forEach(v=>{A.some(p=>p.key===v.key)||A.push(v)});let k=`{ ${A.map(v=>v.isRest?`...${v.key}`:v.simple?v.key:v.default?`${v.key} = ${v.default}`:v.hasAlias?`${v.key}: ${v.value}`:v.key).join(", ")} }`,$=k;if(c.typeAnnotation){let v=t.getText(c.typeAnnotation);$=`${k}${v}`}return E.push(d.replaceText(c,$)),n.forEach(v=>{E.push(d.replaceText(v.node,v.property))}),h.forEach(v=>{if(v.statementHasOnlyThisDeclarator){let p=v.statement.range[0],m=v.statement.range[1],w=t.getText().slice(m,m+2);w.startsWith(`
|
|
46
|
+
`)?m+=1:w.startsWith(`\r
|
|
47
|
+
`)&&(m+=2),E.push(d.removeRange([p,m]))}else E.push(d.remove(v.declarator))}),E}:void 0,message:`Component props should be destructured. Use "({ ...props })" instead of "${c.name}"`,node:c})}};return{ArrowFunctionExpression:g,FunctionDeclaration:g,FunctionExpression:g}},meta:{docs:{description:"Enforce that React component props must be destructured in the function parameter"},fixable:"code",schema:[],type:"suggestion"}},De={create(e){let t=e.sourceCode||e.getSourceCode(),I=g=>{if(!g)return!1;if(g.type==="JSXElement"||g.type==="JSXFragment")return!0;if(g.type==="BlockStatement"){for(let i of g.body)if(i.type==="ReturnStatement"&&i.argument&&I(i.argument))return!0}return g.type==="ConditionalExpression"?I(g.consequent)||I(g.alternate):g.type==="LogicalExpression"?I(g.left)||I(g.right):g.type==="ParenthesizedExpression"?I(g.expression):!1},C=g=>{let i=null;if(g.parent&&(g.parent.type==="VariableDeclarator"&&g.parent.id&&g.parent.id.type==="Identifier"?i=g.parent.id.name:g.id&&g.id.type==="Identifier"&&(i=g.id.name)),i&&/^[A-Z]/.test(i)){let r=g.body;return I(r)}return!1},y=g=>{let i=g.params;if(i.length===0)return;let r=C(g);r||i.forEach(l=>{if(l.type==="Identifier"&&l.typeAnnotation&&l.typeAnnotation.typeAnnotation){let a=l.typeAnnotation.typeAnnotation;a.type==="TSTypeLiteral"&&e.report({message:`Parameter "${l.name}" must use a type reference (interface or type alias), not an inline object type. Define the type separately.`,node:a})}});let c=i[0];if(c.type!=="ObjectPattern")return;if(!c.typeAnnotation||!c.typeAnnotation.typeAnnotation){let l=e.getFilename?e.getFilename():e.filename||"";(l.endsWith(".ts")||l.endsWith(".tsx"))&&r&&e.report({message:'Component props must have a type annotation. Add inline type: "({ prop }: { prop: Type })"',node:c});return}let o=c.typeAnnotation.typeAnnotation,n=t.getFirstToken(c.typeAnnotation),h=n?t.getTokenBefore(n):null,f=t.getFirstToken(o);if(h&&n&&f&&h.value==="}"){let l=t.getText().slice(h.range[1],n.range[0]),a=t.getText().slice(n.range[1],f.range[0]);(l!==""||a!==" ")&&e.report({fix:u=>u.replaceTextRange([h.range[1],f.range[0]],": "),message:'Type annotation must have no space before colon and one space after: "}: TypeName"',node:o})}if(o.type==="TSIntersectionType"&&r){let l=o.types;for(let u=0;u<l.length-1;u+=1){let T=l[u],x=l[u+1],b=t.getTokenAfter(T,d=>d.value==="&");if(b&&b.loc.start.line!==T.loc.end.line&&e.report({fix:d=>d.replaceTextRange([T.range[1],b.range[1]]," &"),message:'"&" must be on same line as previous type',node:b}),x.type==="TSTypeLiteral"&&b){let d=t.getFirstToken(x);d&&d.loc.start.line!==b.loc.end.line&&e.report({fix:E=>E.replaceTextRange([b.range[1],d.range[0]]," "),message:'Opening brace must be on same line as "&"',node:d})}}let a=l.find(u=>u.type==="TSTypeLiteral");if(a){let u=a.members,x=t.lines[g.loc.start.line-1].match(/^\s*/)[0],b=x+" ",d=t.getFirstToken(a),E=t.getLastToken(a);if(u.length>1&&u[0]){let A=u[0];A.loc.start.line===d.loc.end.line&&e.report({fix:S=>S.replaceTextRange([d.range[1],A.range[0]],`
|
|
48
|
+
`+b),message:"First props type property must be on a new line when there are multiple properties",node:A})}if(u.length>1&&E){let A=u[u.length-1];E.loc.start.line===A.loc.end.line&&e.report({fix:S=>S.replaceTextRange([A.range[1],E.range[0]],`
|
|
49
|
+
`+x),message:"Closing brace must be on its own line when there are multiple properties",node:E})}if(u.length===1&&d&&E){let A=u[0];if(d.loc.end.line!==E.loc.start.line){let S=t.getText(A);S=S.replace(/[,;]\s*$/,""),e.report({fix:k=>k.replaceTextRange([d.range[0],E.range[1]],`{ ${S} }`),message:"Single props type property should be on a single line",node:a})}}if(u.forEach((A,S)=>{let k=t.getText(A);if(k.trimEnd().endsWith(";")&&e.report({fix:$=>{let v=k.lastIndexOf(";"),p=A.range[0]+v;return $.replaceTextRange([p,p+1],",")},message:"Props type properties must end with comma (,) not semicolon (;)",node:A}),u.length>1&&S>0){let $=u[S-1];A.loc.start.line===$.loc.end.line&&e.report({fix:v=>{let p=t.getTokenAfter($);for(;p&&p.value!==","&&p.range[0]<A.range[0];)p=t.getTokenAfter(p);let m=p&&p.value===","?p.range[1]:$.range[1];return v.replaceTextRange([m,A.range[0]],`
|
|
50
|
+
`+b)},message:"Each props type property must be on its own line when there are multiple properties",node:A}),A.loc.start.line-$.loc.end.line>1&&e.report({fix:v=>{let m=t.getText().slice($.range[1],A.range[0]).replace(/\n\s*\n/g,`
|
|
51
|
+
`);return v.replaceTextRange([$.range[1],A.range[0]],m)},message:"No empty lines allowed between props type properties",node:A})}}),u.length>1){let A=u[u.length-1];t.getText(A).trimEnd().endsWith(",")||e.report({fix:k=>k.insertTextAfter(A,","),message:"Last props type property must have trailing comma",node:A})}if(u.length===1){let A=u[0],S=t.getText(A);S.trimEnd().endsWith(",")&&e.report({fix:k=>{let $=S.lastIndexOf(","),v=A.range[0]+$;return k.removeRange([v,v+1])},message:"Single props type property should not have trailing comma",node:A})}if(u.length>0&&E){let A=u[u.length-1];E.loc.start.line-A.loc.end.line>1&&e.report({fix:S=>S.replaceTextRange([A.range[1],E.range[0]],`
|
|
52
|
+
`+x),message:"No empty line before closing brace in props type",node:E})}}return}if(o.type==="TSTypeReference"){if(r){let l=o.typeName&&o.typeName.name?o.typeName.name:t.getText(o.typeName);if(o.typeName&&o.typeName.type==="TSQualifiedName")return;e.report({message:`Component props should use inline type annotation instead of referencing "${l}". Define the type inline as "{ prop: type, ... }"`,node:o})}return}if(o.type==="TSTypeLiteral"&&r){let l=o.members,u=t.lines[g.loc.start.line-1].match(/^\s*/)[0],T=u+" ",x=t.getFirstToken(o),b=c.properties.filter(k=>k.type==="Property"||k.type==="RestElement").map(k=>k.type==="RestElement"?null:k.key&&k.key.name?k.key.name:null).filter(Boolean).sort(),d=l.filter(k=>k.type==="TSPropertySignature").map(k=>k.key&&k.key.name?k.key.name:null).filter(Boolean).sort(),E=b.filter(k=>!d.includes(k)),A=d.filter(k=>!b.includes(k));E.length>0&&e.report({message:`Props type is missing properties that are destructured: ${E.join(", ")}`,node:o}),A.length>0&&e.report({message:`Props type has extra properties not in destructured props: ${A.join(", ")}`,node:o});let S=t.getLastToken(o);if(l.length>0){let k=l[0];k.loc.start.line-x.loc.end.line>1&&e.report({fix:$=>$.replaceTextRange([x.range[1],k.range[0]],`
|
|
53
|
+
`+T),message:"No empty line after opening brace in props type",node:k})}if(l.length>0&&S){let k=l[l.length-1];S.loc.start.line-k.loc.end.line>1&&e.report({fix:$=>$.replaceTextRange([k.range[1],S.range[0]],`
|
|
54
|
+
`+u),message:"No empty line before closing brace in props type",node:k})}if(l.length>1&&l[0]){let k=l[0];k.loc.start.line===x.loc.end.line&&e.report({fix:$=>$.replaceTextRange([x.range[1],k.range[0]],`
|
|
55
|
+
`+T),message:"First props type property must be on a new line when there are multiple properties",node:k})}if(l.length>1&&S){let k=l[l.length-1];S.loc.start.line===k.loc.end.line&&e.report({fix:$=>$.replaceTextRange([k.range[1],S.range[0]],`
|
|
56
|
+
`+u),message:"Closing brace must be on its own line when there are multiple properties",node:S})}if(l.length===1&&x&&S){let k=l[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(l.forEach((k,$)=>{let v=t.getText(k);if(k.type==="TSPropertySignature"&&k.optional){let p=t.getFirstToken(k),m=t.getTokenAfter(p);m&&m.value==="?"&&t.getText().slice(p.range[1],m.range[0])!==""&&e.report({fix:L=>L.replaceTextRange([p.range[1],m.range[0]],""),message:'No space allowed before "?" in optional property',node:k})}if(v.trimEnd().endsWith(";")&&e.report({fix:p=>{let m=v.lastIndexOf(";"),w=k.range[0]+m;return p.replaceTextRange([w,w+1],",")},message:"Props type properties must end with comma (,) not semicolon (;)",node:k}),l.length>1&&$>0){let p=l[$-1];k.loc.start.line===p.loc.end.line&&e.report({fix:m=>{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 m.replaceTextRange([L,k.range[0]],`
|
|
57
|
+
`+T)},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:m=>{let L=t.getText().slice(p.range[1],k.range[0]).replace(/\n\s*\n/g,`
|
|
58
|
+
`);return m.replaceTextRange([p.range[1],k.range[0]],L)},message:"No empty lines allowed between props type properties",node:k})}}),l.length>1){let k=l[l.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(l.length===1){let k=l[0],$=t.getText(k);$.trimEnd().endsWith(",")&&e.report({fix:v=>{let p=$.lastIndexOf(","),m=k.range[0]+p;return v.removeRange([m,m+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,T=>T.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]),l=t.getText().slice(n.range[1],h.range[0]);(f!==""||l!==" ")&&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(c=>c.type==="ReturnStatement"&&c.argument);if(r.length===1){let c=r[0].argument;if(c.type==="JSXElement")return c.openingElement&&c.openingElement.name&&c.openingElement.name.name==="svg";if(c.type==="ParenthesizedExpression"&&c.expression&&c.expression.type==="JSXElement")return c.expression.openingElement&&c.expression.openingElement.name&&c.expression.openingElement.name.name==="svg"}}return!1},s=g=>{let i=t(g);if(!I(i))return;let r=y(g),c=C(i);r&&!c&&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}),c&&!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("|"),c=()=>{let S=new RegExp(`\\/(${r})\\/(.+)\\.(jsx?|tsx?)$`),k=I.match(S);if(!k)return null;let $=k[1],v=C[$],m=k[2].split("/"),w=m[m.length-1],L=m.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 m=v.filter(R=>!o.has(R)),w;if(k==="index"){if(w=[...m].reverse(),w.length===0)return null}else w=[k,...[...m].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),l=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 m=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(m,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)`,T=(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),b=(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 m=0;m<=$;m++)p[m][0]=m;for(let m=0;m<=v;m++)p[0][m]=m;for(let m=1;m<=$;m++)for(let w=1;w<=v;w++)p[m][w]=S[m-1]===k[w-1]?p[m-1][w-1]:1+Math.min(p[m-1][w-1],p[m-1][w],p[m][w-1]);return p[$][v]},d=(S,k,$,v,p,m)=>{let L=m.fileName==="index"?"":g(m.fileName),P=[...m.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)||b(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=c();if(!k)return;let $=h(S);if(!$)return;let{name:v,identifierNode:p}=$,{folder:m,suffix:w}=k;if(s.has(m)){if(!w)return;if(x(v))d(v,m,w,p,S,k);else if(f(v)){let R=i(v);e.report({fix:a(S,v,R,p),message:`"${v}" in "${m}" 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 "${m}" folder should be PascalCase. Rename to "${H}"`,node:p})}return}if(y.has(m)&&!l(S))return;let L=n(k);if(L&&v!==L){let R=T(v,m);if(R){e.report({message:`"${v}" belongs in "${R}/" folder, not "${m}/". Move it to the correct folder.`,node:p});return}e.report({fix:a(S,v,L,p),message:u(v,m,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=c();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))d(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 m=n(k);if(m&&p!==m){let w=T(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,m,S.id),message:u(p,$,v,m),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 E of s){let A=new RegExp(`(.*/${E})/`),S=I.match(A);if(S)return{folder:E,fullPath:S[1]}}return null})();if(!i){let E=I.replace(/.*\//,"").replace(/\.(jsx?|tsx?)$/,"");return s.includes(E)?{Program(A){e.report({message:`"${E}" should be a folder, not a standalone file. Use "${E}/" folder with an index file instead.`,node:A})}}:{}}let r=/\.(tsx?|jsx?)$/,c=(E,A)=>{let S;try{S=Me.readdirSync(E,{withFileTypes:!0})}catch{return null}let k=S.filter(R=>R.isFile()&&r.test(R.name)&&!R.name.startsWith("index.")),$=S.filter(R=>R.isDirectory());if(k.length===0&&$.length===0||k.length<=1&&$.length===0)return null;let v=()=>{for(let R of $)try{let P=`${E}/${R.name}`,H=Me.readdirSync(P,{withFileTypes:!0}),F=H.filter(j=>j.isFile()&&r.test(j.name));if(F.length>=2||F.some(j=>j.name.startsWith("index."))||H.filter(j=>j.isDirectory()).length>0)return!0}catch{}return!1},p=k.length>0,m=$.length>0,w=p&&m,L=m?v():!1;return{folderLabel:A,hasDirectFiles:p,hasSubdirectories:m,isMixed:w,wrappedJustified:L}},{fullPath:o}=i,n=I.split("/"),h=n.slice(0,-1).join("/"),f=n[n.length-2],l=h,a=f,u=c(l,a);if(!u)return{};let{hasDirectFiles:T,hasSubdirectories:x,isMixed:b,wrappedJustified:d}=u;return{Program(E){if(!T&&x&&!d){e.report({message:`Unnecessary wrapper folders in "${a}/". Each item has only one file, use direct files instead (e.g., ${a}/component.tsx).`,node:E});return}if(b&&d){!I.slice(l.length+1).includes("/")&&e.report({message:`Since some items in "${a}/" contain multiple files or subfolders, all items should be wrapped in folders.`,node:E});return}b&&!d&&I.slice(l.length+1).includes("/")&&e.report({message:`Unnecessary wrapper folder. Each item in "${a}/" has only one file, use direct files instead.`,node:E})}}},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 c=[];for(let h=1;h<r.length;h++){let f=r[h];for(let l=0;l<h;l++){let a=r[l],u=g(a),T=`-${a}`,x=`-${u}`,b=f.endsWith(T)?T:a!==u&&f.endsWith(x)?x:null;b&&c.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),l=`-${h}`,a=`-${f}`;if(s.endsWith(l)){n={folder:h,singular:f,suffix:l};break}if(h!==f&&s.endsWith(a)){n={folder:h,singular:f,suffix:a};break}}return c.length===0&&!n&&!o?{}:{Program(h){for(let f of c)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],c=" ".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]],`
|
|
59
|
+
`+c),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]],`
|
|
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),c=t.getTokenAfter(r,l=>l.value==="("),o=t.getTokenAfter(g,l=>l.value===")");if(!c||!o)return;let n=i?t.getFirstToken(s):null;if(r.loc.end.line!==c.loc.start.line){e.report({fix:l=>l.replaceTextRange([r.range[1],c.range[0]]," "),message:"Opening parenthesis should be on the same line as 'if'",node:c});return}let h=c.loc.end.line!==o.loc.start.line,f=t.getText(g);if(h&&I(g,f)){let l=f.replace(/\s+/g," ").trim();e.report({fix:a=>a.replaceTextRange([c.range[1],o.range[0]],l),message:"If condition should be on a single line",node:g});return}n&&o.loc.end.line!==n.loc.start.line&&e.report({fix:l=>l.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)),c=t.getTokenAfter(r,n=>n.value==="else");if(!c)return;c.loc.start.line-r.loc.end.line>1&&e.report({fix:n=>n.replaceTextRange([r.range[1],c.range[0]],`
|
|
61
|
+
`+" ".repeat(c.loc.start.column)),message:"No empty line allowed between single-line if and else",node:c})},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],c=g[i+1];if(r.type!=="IfStatement"||c.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=c.consequent.type==="BlockStatement";(h||f)&&c.loc.start.line-n.loc.end.line===1&&e.report({fix:a=>a.insertTextAfter(n,`
|
|
62
|
+
`),message:"Expected empty line between consecutive if statements with block bodies",node:c})}};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=l=>{let a=t.getTokenBefore(l),u=t.getTokenAfter(l);if(!a||!u)return!1;if(a.value==="("&&u.value===")"){if(l.parent.type==="IfStatement"&&l.parent.test===l){let T=t.getTokenBefore(a);if(T&&T.value==="if")return!1}return!0}return!1},g=l=>{let a=l.range[0],u=l.range[1],T=t.getTokenBefore(l),x=t.getTokenAfter(l);for(;T&&T.value==="("&&x&&x.value===")";){if(l.parent.type==="IfStatement"&&l.parent.test===l){let b=t.getTokenBefore(T);if(b&&b.value==="if")break}a=T.range[0],u=x.range[1],T=t.getTokenBefore(T),x=t.getTokenAfter(x)}return t.text.slice(a,u)},i=l=>{let a=[],u=T=>{T.type==="LogicalExpression"&&!s(T)?(u(T.left),u(T.right)):a.push(T)};return u(l),a},r=(l,a=0)=>{if(l.type!=="LogicalExpression")return a;let u=a;if(l.left.type==="LogicalExpression"){let T=s(l.left)?r(l.left,a+1):r(l.left,a);u=Math.max(u,T)}if(l.right.type==="LogicalExpression"){let T=s(l.right)?r(l.right,a+1):r(l.right,a);u=Math.max(u,T)}return u},c=(l,a=0,u=null)=>{if(l.type!=="LogicalExpression")return null;let T=null;if(l.left.type==="LogicalExpression"){let x=s(l.left),b=x?a+1:a;x&&b>y&&(T={node:l.left,depth:b,parent:l,side:"left"});let d=c(l.left,b,{node:l,side:"left"});d&&(!T||d.depth>T.depth)&&(T=d)}if(l.right.type==="LogicalExpression"){let x=s(l.right),b=x?a+1:a;if(x&&b>y){let E={node:l.right,depth:b,parent:l,side:"right"};(!T||E.depth>T.depth)&&(T=E)}let d=c(l.right,b,{node:l,side:"right"});d&&(!T||d.depth>T.depth)&&(T=d)}return T},o=l=>{if(l.type!=="LogicalExpression")return 1;let a=0,u=T=>{T.type==="LogicalExpression"&&!s(T)?(u(T.left),u(T.right)):a+=1};return u(l.left),u(l.right),a},n=l=>{if(l.type!=="LogicalExpression")return null;if(s(l)&&o(l)>C)return l;if(l.left.type==="LogicalExpression"){let a=n(l.left);if(a)return a}if(l.right.type==="LogicalExpression"){let a=n(l.right);if(a)return a}return null};return{IfStatement:l=>{let{test:a}=l;if(a.type!=="LogicalExpression")return;let u=i(a),T=t.getTokenBefore(a),x=t.getTokenAfter(a);if(!T||!x)return;let b=r(a);if(b>y){let v=c(a);if(v){let p=g(v.node),m=L=>{if(L.type==="LogicalExpression"){let R=m(L.left),P=m(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${m(v.node)}`;w.length>30&&(w="isNestedCondition"),e.report({fix:L=>{let R=[],P=l.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};
|
|
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 (${b}) exceeds maximum (${y}). Extract deeply nested condition to a variable.`,node:v.node});return}}let d=T.loc.start.line!==x.loc.end.line,E=v=>{if(v.type!=="BinaryExpression")return!1;let{left:p,right:m}=v;return!!(p.loc.end.line!==m.loc.start.line||E(p)||E(m))},A=v=>{if(v.type==="BinaryExpression"){let p=A(v.left),m=A(v.right);return`${p} ${v.operator} ${m}`}return t.getText(v)},S=n(a);if(S){let p=t.lines[l.loc.start.line-1].match(/^\s*/)[0],m=p+" ",w=(F,M=!1,j=m)=>{if(F.type==="LogicalExpression"&&(M||!s(F))){let N=w(F.left,!1,j),D=w(F.right,!1,j);return`${N}
|
|
64
64
|
${j}${F.operator} ${D}`}if(F.type==="LogicalExpression"&&s(F)&&o(F)>C){let D=j+" ",z=Y=>{if(Y.type==="LogicalExpression"&&!s(Y)){let ne=z(Y.left),J=z(Y.right);return`${ne}
|
|
65
65
|
${D}${Y.operator} ${J}`}return g(Y)},q=z(F.left),_=z(F.right);return`(
|
|
66
66
|
${D}${q}
|
|
67
67
|
${D}${F.operator} ${_}
|
|
68
68
|
${j})`}return g(F)},L=(F,M)=>{if(F===M){let j=w(F,!0);return`(
|
|
69
|
-
${
|
|
70
|
-
${p})`}if(F.type==="LogicalExpression"&&!s(F)){let j=L(F.left,M),N=L(F.right,M);return`${j} ${F.operator} ${N}`}if(F.type==="LogicalExpression"&&s(F)){let j=(N,D)=>N===D?!0:N.type==="LogicalExpression"?j(N.left,D)||j(N.right,D):!1;if(j(F,M))return`(${L(F,M)})`}return g(F)},P=(F=>{let M=[],j=N=>{N.type==="LogicalExpression"&&!s(N)?(j(N.left),j(N.right)):M.push(N)};return F.type==="LogicalExpression"&&(j(F.left),j(F.right)),M})(S);if(!P.every((F,M)=>M===0?!0:F.loc.start.line!==P[M-1].loc.start.line)){e.report({fix:F=>{let M=L(a,S);return F.replaceTextRange([
|
|
69
|
+
${m}${j}
|
|
70
|
+
${p})`}if(F.type==="LogicalExpression"&&!s(F)){let j=L(F.left,M),N=L(F.right,M);return`${j} ${F.operator} ${N}`}if(F.type==="LogicalExpression"&&s(F)){let j=(N,D)=>N===D?!0:N.type==="LogicalExpression"?j(N.left,D)||j(N.right,D):!1;if(j(F,M))return`(${L(F,M)})`}return g(F)},P=(F=>{let M=[],j=N=>{N.type==="LogicalExpression"&&!s(N)?(j(N.left),j(N.right)):M.push(N)};return F.type==="LogicalExpression"&&(j(F.left),j(F.right)),M})(S);if(!P.every((F,M)=>M===0?!0:F.loc.start.line!==P[M-1].loc.start.line)){e.report({fix:F=>{let M=L(a,S);return F.replaceTextRange([T.range[1],x.range[0]],M)},message:`Nested condition with >${C} operands should be formatted multiline`,node:S});return}}if(u.length<=C){if(n(a))return;let p=u[0].loc.start.line,m=u.every(L=>L.loc.start.line===p),w=u.some(L=>E(L));(!m||w)&&e.report({fix:L=>{let R=P=>{if(P.type==="LogicalExpression"&&!s(P)){let H=R(P.left),F=R(P.right);return`${H} ${P.operator} ${F}`}return P.type==="BinaryExpression"&&E(P)?A(P):g(P)};return L.replaceTextRange([T.range[0],x.range[1]],`(${R(a)})`)},message:`If conditions with \u2264${C} operands should be single line: if (a && b && c). Multi-line only for >${C} operands`,node:a});return}let k=v=>{if(v.type!=="LogicalExpression")return!1;let p=t.getTokenAfter(v.left,m=>m.value==="||"||m.value==="&&");if(p){let m=t.getTokenAfter(p);if(m&&p.loc.end.line<m.loc.start.line)return!0}return!!(k(v.left)||k(v.right))},$=!d;if(d){for(let v=0;v<u.length-1;v+=1)if(u[v].loc.end.line===u[v+1].loc.start.line){$=!0;break}T.loc.end.line===u[0].loc.start.line&&($=!0),!$&&k(a)&&($=!0)}$&&e.report({fix:v=>{let m=t.lines[l.loc.start.line-1].match(/^\s*/)[0],w=m+" ",L=w+" ",R=(P,H)=>{if(P.type==="LogicalExpression"&&!s(P)){let F=R(P.left,H),M=R(P.right,H);return`${F}
|
|
71
71
|
${H}${P.operator} ${M}`}if(P.type==="LogicalExpression"&&s(P)&&o(P)>C){let M=H+" ",j=z=>{if(z.type==="LogicalExpression"&&!s(z)){let q=j(z.left),_=j(z.right);return`${q}
|
|
72
72
|
${M}${z.operator} ${_}`}return g(z)},N=j(P.left),D=j(P.right);return`(
|
|
73
73
|
${M}${N}
|
|
74
74
|
${M}${P.operator} ${D}
|
|
75
|
-
${H})`}return g(P)};return v.replaceTextRange([
|
|
75
|
+
${H})`}return g(P)};return v.replaceTextRange([T.range[0],x.range[1]],`(
|
|
76
76
|
${w}${R(a,w)}
|
|
77
|
-
${
|
|
78
|
-
${p}${w.operator} ${R}`}return g(w)};return k.replaceText(a,
|
|
77
|
+
${m})`)},message:`If conditions with more than ${C} operands should be multiline, with each operand on its own line`,node:a})},Property:l=>{let{value:a}=l;if(!a||a.type!=="LogicalExpression")return;let u=i(a);if(u.length<2)return;let T=a.loc.start.line,x=a.loc.end.line,b=T!==x,d=k=>{if(k.type!=="BinaryExpression")return!1;let{left:$,right:v}=k;return!!($.loc.end.line!==v.loc.start.line||d($)||d(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=>d(p));(!$||v)&&e.report({fix:p=>{let m=w=>{if(w.type==="LogicalExpression"&&!s(w)){let L=m(w.left),R=m(w.right);return`${L} ${w.operator} ${R}`}return w.type==="BinaryExpression"&&d(w)?E(w):g(w)};return p.replaceText(a,m(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=!b;if(b){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[l.loc.start.line-1].match(/^\s*/)[0]+" ",m=w=>{if(w.type==="LogicalExpression"&&!s(w)){let L=m(w.left),R=m(w.right);return`${L}
|
|
78
|
+
${p}${w.operator} ${R}`}return g(w)};return k.replaceText(a,m(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 m=t.getTokenBefore(p),w=t.getTokenAfter(p);return!m||!w?!1:m.value==="("&&w.value===")"},g=p=>{let m=p.range[0],w=p.range[1],L=t.getTokenBefore(p),R=t.getTokenAfter(p);for(;L&&L.value==="("&&R&&R.value===")";)m=L.range[0],w=R.range[1],L=t.getTokenBefore(L),R=t.getTokenAfter(R);return t.text.slice(m,w)},i=p=>{let m=[],w=L=>{L.type==="LogicalExpression"&&!s(L)?(w(L.left),w(L.right)):m.push(L)};return w(p),m},r=(p,m=0)=>{if(p.type!=="LogicalExpression")return m;let w=m;if(p.left.type==="LogicalExpression"){let L=s(p.left)?r(p.left,m+1):r(p.left,m);w=Math.max(w,L)}if(p.right.type==="LogicalExpression"){let L=s(p.right)?r(p.right,m+1):r(p.right,m);w=Math.max(w,L)}return w},c=(p,m=0)=>{if(p.type!=="LogicalExpression")return null;let w=null;if(p.left.type==="LogicalExpression"){let L=s(p.left),R=L?m+1:m;L&&R>y&&(w={node:p.left,depth:R,parent:p,side:"left"});let P=c(p.left,R);P&&(!w||P.depth>w.depth)&&(w=P)}if(p.right.type==="LogicalExpression"){let L=s(p.right),R=L?m+1:m;if(L&&R>y){let H={node:p.right,depth:R,parent:p,side:"right"};(!w||H.depth>w.depth)&&(w=H)}let P=c(p.right,R);P&&(!w||P.depth>w.depth)&&(w=P)}return w},o=p=>{if(p.type==="LogicalExpression"){let m=o(p.left),w=o(p.right),L=p.operator==="&&"?"And":"Or";return`${m}${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 m=0,w=L=>{L.type==="LogicalExpression"&&!s(L)?(w(L.left),w(L.right)):m+=1};return w(p.left),w(p.right),m},h=p=>{if(p.type!=="LogicalExpression")return null;if(s(p)&&n(p)>C)return p;if(p.left.type==="LogicalExpression"){let m=h(p.left);if(m)return m}if(p.right.type==="LogicalExpression"){let m=h(p.right);if(m)return m}return null},f=p=>{if(p.type!=="BinaryExpression")return!1;let{left:m,right:w}=p;return!!(m.loc.end.line!==w.loc.start.line||f(m)||f(w))},l=p=>{if(p.type==="BinaryExpression"){let m=l(p.left),w=l(p.right);return`${m} ${p.operator} ${w}`}return t.getText(p)},a=p=>{if(p.type!=="LogicalExpression")return!1;let m=t.getTokenAfter(p.left,w=>w.value==="||"||w.value==="&&");if(m){let w=t.getTokenAfter(m);if(w&&m.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 m=i(p).length,w=h(p);return m<=C&&!w}return!1},T=p=>{let m=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`${m} ? ${w} : ${L}`},x=p=>t.lines[p.loc.start.line-1].match(/^\s*/)[0].length,b=p=>p?p.type==="JSXElement"||p.type==="JSXFragment"?!0:p.type==="ParenthesizedExpression"?b(p.expression):p.type==="ConditionalExpression"?b(p.consequent)||b(p.alternate):p.type==="LogicalExpression"?b(p.left)||b(p.right):!1:!1,d=p=>p.type==="ObjectExpression"&&p.properties.length>=2||p.type==="ArrayExpression"&&p.elements.length>=3,E=p=>b(p.consequent)||b(p.alternate),A=p=>{let m=w=>w.type==="ConditionalExpression"&&s(w)?i(w.test).length>C:!1;return m(p.consequent)||m(p.alternate)},S=p=>{let m=t.getTokenAfter(p.test,L=>L.value==="?"),w=t.getTokenAfter(p.consequent,L=>L.value===":");return!!(m&&p.consequent.loc.start.line!==m.loc.start.line||w&&p.alternate.loc.start.line!==w.loc.start.line)},k=p=>{let m=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)||d(p.consequent)||d(p.alternate)||E(p)||A(p)||m&&!w)return!1;let R=T(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:m}=p,w=i(m),L=m.loc.start.line,R=m.loc.end.line,P=L!==R,H=h(m);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
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}
|
|
80
80
|
${G}${X.operator} ${Q}`}return g(X)},B=le(J.left),O=le(J.right);return`(
|
|
81
81
|
${G}${B}
|
|
82
82
|
${G}${J.operator} ${O}
|
|
83
83
|
${U})`}return g(J)},q=(J,V)=>{if(J===V){let U=z(J,!0);return`(
|
|
84
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(
|
|
86
|
-
${q}${U.operator} ${G}`}return g(U)},Y=t.getText(p.consequent),ne=t.getText(p.alternate),V=`${_(
|
|
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(m,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(m))return;let N=d(p.consequent)||d(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 _=T(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(m)&&(F=!0),!F){let j=t.getTokenAfter(m,N=>N.value==="?");j&&j.loc.start.line===m.loc.end.line&&(F=!0)}if(!F){let j=t.getTokenAfter(m,N=>N.value==="?");j&&j.loc.start.line>m.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(m,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=`${_(m)}
|
|
87
87
|
${q}? ${Y}
|
|
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:
|
|
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(
|
|
90
|
-
`,
|
|
91
|
-
`);return h.replaceText(o,
|
|
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:m})},v=p=>{let m=p.parent;for(;m&&m.type==="ParenthesizedExpression";)m=m.parent;return m&&m.type==="ConditionalExpression"?m.consequent===p||m.alternate===p||p.parent.type==="ParenthesizedExpression"&&(m.consequent===p.parent||m.alternate===p.parent):!1};return{ConditionalExpression(p){let{test:m}=p;if(!v(p)){if(m.type==="LogicalExpression"){let w=r(m);if(w>y){let L=c(m);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};
|
|
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(m)&&k(p)||m.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(l=>l.value==="||"||l.value==="&&"||l.value==="??"||l.value==="|"||l.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 l=[t.getText(n[0])];for(let a=1;a<n.length;a++){let u=g(n[a-1],n[a]);l.push(` ${u} ${t.getText(n[a])}`)}return f.replaceText(o,l.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]),l=t.getFirstToken(n[0]),a=t.text.lastIndexOf(`
|
|
90
|
+
`,l.range[0])+1,T=t.text.slice(a,l.range[0]).match(/^(\s*)/),x=T?T[1]:"",b=[f];for(let E=1;E<n.length;E++){let A=g(n[E-1],n[E]),S=t.getText(n[E]);b.push(`${x} ${A} ${S}`)}let d=b.join(`
|
|
91
|
+
`);return h.replaceText(o,d)},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 c=C(s);r.loc.start.line-c<2&&e.report({fix:n=>{let h=t.getLastToken(s);return n.insertTextAfter(h,`
|
|
92
92
|
`)},message:"Expected empty line after block statement",node:r})}}},meta:{docs:{description:"Require empty line between block statement closing brace and next statement"},fixable:"whitespace",schema:[],type:"layout"}},Ye={create(e){let t=e.sourceCode||e.getSourceCode();return{SwitchCase:y=>{let{consequent:s,test:g}=y,i=t.getTokenAfter(g||t.getFirstToken(y),r=>r.value===":");if(s.length>0){let r=s[0];t.getTokensBetween(i,r,{includeComments:!0}).length===0&&r.loc.start.line-i.loc.end.line>1&&e.report({fix(o){return o.replaceTextRange([i.range[1],r.range[0]],`
|
|
93
|
-
${" ".repeat(r.loc.start.column)}`)},message:"Empty line not allowed at the beginning of case logic",node:r})}},SwitchStatement:y=>{let{cases:s}=y;for(let g=0;g<s.length-1;g+=1){let i=s[g],r=s[g+1];if(i.consequent.length===0){let
|
|
94
|
-
${" ".repeat(r.loc.start.column)}`)},message:"Empty line not allowed between cases",node:r})}}}}},meta:{docs:{description:"Prevent empty lines at the beginning of switch case logic or between cases"},fixable:"whitespace",schema:[],type:"layout"}};var Qe={create(e){let t=e.sourceCode||e.getSourceCode(),I=(C,y)=>{let s=t.getLastToken(y);if(C.typeArguments||C.typeParameters){let r=C.typeArguments||C.typeParameters,l=t.getFirstToken(r);if(l&&l.value==="<"){let h=t.text.slice(s.range[1],l.range[0]);/\s/.test(h)&&e.report({fix:f=>f.replaceTextRange([s.range[1],l.range[0]],""),message:"No space between function name and generic type arguments",node:l})}let o=t.getLastToken(r),n=t.getTokenAfter(r);if(n&&n.value==="("){let h=t.text.slice(o.range[1],n.range[0]);/\s/.test(h)&&e.report({fix:f=>f.replaceTextRange([o.range[1],n.range[0]],""),message:"No space between generic type arguments and opening parenthesis",node:n})}return}let g=t.getTokenAfter(y);if(!g||g.value!=="(")return;t.text.slice(s.range[1],g.range[0]).length>0&&e.report({fix:r=>r.replaceTextRange([s.range[1],g.range[0]],""),message:"No space between function name and opening parenthesis",node:g})};return{CallExpression(C){I(C,C.callee)},NewExpression(C){I(C,C.callee)}}},meta:{docs:{description:"Enforce no space between function name and opening parenthesis"},fixable:"code",schema:[],type:"layout"}},et={create(e){let t=e.sourceCode||e.getSourceCode();return{FunctionDeclaration(I){if(!I.id)return;let C=I.id.name,y=I.params.map(f=>t.getText(f)).join(", "),s="";I.returnType&&(s=t.getText(I.returnType));let g="";if(I.typeParameters){let f=t.getText(I.typeParameters);if(I.typeParameters.params&&I.typeParameters.params.length===1){let c=f.slice(1,-1).trim();c.endsWith(",")?g=f:g=`<${c},>`}else g=f}let r=I.async?"async ":"",l=t.getText(I.body),o=I.parent,n=o&&o.type==="ExportNamedDeclaration",h=n?"export ":"";e.report({fix(f){let c=n?o:I,a=`${h}const ${C} = ${g}${r}(${y})${s} => ${l};`;return f.replaceText(c,a)},message:`Expected a function expression. Use \`const ${C} = ${g}${r}(${y})${s} => ...\` instead.`,node:I.id})}}},meta:{docs:{description:"Enforce arrow function expressions instead of function declarations"},fixable:"code",schema:[],type:"suggestion"}},tt={create(e){let t=/^[A-Z][a-zA-Z0-9]*$/,I=/Handler$/,C=/^use[A-Z]/,y=["get","set","fetch","load","save","create","update","delete","remove","add","insert","append","prepend","push","pop","shift","unshift","put","patch","is","has","can","should","will","did","was","were","does","do","check","validate","verify","confirm","ensure","assert","test","match","find","search","filter","sort","map","reduce","merge","split","join","query","lookup","locate","detect","identify","discover","scan","probe","parse","format","convert","transform","normalize","serialize","deserialize","encode","decode","encrypt","decrypt","hash","sign","compress","decompress","stringify","objectify","flatten","unflatten","transpose","invert","strip","trim","pad","wrap","unwrap","sanitize","escape","unescape","capitalize","lowercase","uppercase","camel","snake","kebab","truncate","replace","substitute","interpolate","template","render","display","show","hide","toggle","enable","disable","activate","deactivate","highlight","focus","blur","select","deselect","expand","collapse","resize","animate","transition","fade","slide","zoom","rotate","scale","open","close","start","stop","init","setup","reset","clear","destroy","mount","unmount","attach","detach","bind","unbind","dispose","cleanup","register","unregister","install","uninstall","configure","reconfigure","connect","disconnect","subscribe","unsubscribe","listen","emit","broadcast","send","receive","request","respond","submit","cancel","abort","poll","download","upload","import","export","sync","stream","pipe","read","write","copy","move","clone","extract","archive","restore","backup","build","make","generate","compute","calculate","process","execute","run","evaluate","analyze","measure","benchmark","profile","optimize","count","sum","avg","min","max","clamp","round","floor","ceil","abs","increment","decrement","multiply","divide","mod","negate","apply","call","invoke","trigger","fire","dispatch","emit","raise","signal","login","logout","authenticate","authorize","grant","revoke","permit","deny","navigate","redirect","route","scroll","jump","go","back","forward","refresh","reload","restore","log","warn","error","debug","trace","print","dump","inspect","throw","catch","resolve","reject","retry","await","recover","fallback","forgot","debounce","throttle","memoize","cache","batch","queue","defer","delay","schedule","preload","prefetch","lazy","on","click","change","input","press","drag","drop","hover","enter","leave","touch","swipe","pinch","tap","compare","diff","equal","differ","overlap","intersect","union","exclude","group","ungroup","partition","chunk","segment","categorize","classify","order","reorder","arrange","reverse","shuffle","randomize","pick","sample","lock","unlock","freeze","unfreeze","seal","mark","unmark","flag","unflag","use","require","need","want","try","attempt","ensure","guarantee","prepare","finalize","complete","finish","end","begin","continue","resume","pause","suspend","interrupt","break","skip","ignore","include","exclude","accept","decline","approve","reject","confirm","dismiss","acknowledge","assign","allocate","distribute","collect","gather","aggregate","accumulate","populate","fill","empty","drain","flush","purge","prune","clean","sanitize","compose","decompose","assemble","disassemble","construct","deconstruct"],s=c=>y.some(a=>c.startsWith(a)),g=c=>{let a=c.toLowerCase();return y.some(u=>a.startsWith(u))},i=c=>c[0].toLowerCase()+c.slice(1),r=c=>I.test(c),l=c=>{if(!c)return!1;if(c.type==="JSXElement"||c.type==="JSXFragment")return!0;if(c.type==="BlockStatement"){for(let a of c.body)if(a.type==="ReturnStatement"&&a.argument&&l(a.argument)||a.type==="IfStatement"&&(l(a.consequent)||a.alternate&&l(a.alternate)))return!0}return c.type==="ConditionalExpression"?l(c.consequent)||l(c.alternate):c.type==="LogicalExpression"?l(c.left)||l(c.right):c.type==="ParenthesizedExpression"?l(c.expression):!1},o=(c,a)=>!a||!/^[A-Z]/.test(a)?!1:l(c.body),n=c=>{let a=null,u=null;if(c.type==="FunctionDeclaration"&&c.id)a=c.id.name,u=c.id;else if(c.type==="FunctionExpression"||c.type==="ArrowFunctionExpression"){if(c.parent&&c.parent.type==="VariableDeclarator"&&c.parent.id)a=c.parent.id.name,u=c.parent.id;else if(c.parent&&c.parent.type==="CallExpression"){let m=c.parent,E=m.callee;E&&E.type==="Identifier"&&E.name==="useCallback"&&m.arguments&&m.arguments[0]===c&&m.parent&&m.parent.type==="VariableDeclarator"&&m.parent.id&&(a=m.parent.id.name,u=m.parent.id)}}if(!a||!u||/^use[A-Z]/.test(a)||o(c,a))return;if(/^[A-Z]/.test(a)){if(g(a)){let m=i(a),E=c.id||c.parent.id;e.report({fix(A){let S=e.sourceCode?e.sourceCode.getScope(c):e.getScope(),k=S.variables.find(p=>p.name===a)||S.upper&&S.upper.variables.find(p=>p.name===a);if(!k)return A.replaceText(E,m);let $=[],v=new Set;return k.references.forEach(p=>{let d=`${p.identifier.range[0]}-${p.identifier.range[1]}`;v.has(d)||(v.add(d),$.push(A.replaceText(p.identifier,m)))}),$},message:`Function "${a}" should be camelCase. Use "${m}" instead of "${a}"`,node:c.id||c.parent.id})}return}let b=s(a),x=r(a);if(/^handle[A-Z]/.test(a)&&!x){let m=c.id||c.parent.id,E=a.slice(6),A=E[0].toLowerCase()+E.slice(1)+"Handler";e.report({fix(S){let k=e.sourceCode?e.sourceCode.getScope(c):e.getScope(),$=k.variables.find(w=>w.name===a)||k.upper&&k.upper.variables.find(w=>w.name===a);if(!$)return S.replaceText(m,A);let v=[],p=new Set,d=w=>{let L=`${w.range[0]}-${w.range[1]}`;p.has(L)||(p.add(L),v.push(S.replaceText(w,A)))};return $.defs.forEach(w=>{d(w.name)}),$.references.forEach(w=>{d(w.identifier)}),v},message:`Function "${a}" should be "${A}" (handleXxx \u2192 xxxHandler to avoid redundant "handleXxxHandler")`,node:m});return}if(!b&&!x)e.report({message:`Function "${a}" should start with a verb (get, set, fetch, etc.) AND end with "Handler" (e.g., getDataHandler, clickHandler)`,node:u});else if(!b)e.report({message:`Function "${a}" should start with a verb (get, set, fetch, handle, click, submit, etc.)`,node:u});else if(!x){let m=`${a}Handler`;e.report({fix(E){let A=e.sourceCode?e.sourceCode.getScope(c):e.getScope(),S=A.variables.find(p=>p.name===a)||A.upper&&A.upper.variables.find(p=>p.name===a);if(!S)return E.replaceText(u,m);let k=[],$=new Set,v=p=>{let d=`${p.range[0]}-${p.range[1]}`;$.has(d)||($.add(d),k.push(E.replaceText(p,m)))};return S.defs.forEach(p=>{v(p.name)}),S.references.forEach(p=>{v(p.identifier)}),k},message:`Function "${a}" should end with "Handler" suffix (e.g., ${m})`,node:u})}};return{ArrowFunctionExpression:n,FunctionDeclaration:n,FunctionExpression:n,MethodDefinition:c=>{if(c.kind==="constructor"||c.kind==="get"||c.kind==="set")return;let{key:a}=c;if(a.type!=="Identifier")return;let u=a.name;if(/^use[A-Z]/.test(u)||["render","componentDidMount","componentDidUpdate","componentWillUnmount","shouldComponentUpdate","getSnapshotBeforeUpdate","componentDidCatch","getDerivedStateFromProps","getDerivedStateFromError"].includes(u))return;let x=s(u),T=r(u);if(!x&&!T)e.report({message:`Method "${u}" should start with a verb (get, set, fetch, handle, etc.) AND end with "Handler" (e.g., getDataHandler, handleClickHandler)`,node:a});else if(!x)e.report({message:`Method "${u}" should start with a verb (get, set, fetch, handle, click, submit, etc.)`,node:a});else if(!T){let m=`${u}Handler`;e.report({fix(E){let A=[E.replaceText(a,m)],S=c.parent;if(S&&S.type==="ClassBody"){let k=S.parent;if(k){let $=new Set,v=p=>{if(!p||typeof p!="object"||$.has(p))return;$.add(p),p.type==="MemberExpression"&&p.property&&p.property.type==="Identifier"&&p.property.name===u&&p.object&&(p.object.type==="ThisExpression"||p.object.type==="Super")&&p.property!==a&&A.push(E.replaceText(p.property,m));let d=["body","declarations","expression","left","right","callee","arguments","object","property","consequent","alternate","test","init","update","params","elements","properties","value","key","argument","block","handler","finalizer","cases"];for(let w of d){let L=p[w];L&&(Array.isArray(L)?L.forEach(R=>v(R)):v(L))}};v(k)}}return A},message:`Method "${u}" should end with "Handler" suffix (e.g., ${m})`,node:a})}},VariableDeclarator:c=>{if(!c.init||c.init.type!=="CallExpression"||!c.id||c.id.type!=="ObjectPattern")return;let a=c.init.callee;if(!a||a.type!=="Identifier"||!C.test(a.name))return;let u=["login","logout","authenticate","authorize","signup","signout","signin","submit","reset","clear","refresh","reload","retry","toggle","enable","disable","activate","deactivate","show","hide","open","close","expand","collapse","navigate","redirect","goBack","goForward","increment","decrement","increase","decrease","connect","disconnect","subscribe","unsubscribe","start","stop","pause","resume","cancel","abort","select","deselect","check","uncheck","add","remove","insert","delete","update"];c.id.properties.forEach(b=>{if(b.type!=="Property"||b.key.type!=="Identifier")return;let x=b.key.name,T=b.value||b.key,m=T.type==="Identifier"?T.name:x;if(/^on[A-Z]/.test(m)||/Action$/.test(m)||I.test(m)||["is","has","can","should","will","did","was","were","does"].some(k=>m.startsWith(k)&&m.length>k.length&&/[A-Z]/.test(m[k.length]))||!u.some(k=>m===k||m.startsWith(k)&&m.length>k.length&&/[A-Z]/.test(m[k.length])))return;let S=m+"Handler";e.report({fix(k){let $=[],v=e.sourceCode||e.getSourceCode();b.shorthand?$.push(k.replaceText(b,`${x}: ${S}`)):$.push(k.replaceText(T,S));let p=v.getScope?v.getScope(c):e.getScope(),d=(L,R)=>{let P=L.variables.find(H=>H.name===R);return P||(L.upper?d(L.upper,R):null)},w=d(p,m);if(w){let L=new Set;T.range&&L.add(`${T.range[0]}-${T.range[1]}`),w.references.forEach(R=>{let P=`${R.identifier.range[0]}-${R.identifier.range[1]}`;L.has(P)||(L.add(P),$.push(k.replaceText(R.identifier,S)))})}return $},message:`Function "${m}" destructured from hook should end with "Handler" suffix. Use "${S}" instead`,node:T})})}}},meta:{docs:{description:"Enforce function and method names to start with a verb AND end with Handler"},fixable:"code",schema:[],type:"suggestion"}},nt={create(e){let t=e.sourceCode||e.getSourceCode(),I=r=>{if(r.type==="ObjectPattern"){let o=`{ ${r.properties.map(n=>{if(n.type==="RestElement")return`...${I(n.argument)}`;let h=t.getText(n.key),f;return n.value?n.value.type==="ObjectPattern"||n.value.type==="ArrayPattern"||n.value.type==="AssignmentPattern"?f=I(n.value):f=t.getText(n.value).replace(/\s+/g," ").trim():f=h,n.shorthand||n.value&&n.value.type==="Identifier"&&n.value.name===n.key.name?n.value&&n.value.type==="AssignmentPattern"?f:h:`${h}: ${f}`}).join(", ")} }`;if(r.typeAnnotation){let n=t.getText(r.typeAnnotation),h=r.typeAnnotation.typeAnnotation;if(h){let f=null;if(h.type==="TSTypeLiteral")f=h.members;else if(h.type==="TSIntersectionType"){let c=h.types.find(a=>a.type==="TSTypeLiteral");c&&(f=c.members)}f&&f.length===1&&(n=n.replace(/\s+/g," ").trim().replace(/,\s*}/," }").replace(/,\s*&/," &"))}o+=n}return o}if(r.type==="ArrayPattern")return`[${r.elements.map(o=>o===null?"":I(o)).join(", ")}]`;if(r.type==="AssignmentPattern"){let l=I(r.left),o=t.getText(r.right).replace(/\s+/g," ").trim();return`${l} = ${o}`}return r.type==="RestElement"?`...${I(r.argument)}`:t.getText(r).replace(/\s+/g," ").trim()},C=r=>{if(!r)return!1;if(r.type==="AssignmentPattern")return C(r.left);if(r.type==="ObjectPattern"){if(r.properties.length>=2)return!0;if(r.typeAnnotation&&r.typeAnnotation.typeAnnotation){let l=r.typeAnnotation.typeAnnotation;if(l.type==="TSTypeLiteral"&&l.members.length>=2)return!0;if(l.type==="TSIntersectionType"){let o=l.types.find(n=>n.type==="TSTypeLiteral");if(o&&o.members.length>=2)return!0}}for(let l of r.properties)if(l.type==="Property"&&l.value&&C(l.value))return!0}if(r.type==="ArrayPattern"){let l=r.elements.filter(o=>o!==null);if(l.length>=2)return!0;for(let o of l)if(C(o))return!0}return!1},y=r=>r.some(l=>C(l)),s=(r,l)=>{let o=r;if(r.type==="AssignmentPattern"&&(o=r.left),o.type==="ObjectPattern"){let n=o.properties,h=n.some(T=>T.type==="Property"&&T.value?C(T.value):!1),f=n.length>=2||h;for(let T of n)if(T.type==="Property"&&T.value){let m=l+4;s(T.value,m)}if(!f)return;let c=t.getFirstToken(o),a=n[n.length-1],u=t.getTokenAfter(a);for(;u&&u.value!=="}";)u=t.getTokenAfter(u);let b=" ".repeat(l+4),x=" ".repeat(l);if(c.loc.end.line===n[0].loc.start.line&&e.report({fix:T=>T.replaceTextRange([c.range[1],n[0].range[0]],`
|
|
95
|
-
`+
|
|
96
|
-
`+x+"}"):
|
|
97
|
-
`+x),message:"Closing brace should be on its own line when complex destructuring",node:u})}for(let
|
|
98
|
-
`+
|
|
99
|
-
`+
|
|
100
|
-
`+a),message:"Closing bracket should be on its own line when 2+ elements",node:f});for(let u=0;u<n.length-1;u+=1){let
|
|
101
|
-
`+
|
|
102
|
-
`+S),message:"Callback arrow with 2+ params: first param should be on its own line",node:
|
|
103
|
-
`+k),message:"Callback arrow with 2+ params: closing paren should be on its own line",node:f});for(let $=0;$<
|
|
104
|
-
`+S),message:"Callback arrow with 2+ params: each param should be on its own line",node:p})}}for(let $ of
|
|
105
|
-
`+x),message:"First parameter should be on its own line when more than 2 parameters or has destructuring",node:
|
|
106
|
-
`+
|
|
107
|
-
`+x),message:"Each parameter should be on its own line when more than 2 parameters or has destructuring",node:S})}}for(let E of
|
|
93
|
+
${" ".repeat(r.loc.start.column)}`)},message:"Empty line not allowed at the beginning of case logic",node:r})}},SwitchStatement:y=>{let{cases:s}=y;for(let g=0;g<s.length-1;g+=1){let i=s[g],r=s[g+1];if(i.consequent.length===0){let c=t.getTokenAfter(i.test||t.getFirstToken(i),n=>n.value===":");t.getTokensBetween(c,r,{includeComments:!0}).length===0&&r.loc.start.line-c.loc.end.line>1&&e.report({fix(n){return n.replaceTextRange([c.range[1],r.range[0]],`
|
|
94
|
+
${" ".repeat(r.loc.start.column)}`)},message:"Empty line not allowed between cases",node:r})}}}}},meta:{docs:{description:"Prevent empty lines at the beginning of switch case logic or between cases"},fixable:"whitespace",schema:[],type:"layout"}};var Qe={create(e){let t=e.sourceCode||e.getSourceCode(),I=(C,y)=>{let s=t.getLastToken(y);if(C.typeArguments||C.typeParameters){let r=C.typeArguments||C.typeParameters,c=t.getFirstToken(r);if(c&&c.value==="<"){let h=t.text.slice(s.range[1],c.range[0]);/\s/.test(h)&&e.report({fix:f=>f.replaceTextRange([s.range[1],c.range[0]],""),message:"No space between function name and generic type arguments",node:c})}let o=t.getLastToken(r),n=t.getTokenAfter(r);if(n&&n.value==="("){let h=t.text.slice(o.range[1],n.range[0]);/\s/.test(h)&&e.report({fix:f=>f.replaceTextRange([o.range[1],n.range[0]],""),message:"No space between generic type arguments and opening parenthesis",node:n})}return}let g=t.getTokenAfter(y);if(!g||g.value!=="(")return;t.text.slice(s.range[1],g.range[0]).length>0&&e.report({fix:r=>r.replaceTextRange([s.range[1],g.range[0]],""),message:"No space between function name and opening parenthesis",node:g})};return{CallExpression(C){I(C,C.callee)},NewExpression(C){I(C,C.callee)}}},meta:{docs:{description:"Enforce no space between function name and opening parenthesis"},fixable:"code",schema:[],type:"layout"}},et={create(e){let t=e.sourceCode||e.getSourceCode();return{FunctionDeclaration(I){if(!I.id)return;let C=I.id.name,y=I.params.map(f=>t.getText(f)).join(", "),s="";I.returnType&&(s=t.getText(I.returnType));let g="";if(I.typeParameters){let f=t.getText(I.typeParameters);if(I.typeParameters.params&&I.typeParameters.params.length===1){let l=f.slice(1,-1).trim();l.endsWith(",")?g=f:g=`<${l},>`}else g=f}let r=I.async?"async ":"",c=t.getText(I.body),o=I.parent,n=o&&o.type==="ExportNamedDeclaration",h=n?"export ":"";e.report({fix(f){let l=n?o:I,a=`${h}const ${C} = ${g}${r}(${y})${s} => ${c};`;return f.replaceText(l,a)},message:`Expected a function expression. Use \`const ${C} = ${g}${r}(${y})${s} => ...\` instead.`,node:I.id})}}},meta:{docs:{description:"Enforce arrow function expressions instead of function declarations"},fixable:"code",schema:[],type:"suggestion"}},tt={create(e){let t=/^[A-Z][a-zA-Z0-9]*$/,I=/Handler$/,C=/^use[A-Z]/,y=["get","set","fetch","load","save","create","update","delete","remove","add","insert","append","prepend","push","pop","shift","unshift","put","patch","is","has","can","should","will","did","was","were","does","do","check","validate","verify","confirm","ensure","assert","test","match","find","search","filter","sort","map","reduce","merge","split","join","query","lookup","locate","detect","identify","discover","scan","probe","parse","format","convert","transform","normalize","serialize","deserialize","encode","decode","encrypt","decrypt","hash","sign","compress","decompress","stringify","objectify","flatten","unflatten","transpose","invert","strip","trim","pad","wrap","unwrap","sanitize","escape","unescape","capitalize","lowercase","uppercase","camel","snake","kebab","truncate","replace","substitute","interpolate","template","render","display","show","hide","toggle","enable","disable","activate","deactivate","highlight","focus","blur","select","deselect","expand","collapse","resize","animate","transition","fade","slide","zoom","rotate","scale","open","close","start","stop","init","setup","reset","clear","destroy","mount","unmount","attach","detach","bind","unbind","dispose","cleanup","register","unregister","install","uninstall","configure","reconfigure","connect","disconnect","subscribe","unsubscribe","listen","emit","broadcast","send","receive","request","respond","submit","cancel","abort","poll","download","upload","import","export","sync","stream","pipe","read","write","copy","move","clone","extract","archive","restore","backup","build","make","generate","compute","calculate","process","execute","run","evaluate","analyze","measure","benchmark","profile","optimize","count","sum","avg","min","max","clamp","round","floor","ceil","abs","increment","decrement","multiply","divide","mod","negate","apply","call","invoke","trigger","fire","dispatch","emit","raise","signal","login","logout","authenticate","authorize","grant","revoke","permit","deny","navigate","redirect","route","scroll","jump","go","back","forward","refresh","reload","restore","log","warn","error","debug","trace","print","dump","inspect","throw","catch","resolve","reject","retry","await","recover","fallback","forgot","debounce","throttle","memoize","cache","batch","queue","defer","delay","schedule","preload","prefetch","lazy","on","click","change","input","press","drag","drop","hover","enter","leave","touch","swipe","pinch","tap","compare","diff","equal","differ","overlap","intersect","union","exclude","group","ungroup","partition","chunk","segment","categorize","classify","order","reorder","arrange","reverse","shuffle","randomize","pick","sample","lock","unlock","freeze","unfreeze","seal","mark","unmark","flag","unflag","use","require","need","want","try","attempt","ensure","guarantee","prepare","finalize","complete","finish","end","begin","continue","resume","pause","suspend","interrupt","break","skip","ignore","include","exclude","accept","decline","approve","reject","confirm","dismiss","acknowledge","assign","allocate","distribute","collect","gather","aggregate","accumulate","populate","fill","empty","drain","flush","purge","prune","clean","sanitize","compose","decompose","assemble","disassemble","construct","deconstruct"],s=l=>y.some(a=>l.startsWith(a)),g=l=>{let a=l.toLowerCase();return y.some(u=>a.startsWith(u))},i=l=>l[0].toLowerCase()+l.slice(1),r=l=>I.test(l),c=l=>{if(!l)return!1;if(l.type==="JSXElement"||l.type==="JSXFragment")return!0;if(l.type==="BlockStatement"){for(let a of l.body)if(a.type==="ReturnStatement"&&a.argument&&c(a.argument)||a.type==="IfStatement"&&(c(a.consequent)||a.alternate&&c(a.alternate)))return!0}return l.type==="ConditionalExpression"?c(l.consequent)||c(l.alternate):l.type==="LogicalExpression"?c(l.left)||c(l.right):l.type==="ParenthesizedExpression"?c(l.expression):!1},o=(l,a)=>!a||!/^[A-Z]/.test(a)?!1:c(l.body),n=l=>{let a=null,u=null;if(l.type==="FunctionDeclaration"&&l.id)a=l.id.name,u=l.id;else if(l.type==="FunctionExpression"||l.type==="ArrowFunctionExpression"){if(l.parent&&l.parent.type==="VariableDeclarator"&&l.parent.id)a=l.parent.id.name,u=l.parent.id;else if(l.parent&&l.parent.type==="CallExpression"){let d=l.parent,E=d.callee;E&&E.type==="Identifier"&&E.name==="useCallback"&&d.arguments&&d.arguments[0]===l&&d.parent&&d.parent.type==="VariableDeclarator"&&d.parent.id&&(a=d.parent.id.name,u=d.parent.id)}}if(!a||!u||/^use[A-Z]/.test(a)||o(l,a))return;if(/^[A-Z]/.test(a)){if(g(a)){let d=i(a),E=l.id||l.parent.id;e.report({fix(A){let S=e.sourceCode?e.sourceCode.getScope(l):e.getScope(),k=S.variables.find(p=>p.name===a)||S.upper&&S.upper.variables.find(p=>p.name===a);if(!k)return A.replaceText(E,d);let $=[],v=new Set;return k.references.forEach(p=>{let m=`${p.identifier.range[0]}-${p.identifier.range[1]}`;v.has(m)||(v.add(m),$.push(A.replaceText(p.identifier,d)))}),$},message:`Function "${a}" should be camelCase. Use "${d}" instead of "${a}"`,node:l.id||l.parent.id})}return}let T=s(a),x=r(a);if(/^handle[A-Z]/.test(a)&&!x){let d=l.id||l.parent.id,E=a.slice(6),A=E[0].toLowerCase()+E.slice(1)+"Handler";e.report({fix(S){let k=e.sourceCode?e.sourceCode.getScope(l):e.getScope(),$=k.variables.find(w=>w.name===a)||k.upper&&k.upper.variables.find(w=>w.name===a);if(!$)return S.replaceText(d,A);let v=[],p=new Set,m=w=>{let L=`${w.range[0]}-${w.range[1]}`;p.has(L)||(p.add(L),v.push(S.replaceText(w,A)))};return $.defs.forEach(w=>{m(w.name)}),$.references.forEach(w=>{m(w.identifier)}),v},message:`Function "${a}" should be "${A}" (handleXxx \u2192 xxxHandler to avoid redundant "handleXxxHandler")`,node:d});return}if(!T&&!x)e.report({message:`Function "${a}" should start with a verb (get, set, fetch, etc.) AND end with "Handler" (e.g., getDataHandler, clickHandler)`,node:u});else if(!T)e.report({message:`Function "${a}" should start with a verb (get, set, fetch, handle, click, submit, etc.)`,node:u});else if(!x){let d=`${a}Handler`;e.report({fix(E){let A=e.sourceCode?e.sourceCode.getScope(l):e.getScope(),S=A.variables.find(p=>p.name===a)||A.upper&&A.upper.variables.find(p=>p.name===a);if(!S)return E.replaceText(u,d);let k=[],$=new Set,v=p=>{let m=`${p.range[0]}-${p.range[1]}`;$.has(m)||($.add(m),k.push(E.replaceText(p,d)))};return S.defs.forEach(p=>{v(p.name)}),S.references.forEach(p=>{v(p.identifier)}),k},message:`Function "${a}" should end with "Handler" suffix (e.g., ${d})`,node:u})}};return{ArrowFunctionExpression:n,FunctionDeclaration:n,FunctionExpression:n,MethodDefinition:l=>{if(l.kind==="constructor"||l.kind==="get"||l.kind==="set")return;let{key:a}=l;if(a.type!=="Identifier")return;let u=a.name;if(/^use[A-Z]/.test(u)||["render","componentDidMount","componentDidUpdate","componentWillUnmount","shouldComponentUpdate","getSnapshotBeforeUpdate","componentDidCatch","getDerivedStateFromProps","getDerivedStateFromError"].includes(u))return;let x=s(u),b=r(u);if(!x&&!b)e.report({message:`Method "${u}" should start with a verb (get, set, fetch, handle, etc.) AND end with "Handler" (e.g., getDataHandler, handleClickHandler)`,node:a});else if(!x)e.report({message:`Method "${u}" should start with a verb (get, set, fetch, handle, click, submit, etc.)`,node:a});else if(!b){let d=`${u}Handler`;e.report({fix(E){let A=[E.replaceText(a,d)],S=l.parent;if(S&&S.type==="ClassBody"){let k=S.parent;if(k){let $=new Set,v=p=>{if(!p||typeof p!="object"||$.has(p))return;$.add(p),p.type==="MemberExpression"&&p.property&&p.property.type==="Identifier"&&p.property.name===u&&p.object&&(p.object.type==="ThisExpression"||p.object.type==="Super")&&p.property!==a&&A.push(E.replaceText(p.property,d));let m=["body","declarations","expression","left","right","callee","arguments","object","property","consequent","alternate","test","init","update","params","elements","properties","value","key","argument","block","handler","finalizer","cases"];for(let w of m){let L=p[w];L&&(Array.isArray(L)?L.forEach(R=>v(R)):v(L))}};v(k)}}return A},message:`Method "${u}" should end with "Handler" suffix (e.g., ${d})`,node:a})}},VariableDeclarator:l=>{if(!l.init||l.init.type!=="CallExpression"||!l.id||l.id.type!=="ObjectPattern")return;let a=l.init.callee;if(!a||a.type!=="Identifier"||!C.test(a.name))return;let u=["login","logout","authenticate","authorize","signup","signout","signin","submit","reset","clear","refresh","reload","retry","toggle","enable","disable","activate","deactivate","show","hide","open","close","expand","collapse","navigate","redirect","goBack","goForward","increment","decrement","increase","decrease","connect","disconnect","subscribe","unsubscribe","start","stop","pause","resume","cancel","abort","select","deselect","check","uncheck","add","remove","insert","delete","update"];l.id.properties.forEach(T=>{if(T.type!=="Property"||T.key.type!=="Identifier")return;let x=T.key.name,b=T.value||T.key,d=b.type==="Identifier"?b.name:x;if(/^on[A-Z]/.test(d)||/Action$/.test(d)||I.test(d)||["is","has","can","should","will","did","was","were","does"].some(k=>d.startsWith(k)&&d.length>k.length&&/[A-Z]/.test(d[k.length]))||!u.some(k=>d===k||d.startsWith(k)&&d.length>k.length&&/[A-Z]/.test(d[k.length])))return;let S=d+"Handler";e.report({fix(k){let $=[],v=e.sourceCode||e.getSourceCode();T.shorthand?$.push(k.replaceText(T,`${x}: ${S}`)):$.push(k.replaceText(b,S));let p=v.getScope?v.getScope(l):e.getScope(),m=(L,R)=>{let P=L.variables.find(H=>H.name===R);return P||(L.upper?m(L.upper,R):null)},w=m(p,d);if(w){let L=new Set;b.range&&L.add(`${b.range[0]}-${b.range[1]}`),w.references.forEach(R=>{let P=`${R.identifier.range[0]}-${R.identifier.range[1]}`;L.has(P)||(L.add(P),$.push(k.replaceText(R.identifier,S)))})}return $},message:`Function "${d}" destructured from hook should end with "Handler" suffix. Use "${S}" instead`,node:b})})}}},meta:{docs:{description:"Enforce function and method names to start with a verb AND end with Handler"},fixable:"code",schema:[],type:"suggestion"}},nt={create(e){let t=e.sourceCode||e.getSourceCode(),I=r=>{if(r.type==="ObjectPattern"){let o=`{ ${r.properties.map(n=>{if(n.type==="RestElement")return`...${I(n.argument)}`;let h=t.getText(n.key),f;return n.value?n.value.type==="ObjectPattern"||n.value.type==="ArrayPattern"||n.value.type==="AssignmentPattern"?f=I(n.value):f=t.getText(n.value).replace(/\s+/g," ").trim():f=h,n.shorthand||n.value&&n.value.type==="Identifier"&&n.value.name===n.key.name?n.value&&n.value.type==="AssignmentPattern"?f:h:`${h}: ${f}`}).join(", ")} }`;if(r.typeAnnotation){let n=t.getText(r.typeAnnotation),h=r.typeAnnotation.typeAnnotation;if(h){let f=null;if(h.type==="TSTypeLiteral")f=h.members;else if(h.type==="TSIntersectionType"){let l=h.types.find(a=>a.type==="TSTypeLiteral");l&&(f=l.members)}f&&f.length===1&&(n=n.replace(/\s+/g," ").trim().replace(/,\s*}/," }").replace(/,\s*&/," &"))}o+=n}return o}if(r.type==="ArrayPattern")return`[${r.elements.map(o=>o===null?"":I(o)).join(", ")}]`;if(r.type==="AssignmentPattern"){let c=I(r.left),o=t.getText(r.right).replace(/\s+/g," ").trim();return`${c} = ${o}`}return r.type==="RestElement"?`...${I(r.argument)}`:t.getText(r).replace(/\s+/g," ").trim()},C=r=>{if(!r)return!1;if(r.type==="AssignmentPattern")return C(r.left);if(r.type==="ObjectPattern"){if(r.properties.length>=2)return!0;if(r.typeAnnotation&&r.typeAnnotation.typeAnnotation){let c=r.typeAnnotation.typeAnnotation;if(c.type==="TSTypeLiteral"&&c.members.length>=2)return!0;if(c.type==="TSIntersectionType"){let o=c.types.find(n=>n.type==="TSTypeLiteral");if(o&&o.members.length>=2)return!0}}for(let c of r.properties)if(c.type==="Property"&&c.value&&C(c.value))return!0}if(r.type==="ArrayPattern"){let c=r.elements.filter(o=>o!==null);if(c.length>=2)return!0;for(let o of c)if(C(o))return!0}return!1},y=r=>r.some(c=>C(c)),s=(r,c)=>{let o=r;if(r.type==="AssignmentPattern"&&(o=r.left),o.type==="ObjectPattern"){let n=o.properties,h=n.some(b=>b.type==="Property"&&b.value?C(b.value):!1),f=n.length>=2||h;for(let b of n)if(b.type==="Property"&&b.value){let d=c+4;s(b.value,d)}if(!f)return;let l=t.getFirstToken(o),a=n[n.length-1],u=t.getTokenAfter(a);for(;u&&u.value!=="}";)u=t.getTokenAfter(u);let T=" ".repeat(c+4),x=" ".repeat(c);if(l.loc.end.line===n[0].loc.start.line&&e.report({fix:b=>b.replaceTextRange([l.range[1],n[0].range[0]],`
|
|
95
|
+
`+T),message:"First destructured property should be on its own line when complex destructuring",node:n[0]}),u.loc.start.line===n[n.length-1].loc.end.line){let b=o.typeAnnotation;e.report({fix:d=>b?d.replaceTextRange([n[n.length-1].range[1],u.range[1]],`,
|
|
96
|
+
`+x+"}"):d.replaceTextRange([n[n.length-1].range[1],u.range[0]],`,
|
|
97
|
+
`+x),message:"Closing brace should be on its own line when complex destructuring",node:u})}for(let b=0;b<n.length-1;b+=1){let d=n[b],E=n[b+1];if(d.loc.end.line===E.loc.start.line){let A=t.getTokenAfter(d,S=>S.value===",");e.report({fix:S=>S.replaceTextRange([A.range[1],E.range[0]],`
|
|
98
|
+
`+T),message:"Each destructured property should be on its own line when complex destructuring",node:E})}}}if(o.type==="ArrayPattern"){let n=o.elements.filter(u=>u!==null);for(let u of n)if(u){let T=c+4;s(u,T)}if(n.length<2)return;let h=t.getFirstToken(o),f=t.getLastToken(o),l=" ".repeat(c+4),a=" ".repeat(c);h.loc.end.line===n[0].loc.start.line&&e.report({fix:u=>u.replaceTextRange([h.range[1],n[0].range[0]],`
|
|
99
|
+
`+l),message:"First destructured element should be on its own line when 2+ elements",node:n[0]}),f.loc.start.line===n[n.length-1].loc.end.line&&e.report({fix:u=>u.replaceTextRange([n[n.length-1].range[1],f.range[0]],`,
|
|
100
|
+
`+a),message:"Closing bracket should be on its own line when 2+ elements",node:f});for(let u=0;u<n.length-1;u+=1){let T=n[u],x=n[u+1];if(T.loc.end.line===x.loc.start.line){let b=t.getTokenAfter(T,d=>d.value===",");e.report({fix:d=>d.replaceTextRange([b.range[1],x.range[0]],`
|
|
101
|
+
`+l),message:"Each destructured element should be on its own line when 2+ elements",node:x})}}}},g=r=>{if(r.type!=="ArrowFunctionExpression")return!1;let{parent:c}=r;return c&&c.type==="CallExpression"&&c.arguments.includes(r)},i=r=>{let c=r.params;if(c.length===0)return;let o=g(r),n=t.getFirstToken(r);for(;n&&n.value!=="(";)n=t.getTokenAfter(n);if(!n)return;let h=c[c.length-1],f=t.getTokenAfter(h,E=>E.value===")");if(!f)return;let l=c[0],a=n.loc.end.line!==f.loc.start.line,u=c.map(E=>I(E)).join(", "),T=t.text.slice(n.range[1],f.range[0]);if(o&&c.length>=2){let A=t.lines[n.loc.start.line-1].match(/^(\s*)/)[1].length,S=" ".repeat(A+4),k=" ".repeat(A);n.loc.end.line===l.loc.start.line&&e.report({fix:$=>$.replaceTextRange([n.range[1],l.range[0]],`
|
|
102
|
+
`+S),message:"Callback arrow with 2+ params: first param should be on its own line",node:l}),f.loc.start.line===h.loc.end.line&&e.report({fix:$=>$.replaceTextRange([h.range[1],f.range[0]],`,
|
|
103
|
+
`+k),message:"Callback arrow with 2+ params: closing paren should be on its own line",node:f});for(let $=0;$<c.length-1;$+=1){let v=c[$],p=c[$+1];if(v.loc.end.line===p.loc.start.line){let m=t.getTokenAfter(v,w=>w.value===",");e.report({fix:w=>w.replaceTextRange([m.range[1],p.range[0]],`
|
|
104
|
+
`+S),message:"Callback arrow with 2+ params: each param should be on its own line",node:p})}}for(let $ of c){let v=$.loc.start.column;s($,v)}return}if(o)return;if(c.length<=2&&!y(c)){let E=!a&&c.length>1&&T!==u;(a||E)&&e.report({fix:A=>A.replaceTextRange([n.range[1],f.range[0]],u),message:a?"Function parameters should be on same line when 2 or fewer without complex destructuring":"Missing space after comma between parameters",node:r});return}let x=" ".repeat(l.loc.start.column),b=" ".repeat(n.loc.start.column),d=c.length===1&&(l.type==="ObjectPattern"||l.type==="AssignmentPattern"&&l.left.type==="ObjectPattern");!d&&n.loc.end.line===l.loc.start.line&&e.report({fix:E=>E.replaceTextRange([n.range[1],l.range[0]],`
|
|
105
|
+
`+x),message:"First parameter should be on its own line when more than 2 parameters or has destructuring",node:l}),!d&&f.loc.start.line===h.loc.end.line&&e.report({fix:E=>E.replaceTextRange([h.range[1],f.range[0]],`,
|
|
106
|
+
`+b),message:"Closing parenthesis should be on its own line when more than 2 parameters or has destructuring",node:f});for(let E=0;E<c.length-1;E+=1){let A=c[E],S=c[E+1];if(A.loc.end.line===S.loc.start.line){let k=t.getTokenAfter(A,$=>$.value===",");e.report({fix:$=>$.replaceTextRange([k.range[1],S.range[0]],`
|
|
107
|
+
`+x),message:"Each parameter should be on its own line when more than 2 parameters or has destructuring",node:S})}}for(let E of c){let A=E.loc.start.column;s(E,A)}};return{ArrowFunctionExpression:i,FunctionDeclaration:i,FunctionExpression:i}},meta:{docs:{description:"Enforce function parameters on separate lines when more than 2"},fixable:"whitespace",schema:[],type:"layout"}},rt={create(e){let t=e.sourceCode||e.getSourceCode(),I=y=>{let s=y.params;if(s.length===0)return;let g=s[0],i=s[s.length-1],r=t.getTokenBefore(g);if(r&&r.value==="("&&r.range[0]>=y.range[0]){let o=r,n=t.getTokenAfter(i);n&&n.value===")"&&n.range[1]<=(y.body?y.body.range[0]:y.range[1])&&(g.loc.start.line-o.loc.end.line>1&&e.report({fix:h=>h.replaceTextRange([o.range[1],g.range[0]],`
|
|
108
108
|
`+" ".repeat(g.loc.start.column)),message:"No empty line after opening parenthesis in function parameters",node:g}),n.loc.start.line-i.loc.end.line>1&&e.report({fix:h=>h.replaceTextRange([i.range[1],n.range[0]],`
|
|
109
|
-
`+" ".repeat(n.loc.start.column)),message:"No empty line before closing parenthesis in function parameters",node:i}))}for(let o=0;o<s.length-1;o+=1){let n=s[o],h=s[o+1];if(h.loc.start.line-n.loc.end.line>1){let f=t.getTokenAfter(n,
|
|
109
|
+
`+" ".repeat(n.loc.start.column)),message:"No empty line before closing parenthesis in function parameters",node:i}))}for(let o=0;o<s.length-1;o+=1){let n=s[o],h=s[o+1];if(h.loc.start.line-n.loc.end.line>1){let f=t.getTokenAfter(n,l=>l.value===",");e.report({fix:l=>l.replaceTextRange([f.range[1],h.range[0]],`
|
|
110
110
|
`+" ".repeat(h.loc.start.column)),message:"No empty line between function parameters",node:h})}}s.forEach(o=>{if(o.type==="ObjectPattern"&&o.properties.length>0){let n=o.properties[0],h=o.properties[o.properties.length-1],f=t.getFirstToken(o);f&&f.value==="{"&&n.loc.start.line-f.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([f.range[1],n.range[0]],`
|
|
111
|
-
`+" ".repeat(n.loc.start.column)),message:"No empty line after opening brace in destructuring",node:n});let
|
|
112
|
-
`+" ".repeat(
|
|
113
|
-
`+" ".repeat(
|
|
114
|
-
`+" ".repeat(s.loc.start.column)),message:"No empty line after opening brace in type definition",node:s});let r=t.getLastToken(y);r&&r.value==="}"&&r.loc.start.line-g.loc.end.line>1&&e.report({fix:
|
|
115
|
-
`+" ".repeat(r.loc.start.column)),message:"No empty line before closing brace in type definition",node:g});for(let
|
|
116
|
-
`+" ".repeat(n.loc.start.column)),message:"No empty lines between type members",node:n})}}}},meta:{docs:{description:"Disallow empty lines in function parameters and type definitions"},fixable:"whitespace",schema:[],type:"layout"}},st={create(e){let t=e.sourceCode||e.getSourceCode(),I=new Set,C=["api","apis","config","configs","constants","data","helpers","lib","routes","services","utils","utilities"],y=x=>C.some(
|
|
117
|
-
`);R!==-1&&(
|
|
118
|
-
`);R!==-1&&(w=x.range[1]+R+1)}$.push(k.removeRange([
|
|
119
|
-
${L}`;p.push(v.insertTextBefore(
|
|
111
|
+
`+" ".repeat(n.loc.start.column)),message:"No empty line after opening brace in destructuring",node:n});let l=t.getTokenAfter(h,a=>a.value==="}");if(l&&l.loc.start.line-h.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([h.range[1],l.range[0]],`
|
|
112
|
+
`+" ".repeat(l.loc.start.column)),message:"No empty line before closing brace in destructuring",node:h}),o.properties.length>1)for(let a=0;a<o.properties.length-1;a+=1){let u=o.properties[a],T=o.properties[a+1];if(T.loc.start.line-u.loc.end.line>1){let x=t.getTokenAfter(u,b=>b.value===",");e.report({fix:b=>b.replaceTextRange([x.range[1],T.range[0]],`
|
|
113
|
+
`+" ".repeat(T.loc.start.column)),message:"No empty lines between destructured properties",node:T})}}}})};return{ArrowFunctionExpression:I,FunctionDeclaration:I,FunctionExpression:I,TSTypeLiteral:y=>{if(!y.members||y.members.length===0)return;let s=y.members[0],g=y.members[y.members.length-1],i=t.getFirstToken(y);i&&i.value==="{"&&s.loc.start.line-i.loc.end.line>1&&e.report({fix:c=>c.replaceTextRange([i.range[1],s.range[0]],`
|
|
114
|
+
`+" ".repeat(s.loc.start.column)),message:"No empty line after opening brace in type definition",node:s});let r=t.getLastToken(y);r&&r.value==="}"&&r.loc.start.line-g.loc.end.line>1&&e.report({fix:c=>c.replaceTextRange([g.range[1],r.range[0]],`
|
|
115
|
+
`+" ".repeat(r.loc.start.column)),message:"No empty line before closing brace in type definition",node:g});for(let c=0;c<y.members.length-1;c+=1){let o=y.members[c],n=y.members[c+1];n.loc.start.line-o.loc.end.line>1&&e.report({fix:h=>h.replaceTextRange([o.range[1],n.range[0]],`
|
|
116
|
+
`+" ".repeat(n.loc.start.column)),message:"No empty lines between type members",node:n})}}}},meta:{docs:{description:"Disallow empty lines in function parameters and type definitions"},fixable:"whitespace",schema:[],type:"layout"}},st={create(e){let t=e.sourceCode||e.getSourceCode(),I=new Set,C=["api","apis","config","configs","constants","data","helpers","lib","routes","services","utils","utilities"],y=x=>C.some(b=>x===`@/${b}`||x.endsWith(`/${b}`)||x.includes(`/${b}/`)||new RegExp(`^\\.?\\.?/${b}$`).test(x)),s=x=>{if(!x.source||!x.source.value)return;let b=x.source.value;y(b)&&x.specifiers.forEach(d=>{(d.type==="ImportSpecifier"&&d.local&&d.local.name||d.type==="ImportDefaultSpecifier"&&d.local&&d.local.name)&&I.add(d.local.name)})},g=(x,b,d)=>{let E=[],A=(S,k)=>{if(!(!S||typeof S!="object")&&S!==d){if(S.type==="Identifier"&&S.name===b){let $=k&&k.type==="MemberExpression"&&k.property===S&&!k.computed,v=k&&k.type==="Property"&&k.key===S&&!k.computed,p=k&&k.type==="Property"&&k.shorthand&&k.value===S;!$&&!v&&E.push(S)}for(let $ of Object.keys(S)){if($==="parent"||$==="range"||$==="loc")continue;let v=S[$];Array.isArray(v)?v.forEach(p=>A(p,S)):v&&typeof v=="object"&&v.type&&A(v,S)}}};return A(x,null),E},i=x=>{for(let b of x.declarations)if(b.id.type==="ObjectPattern"&&b.init){let d=null;if(b.init.type==="Identifier"&&(d=b.init.name),b.init.type==="MemberExpression"){let E=b.init;for(;E.type==="MemberExpression";)E=E.object;E.type==="Identifier"&&(d=E.name)}if(d&&I.has(d)){let E=b.id.properties.filter(k=>k.type==="Property"&&k.key&&k.key.name).map(k=>({key:k.key.name,local:k.value&&k.value.type==="Identifier"?k.value.name:k.key.name})),A=t.getText(b.init),S=x.parent;for(;S&&S.type!=="BlockStatement"&&S.type!=="Program";)S=S.parent;e.report({fix:S?k=>{let $=[];if(E.forEach(({key:v,local:p})=>{g(S,p,b).forEach(w=>{$.push(k.replaceText(w,`${A}.${v}`))})}),x.declarations.length===1){let v=t.getTokenBefore(x),p=t.getTokenAfter(x),m=x.range[0],w=x.range[1];if(v){let R=t.text.slice(v.range[1],x.range[0]).lastIndexOf(`
|
|
117
|
+
`);R!==-1&&(m=v.range[1]+R)}if(p){let R=t.text.slice(x.range[1],p.range[0]).indexOf(`
|
|
118
|
+
`);R!==-1&&(w=x.range[1]+R+1)}$.push(k.removeRange([m,w]))}else $.push(k.remove(b));return $}:void 0,message:`Do not destructure module imports. Use dot notation for searchability: "${A}.${E[0].key}" instead of destructuring`,node:b.id})}}},r=x=>{if(!x)return!1;if(x.type==="JSXElement"||x.type==="JSXFragment")return!0;if(x.type==="BlockStatement"){for(let b of x.body)if(b.type==="ReturnStatement"&&b.argument&&r(b.argument))return!0}return x.type==="ConditionalExpression"?r(x.consequent)||r(x.alternate):x.type==="LogicalExpression"?r(x.left)||r(x.right):x.type==="ParenthesizedExpression"?r(x.expression):!1},c=x=>{let b=null;if(x.parent)if(x.parent.type==="VariableDeclarator"&&x.parent.id&&x.parent.id.type==="Identifier")b=x.parent.id.name;else if(x.parent.type==="CallExpression"){let d=x.parent.parent;d&&d.type==="VariableDeclarator"&&d.id&&d.id.type==="Identifier"&&(b=d.id.name)}else x.id&&x.id.type==="Identifier"&&(b=x.id.name);if(b&&/^[A-Z]/.test(b)){let d=x.body;return r(d)}return!1},o=new Set(["map","filter","reduce","forEach","find","findIndex","some","every","flat","flatMap","sort","reverse","slice","splice","concat","join","includes","indexOf","lastIndexOf","push","pop","shift","unshift","keys","values","entries","toString","toLocaleString","length"]),n=(x,b)=>{let d=[],E=new Set,A=k=>{if(!(!k||typeof k!="object")){k.type==="CallExpression"&&k.callee&&k.callee.type==="MemberExpression"&&E.add(k.callee);for(let $ of Object.keys(k)){if($==="parent")continue;let v=k[$];Array.isArray(v)?v.forEach(A):v&&typeof v=="object"&&v.type&&A(v)}}};A(x);let S=k=>{if(!(!k||typeof k!="object")){if(k.type==="MemberExpression"&&!k.computed&&k.object.type==="Identifier"&&k.object.name===b){let $=k.property.name;if(E.has(k))return;o.has($)||d.push({node:k,property:$})}for(let $ of Object.keys(k)){if($==="parent")continue;let v=k[$];Array.isArray(v)?v.forEach(S):v&&typeof v=="object"&&v.type&&S(v)}}};return S(x),d},h=(x,b)=>{if(x.type!=="BlockStatement")return null;let d=x.body;if(d.length===0)return null;let E=d[d.length-1];if(E.type!=="ReturnStatement"||!E.argument)return null;let A=[],S=new Set([b]);for(let k=0;k<d.length-1;k+=1){let $=d[k];if($.type!=="VariableDeclaration")return null;for(let v of $.declarations){if(!v.init)return null;if(v.id.type==="ObjectPattern"){if(v.init.type!=="Identifier"||!S.has(v.init.name))return null;for(let p of v.id.properties)if(p.type==="Property"&&p.key.type==="Identifier"){if(p.value.type==="ObjectPattern"||p.value.type==="ArrayPattern")return null;let m=p.value.type==="Identifier"?p.value.name:p.key.name;S.add(m),v.init.name===b&&A.push(p.key.name)}}else if(v.id.type==="Identifier")if(v.init.type==="MemberExpression"&&!v.init.computed)if(v.init.object.type==="Identifier"&&S.has(v.init.object.name))S.add(v.id.name);else return null;else return null;else return null}}return A.length===0?null:{destructuredProps:A,returnStatement:E}},f=(x,b)=>{if(x.type!=="BlockStatement")return!1;let d=x.body,E=new Set([b]);for(let A of d)if(A.type!=="ReturnStatement")if(A.type==="VariableDeclaration")for(let S of A.declarations){if(!S.init)return!0;if(S.id.type==="ObjectPattern"&&S.init.type==="Identifier"&&E.has(S.init.name)){for(let k of S.id.properties)k.type==="Property"&&k.value.type==="Identifier"?E.add(k.value.name):k.type==="Property"&&k.key.type==="Identifier"&&E.add(k.key.name);continue}if(S.id.type==="Identifier"&&S.init.type==="MemberExpression"&&S.init.object.type==="Identifier"&&E.has(S.init.object.name)){E.add(S.id.name);continue}return!0}else return!0;return!1},l=(x,b,d)=>{let E=[],A=new Set,S=$=>{if(!(!$||typeof $!="object")){$.type==="CallExpression"&&$.callee&&$.callee.type==="MemberExpression"&&A.add($.callee);for(let v of Object.keys($)){if(v==="parent")continue;let p=$[v];Array.isArray(p)?p.forEach(S):p&&typeof p=="object"&&p.type&&S(p)}}};S(x);let k=$=>{if(!(!$||typeof $!="object")){if($.type==="MemberExpression"&&!$.computed&&$.object.type==="Identifier"&&$.object.name===b){let v=$.property.name;if(A.has($))return;o.has(v)||E.push({node:$,property:v})}for(let v of Object.keys($)){if(v==="parent")continue;let p=$[v];Array.isArray(p)?p.forEach(k):p&&typeof p=="object"&&p.type&&k(p)}}};return k(x),E},a=(x,b)=>{let d=new Map;if(x.type!=="BlockStatement")return d;for(let E of x.body)if(E.type==="VariableDeclaration")for(let A of E.declarations){if(A.id.type==="ObjectPattern"&&A.init){if(A.init.type==="Identifier"&&A.init.name===b){for(let S of A.id.properties)if(S.type==="Property"&&S.key.type==="Identifier"){let k=S.value.type==="Identifier"?S.value.name:S.key.name;d.set(k,{fromParam:!0,fromVar:null,originalProp:S.key.name})}}if(A.init.type==="Identifier"&&d.has(A.init.name)){for(let S of A.id.properties)if(S.type==="Property"&&S.key.type==="Identifier"){let k=S.value.type==="Identifier"?S.value.name:S.key.name;d.set(k,{fromParam:!1,fromVar:A.init.name,originalProp:S.key.name})}}}if(A.id.type==="Identifier"&&A.init&&A.init.type==="MemberExpression"){let S=A.init;S.object.type==="Identifier"&&d.has(S.object.name)&&!S.computed&&S.property.type==="Identifier"&&d.set(A.id.name,{fromParam:!1,fromVar:S.object.name,originalProp:S.property.name})}}return d},u=(x,b,d)=>{if(x.type!=="BlockStatement")return null;for(let E of x.body)if(E.type==="VariableDeclaration"){for(let A of E.declarations)if(A.id.type==="ObjectPattern"&&A.init&&A.init.type==="Identifier"&&A.init.name===d){for(let S of A.id.properties)if(S.type==="Property"&&S.key.type==="Identifier"&&(S.value.type==="Identifier"?S.value.name:S.key.name)===b)return{declarator:A,property:S,statement:E}}}return null},T=x=>{let b=c(x),d=x.params,E=x.body;if(!(d.length===0||!E)){if(x.type==="ArrowFunctionExpression"&&E.type!=="BlockStatement"){d.forEach(A=>{if(A.type!=="Identifier")return;let S=A.name,k=!1,$=(p,m)=>{if(!(!p||typeof p!="object")){if(p.type==="SpreadElement"&&p.argument&&p.argument.type==="Identifier"&&p.argument.name===S){k=!0;return}for(let w of Object.keys(p)){if(w==="parent")continue;let L=p[w];Array.isArray(L)?L.forEach(R=>$(R,p)):L&&typeof L=="object"&&L.type&&$(L,p)}}};if($(E,null),k)return;let v=n(E,S);if(v.length>0){let p=[...new Set(v.map(R=>R.property))],m=[],w=(R,P)=>{if(!(!R||typeof R!="object")){R.type==="Identifier"&&R.name===S&&(P&&P.type==="Property"&&P.key===R&&!P.computed||m.push(R));for(let H of Object.keys(R)){if(H==="parent")continue;let F=R[H];Array.isArray(F)?F.forEach(M=>w(M,R)):F&&typeof F=="object"&&F.type&&w(F,R)}}};w(E,null);let L=m.length===v.length;e.report({fix:L?R=>{let P=[];return P.push(R.replaceText(A,`{ ${p.join(", ")} }`)),v.forEach(H=>{P.push(R.replaceText(H.node,H.property))}),P}:void 0,message:`Parameter "${S}" is accessed via dot notation. For arrow functions with direct returns, destructure in the parameter: "({ ${p.join(", ")} })"`,node:v[0].node})}});return}if(!b){let A=d[0];if(A.type==="ObjectPattern"){e.report({message:'Non-component functions should not destructure parameters in the signature. Use a typed parameter (e.g., "data: InterfaceType") and destructure in the function body instead.',node:A});return}}if(x.type==="ArrowFunctionExpression"&&E.type==="BlockStatement"){let A=d[0];if(A&&A.type==="Identifier"){let S=h(E,A.name);if(S){e.report({message:`This function only destructures and returns. Convert to expression body with destructured param: "({ ${S.destructuredProps.join(", ")} }) => ..."`,node:E});return}}}if(E.type==="BlockStatement"){let A=d[0];if(A&&A.type==="Identifier"&&f(E,A.name)){let S=a(E,A.name);for(let[k,$]of S){let v=l(E,k,A.name);if(v.length>0){let p=[...new Set(v.map(w=>w.property))],m=u(E,k,A.name);e.report({fix:m?w=>{let L=[],{property:R}=m,P=`${$.originalProp}: { ${p.join(", ")} }`;return L.push(w.replaceText(R,P)),v.forEach(H=>{L.push(w.replaceText(H.node,H.property))}),L}:void 0,message:`Variable "${k}" is accessed via dot notation (${p.join(", ")}). Use nested destructuring instead: "const { ${$.originalProp}: { ${p.join(", ")} } } = ..."`,node:v[0].node})}}}}if(d.forEach(A=>{if(A.type!=="Identifier")return;let S=A.name,k=n(E,S);if(k.length>0){let $=[...new Set(k.map(v=>v.property))];e.report({fix:v=>{let p=[],m=E.body[0];if(m){let L=t.lines[m.loc.start.line-1].match(/^\s*/)[0],R=`const { ${$.join(", ")} } = ${S};
|
|
119
|
+
${L}`;p.push(v.insertTextBefore(m,R))}return k.forEach(w=>{p.push(v.replaceText(w.node,w.property))}),p},message:`Parameter "${S}" is accessed via dot notation. Destructure it at the top of the function body: "const { ${$.join(", ")} } = ${S};"`,node:k[0].node})}}),b&&E.type==="BlockStatement"){let A=d[0];A&&A.type==="ObjectPattern"&&A.properties.filter(k=>k.type==="Property"&&k.key.type==="Identifier").map(k=>k.value.type==="Identifier"?k.value.name:k.key.name).forEach(k=>{let $=n(E,k);if($.length>0){let v=[...new Set($.map(p=>p.property))];e.report({fix:p=>{let m=[],w=E.body[0];if(w){let R=t.lines[w.loc.start.line-1].match(/^\s*/)[0],P=`const { ${v.join(", ")} } = ${k};
|
|
120
120
|
|
|
121
|
-
${R}`;
|
|
122
|
-
`),message:`${y.name} callback should start on a new line after opening parenthesis`,node:g}),s.length>=2)){let r=s[1],
|
|
123
|
-
`),message:`${y.name} dependency array should be on a new line`,node:r});let o=s[s.length-1],n=t.getTokenAfter(o);if(n&&n.value===","&&(n=t.getTokenAfter(n)),n&&n.value===")"&&o.loc.end.line===n.loc.start.line){let h=t.getTokenBefore(n);h&&h.value===","?e.report({fix:
|
|
124
|
-
`),message:`${y.name} closing parenthesis should be on a new line`,node:n}):e.report({fix:
|
|
125
|
-
`),message:`${y.name} closing parenthesis should be on a new line`,node:n})}}}}},meta:{docs:{description:"Enforce consistent formatting for React hooks (useEffect, useCallback, etc.)"},fixable:"whitespace",schema:[],type:"layout"}},at={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxDeps!==void 0?I.maxDeps:2,y=["useEffect","useCallback","useMemo","useLayoutEffect","useImperativeHandle"];return{CallExpression:g=>{if(g.callee.type!=="Identifier"||!y.includes(g.callee.name))return;let i=g.arguments[g.arguments.length-1];if(!i||i.type!=="ArrayExpression")return;let r=i.elements.filter(Boolean);if(r.length===0)return;let
|
|
121
|
+
${R}`;m.push(p.insertTextBefore(w,P))}return $.forEach(L=>{m.push(p.replaceText(L.node,L.property))}),m},message:`Prop "${k}" is accessed via dot notation. Destructure it at the top of the component: "const { ${v.join(", ")} } = ${k};"`,node:$[0].node})}})}}};return{ArrowFunctionExpression:T,FunctionDeclaration:T,FunctionExpression:T,ImportDeclaration:s,VariableDeclaration:i}},meta:{docs:{description:"Enforce object parameters to be destructured in function body, not accessed via dot notation. Also prevent destructuring of data imports."},fixable:"code",schema:[],type:"suggestion"}};var it={create(e){let t=e.sourceCode||e.getSourceCode(),I=["useEffect","useLayoutEffect","useCallback","useMemo","useImperativeHandle"];return{CallExpression(C){let{callee:y}=C;if(y.type!=="Identifier"||!I.includes(y.name))return;let s=C.arguments;if(s.length===0)return;let g=s[0];if(g.type!=="ArrowFunctionExpression"&&g.type!=="FunctionExpression")return;let i=t.getTokenAfter(y);if(!(!i||i.value!=="(")&&(i.loc.end.line===g.loc.start.line&&e.report({fix:r=>r.replaceTextRange([i.range[1],g.range[0]],`
|
|
122
|
+
`),message:`${y.name} callback should start on a new line after opening parenthesis`,node:g}),s.length>=2)){let r=s[1],c=t.getTokenAfter(g);c&&c.value===","&&c.loc.end.line===r.loc.start.line&&e.report({fix:h=>h.replaceTextRange([c.range[1],r.range[0]],`
|
|
123
|
+
`),message:`${y.name} dependency array should be on a new line`,node:r});let o=s[s.length-1],n=t.getTokenAfter(o);if(n&&n.value===","&&(n=t.getTokenAfter(n)),n&&n.value===")"&&o.loc.end.line===n.loc.start.line){let h=t.getTokenBefore(n);h&&h.value===","?e.report({fix:l=>l.replaceTextRange([h.range[1],n.range[0]],`
|
|
124
|
+
`),message:`${y.name} closing parenthesis should be on a new line`,node:n}):e.report({fix:l=>l.replaceTextRange([o.range[1],n.range[0]],`,
|
|
125
|
+
`),message:`${y.name} closing parenthesis should be on a new line`,node:n})}}}}},meta:{docs:{description:"Enforce consistent formatting for React hooks (useEffect, useCallback, etc.)"},fixable:"whitespace",schema:[],type:"layout"}},at={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxDeps!==void 0?I.maxDeps:2,y=["useEffect","useCallback","useMemo","useLayoutEffect","useImperativeHandle"];return{CallExpression:g=>{if(g.callee.type!=="Identifier"||!y.includes(g.callee.name))return;let i=g.arguments[g.arguments.length-1];if(!i||i.type!=="ArrayExpression")return;let r=i.elements.filter(Boolean);if(r.length===0)return;let c=t.getFirstToken(i),o=t.getLastToken(i),n=r[0],h=r[r.length-1];if(r.length<=C){if(c.loc.end.line!==o.loc.start.line){let u=r.map(T=>t.getText(T)).join(", ");e.report({fix:T=>T.replaceTextRange([c.range[1],o.range[0]],u),message:`Hook dependencies with \u2264${C} items should be single line: [dep1, dep2]. Multi-line only for >${C} dependencies`,node:i})}return}let f=" ".repeat(c.loc.start.column+4),l=" ".repeat(c.loc.start.column);c.loc.end.line===n.loc.start.line&&e.report({fix:a=>a.replaceTextRange([c.range[1],n.range[0]],`
|
|
126
126
|
`+f),message:`First dependency should be on its own line when more than ${C}`,node:n}),o.loc.start.line===h.loc.end.line&&e.report({fix:a=>a.replaceTextRange([h.range[1],o.range[0]],`,
|
|
127
|
-
`+
|
|
128
|
-
`+f),message:`Each dependency should be on its own line when more than ${C}`,node:
|
|
129
|
-
`+
|
|
130
|
-
`+f),message:`Exports with more than ${C} specifiers should have closing brace on its own line`,node:
|
|
131
|
-
`+
|
|
132
|
-
`+u),message:`Imports with more than ${C} specifiers should have first specifier on its own line`,node:f}),o.loc.start.line===
|
|
133
|
-
`+a),message:`Imports with more than ${C} specifiers should have closing brace on its own line`,node:o});for(let
|
|
134
|
-
`+u),message:`Each import specifier should be on its own line when more than ${C} specifiers`,node:
|
|
127
|
+
`+l),message:`Closing bracket should be on its own line when more than ${C} dependencies`,node:o});for(let a=0;a<r.length-1;a+=1){let u=r[a],T=r[a+1];if(u.loc.end.line===T.loc.start.line){let x=t.getTokenAfter(u);e.report({fix:b=>b.replaceTextRange([x.range[1],T.range[0]],`
|
|
128
|
+
`+f),message:`Each dependency should be on its own line when more than ${C}`,node:T})}}}}},meta:{docs:{description:"Enforce each hook dependency on its own line when exceeding threshold (default: >2)"},fixable:"whitespace",schema:[{additionalProperties:!1,properties:{maxDeps:{default:2,description:"Maximum dependencies to keep on single line (default: 2)",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},ot={create(e){let t=e.options[0]||{},I=["is","has","with","without"],C=t.booleanPrefixes||[...I,...t.extendBooleanPrefixes||[]],y=t.allowPastVerbBoolean||!1,s=t.allowContinuousVerbBoolean||!1,g=new RegExp(`^(${C.join("|")})[A-Z]`),i=/^[a-z]+ed$/,r=/^[a-z]+ing$/,c=["children","content","data","error","errors","items","permission","permissions","value","values"],o=a=>{let u=a.toLowerCase();return(c.some(x=>u.includes(x))?"has":"is")+a[0].toUpperCase()+a.slice(1)},n=a=>"set"+a[0].toUpperCase()+a.slice(1),h=a=>!!(g.test(a)||y&&i.test(a)||s&&r.test(a)),f=a=>a?a.type==="Literal"&&typeof a.value=="boolean":!1,l=a=>{if(a.typeParameters&&a.typeParameters.params&&a.typeParameters.params.length>0){let u=a.typeParameters.params[0];if(u.type==="TSBooleanKeyword")return!0;if(u.type==="TSUnionType")return u.types.some(T=>T.type==="TSBooleanKeyword")}return!1};return{CallExpression(a){if(a.callee.type!=="Identifier"||a.callee.name!=="useState"||!a.parent||a.parent.type!=="VariableDeclarator"||!a.parent.id||a.parent.id.type!=="ArrayPattern")return;let u=a.parent.id;if(!u.elements||u.elements.length<1)return;let T=u.elements[0],x=u.elements[1];if(!T||T.type!=="Identifier")return;let b=T.name;if(!(a.arguments&&a.arguments.length>0&&f(a.arguments[0])||l(a))||h(b))return;let E=o(b),A=n(E);e.report({fix(S){let k=[],$=e.sourceCode?e.sourceCode.getScope(a):e.getScope(),v=(L,R)=>{let P=L.variables.find(H=>H.name===R);return P||(L.upper?v(L.upper,R):null)},p=v($,b),m=new Set,w=`${T.range[0]}-${T.range[1]}`;if(m.add(w),k.push(S.replaceText(T,E)),p&&p.references.forEach(L=>{let R=`${L.identifier.range[0]}-${L.identifier.range[1]}`;m.has(R)||(m.add(R),k.push(S.replaceText(L.identifier,E)))}),x&&x.type==="Identifier"){let L=x.name,R=v($,L),P=new Set,H=`${x.range[0]}-${x.range[1]}`;P.add(H),k.push(S.replaceText(x,A)),R&&R.references.forEach(F=>{let M=`${F.identifier.range[0]}-${F.identifier.range[1]}`;P.has(M)||(P.add(M),k.push(S.replaceText(F.identifier,A)))})}return k},message:`Boolean state "${b}" should start with a valid prefix (${C.join(", ")}). Use "${E}" instead.`,node:T})}}},meta:{docs:{description:"Enforce boolean useState variables to start with is/has/with/without prefix"},fixable:"code",schema:[{additionalProperties:!1,properties:{allowContinuousVerbBoolean:{default:!1,description:"Allow continuous verb boolean state without prefix (e.g., loading, saving)",type:"boolean"},allowPastVerbBoolean:{default:!1,description:"Allow past verb boolean state without prefix (e.g., disabled, selected)",type:"boolean"},booleanPrefixes:{description:"Replace default boolean prefixes entirely",items:{type:"string"},type:"array"},extendBooleanPrefixes:{default:[],description:"Add additional prefixes to the defaults (is, has, with, without)",items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}};import fe from"fs";import ie from"path";var lt={create(e){let t=e.options[0]||{},I=t.aliasPrefix||"@/",C=["actions","reducers","store","thunks","types"],y=t.reduxSubfolders||[...C,...t.extraReduxSubfolders||[]],s=["@constants","@strings","actions","apis","assets","atoms","components","config","configs","constants","contexts","data","enums","helpers","hooks","interfaces","layouts","lib","middlewares","pages","providers","reducers","redux","requests","routes","schemas","services","store","strings","styles","theme","thunks","types","ui","utils","utilities","views"],g=t.allowedFolders||[...s,...t.extraAllowedFolders||[]],i=["assets"],r=t.deepImportFolders||[...i,...t.extraDeepImportFolders||[]];return{ImportDeclaration(c){let o=c.source.value;if(typeof o!="string")return;let h=(e.filename||e.getFilename()).replace(/\\/g,"/"),f=/\/index\.(js|jsx|ts|tsx)$/.test(h),l=/\/main\.(js|jsx|ts|tsx)$/.test(h),u=(()=>{for(let T of g)if(new RegExp(`/(${T})/`).test(h))return T;return null})();if(o.startsWith("./")||o.startsWith("../")){if(f||l||u)return;e.report({message:`Relative imports are not allowed. Use absolute imports with "${I}" prefix instead.`,node:c.source});return}if(!(!o.startsWith("@")&&!o.startsWith("."))&&!(o.startsWith("@")&&!o.startsWith(I))&&o.startsWith(I)){let x=o.slice(I.length).split("/").filter(d=>d.length>0);if(x.length===0){e.report({message:`Invalid import path "${o}". Specify a folder to import from.`,node:c.source});return}let b=x[0];if(!g.includes(b)){e.report({message:`Unknown folder "${b}" in import path. Allowed folders: ${g.join(", ")}`,node:c.source});return}if(u&&b===u){let d=x.slice(1).join("/");if(d){let E=h.lastIndexOf(`/${u}/`),A=h.slice(E+u.length+2),S=A.substring(0,A.lastIndexOf("/")),k=ie.posix.relative(S,d);k.startsWith(".")||(k=`./${k}`),e.report({message:`Files within "${u}/" should use relative imports (e.g., "${k}") instead of "${o}" to avoid circular dependencies.`,node:c.source,fix:$=>$.replaceText(c.source,`"${k}"`)});return}e.report({message:`Files within "${u}/" should use relative imports instead of "${o}" to avoid circular dependencies through the index file.`,node:c.source});return}if(x.length>1){if(b==="redux"&&x.length===2&&y.includes(x[1]))return;if(b==="redux"&&x.length>2){let A=`${I}redux/${x[1]}`;e.report({message:`Deep imports are not allowed. Import from "${A}" instead of "${o}". Export the module from the folder's index file.`,node:c.source});return}if(r.includes(b))return;let E=`${I}${b}`;e.report({fix:A=>A.replaceText(c.source,`"${E}"`),message:`Deep imports are not allowed. Import from "${E}" instead of "${o}". Export the module from the folder's index file.`,node:c.source})}}}}},meta:{docs:{description:"Enforce absolute imports from index files only for local paths, with relative imports required for files within the same module folder"},fixable:"code",schema:[{additionalProperties:!1,properties:{aliasPrefix:{type:"string"},allowedFolders:{items:{type:"string"},type:"array"},deepImportFolders:{items:{type:"string"},type:"array"},extraAllowedFolders:{items:{type:"string"},type:"array"},extraDeepImportFolders:{items:{type:"string"},type:"array"},extraReduxSubfolders:{items:{type:"string"},type:"array"},reduxSubfolders:{items:{type:"string"},type:"array"}},type:"object"}],type:"problem"}},ct={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxSpecifiers!==void 0?I.maxSpecifiers:3;return{ExportNamedDeclaration:s=>{let g=t.getFirstToken(s);if(s.declaration){let f=t.getFirstToken(s.declaration);f&&g.loc.end.line!==f.loc.start.line&&e.report({fix:l=>l.replaceTextRange([g.range[1],f.range[0]]," "),message:"Declaration keyword must be on the same line as 'export'",node:f});return}let i=s.specifiers;if(i.length===0)return;let r=t.getTokenAfter(g,f=>f.value==="{"),c=t.getLastToken(s,f=>f.value==="}");if(!r||!c)return;g.loc.end.line!==r.loc.start.line&&e.report({fix:f=>f.replaceTextRange([g.range[1],r.range[0]]," "),message:"Opening brace should be on the same line as 'export'",node:r});let o=r.loc.start.line!==c.loc.end.line,n=i[0],h=i[i.length-1];if(i.length<=C){if(o){let f=i.map(l=>l.exported.name===l.local.name?l.local.name:`${l.local.name} as ${l.exported.name}`).join(", ");e.report({fix:l=>l.replaceTextRange([r.range[0],c.range[1]],`{ ${f} }`),message:`Exports with \u2264${C} specifiers should be single line: export { a, b, c }`,node:s})}}else{let f=" ".repeat(g.loc.start.column),l=f+" ";r.loc.end.line===n.loc.start.line&&e.report({fix:a=>a.replaceTextRange([r.range[1],n.range[0]],`
|
|
129
|
+
`+l),message:`Exports with more than ${C} specifiers should have first specifier on its own line`,node:n}),c.loc.start.line===h.loc.end.line&&e.report({fix:a=>a.replaceTextRange([h.range[1],c.range[0]],`,
|
|
130
|
+
`+f),message:`Exports with more than ${C} specifiers should have closing brace on its own line`,node:c});for(let a=0;a<i.length-1;a+=1){let u=i[a],T=i[a+1];if(u.loc.end.line===T.loc.start.line){let x=t.getTokenAfter(u,b=>b.value===",");e.report({fix:b=>b.replaceTextRange([x.range[1],T.range[0]],`
|
|
131
|
+
`+l),message:`Each export specifier should be on its own line when more than ${C} specifiers`,node:T})}}}}}},meta:{docs:{description:"Format exports: export { on same line, collapse/expand specifiers based on count threshold"},fixable:"code",schema:[{additionalProperties:!1,properties:{maxSpecifiers:{default:3,description:"Maximum specifiers to keep on single line (default: 3). Exports exceeding this will be expanded to multiline.",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},pt={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxSpecifiers!==void 0?I.maxSpecifiers:3;return{ImportDeclaration:s=>{let g=t.getFirstToken(s),i=s.specifiers.filter(a=>a.type==="ImportSpecifier"),r=s.specifiers.find(a=>a.type==="ImportDefaultSpecifier");if(r&&i.length===0){if(t.getTokenBefore(s.source,u=>u.value==="from")&&g.loc.start.line!==s.source.loc.end.line){let u=r.local.name,T=s.source.raw;e.report({fix:x=>x.replaceText(s,`import ${u} from ${T};`),message:"Default import should be on a single line",node:s})}return}if(i.length===0)return;let c=t.getTokenAfter(g,a=>a.value==="{"),o=t.getTokenBefore(s.source,a=>a.value==="}"),n=t.getTokenBefore(s.source,a=>a.value==="from");if(!c||!o||!n)return;g.loc.end.line!==c.loc.start.line&&e.report({fix:a=>a.replaceTextRange([g.range[1],c.range[0]]," "),message:"Opening brace should be on the same line as 'import'",node:c}),o.loc.end.line!==n.loc.start.line&&e.report({fix:a=>a.replaceTextRange([o.range[1],n.range[0]]," "),message:"Closing brace should be on the same line as 'from'",node:n});let h=c.loc.start.line!==o.loc.end.line,f=i[0],l=i[i.length-1];if(i.length<=C){if(h){let a=i.map(u=>u.imported.name===u.local.name?u.local.name:`${u.imported.name} as ${u.local.name}`).join(", ");e.report({fix:u=>u.replaceTextRange([c.range[0],o.range[1]],`{ ${a} }`),message:`Imports with \u2264${C} specifiers should be single line: import { a, b, c } from "module"`,node:s})}}else{let a=" ".repeat(g.loc.start.column),u=a+" ";c.loc.end.line===f.loc.start.line&&e.report({fix:T=>T.replaceTextRange([c.range[1],f.range[0]],`
|
|
132
|
+
`+u),message:`Imports with more than ${C} specifiers should have first specifier on its own line`,node:f}),o.loc.start.line===l.loc.end.line&&e.report({fix:T=>T.replaceTextRange([l.range[1],o.range[0]],`,
|
|
133
|
+
`+a),message:`Imports with more than ${C} specifiers should have closing brace on its own line`,node:o});for(let T=0;T<i.length-1;T+=1){let x=i[T],b=i[T+1];if(x.loc.end.line===b.loc.start.line){let d=t.getTokenAfter(x,E=>E.value===",");e.report({fix:E=>E.replaceTextRange([d.range[1],b.range[0]],`
|
|
134
|
+
`+u),message:`Each import specifier should be on its own line when more than ${C} specifiers`,node:b})}}}}}},meta:{docs:{description:"Format imports: import { on same line, } from on same line, collapse/expand specifiers based on count threshold"},fixable:"code",schema:[{additionalProperties:!1,properties:{maxSpecifiers:{default:3,description:"Maximum specifiers to keep on single line (default: 3). Imports exceeding this will be expanded to multiline.",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},ft={create(e){return{ImportDeclaration(t){let{source:I}=t;if(I.type!=="Literal"||typeof I.value!="string")return;let C=I.value,y=C.trim();C!==y&&y.length>0&&e.report({fix:s=>s.replaceText(I,`"${y}"`),message:`Import path should not have extra spaces inside quotes: "${y}" not "${C}"`,node:I})}}},meta:{docs:{description:"Enforce no extra spaces inside import path quotes"},fixable:"code",schema:[],type:"layout"}},ut={create(e){let t=e.filename||e.getFilename(),I=ie.resolve(t,"../../..").replace(/\\/g,"/"),C=e.options[0]||{},y=["@constants","@strings","actions","apis","assets","atoms","components","config","configs","constants","contexts","data","enums","helpers","hooks","interfaces","layouts","lib","middlewares","pages","providers","reducers","redux","requests","routes","schemas","services","store","strings","styles","theme","thunks","types","ui","utils","utilities","views"],s=C.moduleFolders||[...y,...C.extraModuleFolders||[]],g=["pages","views"],i=C.lazyLoadFolders||[...g,...C.extraLazyLoadFolders||[]],r=["index.js","index.jsx","index.ts","index.tsx",".DS_Store","__tests__","__mocks__","*.test.js","*.test.jsx","*.test.ts","*.test.tsx","*.spec.js","*.spec.jsx","*.spec.ts","*.spec.tsx"],c=C.ignorePatterns||[...r,...C.extraIgnorePatterns||[]],o=l=>c.some(a=>a.includes("*")?new RegExp("^"+a.replace(/\*/g,".*")+"$").test(l):l===a),n=l=>{let a=new Set,u=new Map;return l.type==="Program"&&(l.body.forEach(T=>{if(T.type==="ImportDeclaration"&&T.source){let x=T.source.value;T.specifiers.forEach(b=>{b.local&&b.local.name&&u.set(b.local.name,x)})}}),l.body.forEach(T=>{if(T.type==="ExportNamedDeclaration"){if(T.source){let x=T.source.value;a.add(x)}T.specifiers&&!T.source&&T.specifiers.forEach(x=>{let b=x.local?x.local.name:x.exported.name;u.has(b)&&a.add(u.get(b))})}T.type==="ExportAllDeclaration"&&T.source&&a.add(T.source.value)})),a},h=l=>l.replace(/\.(js|jsx|ts|tsx)$/,""),f=(l,a,u)=>{let T;try{T=fe.readdirSync(a)}catch{return}let x=T.filter(d=>{if(o(d))return!1;let E=ie.join(a,d);try{if(fe.statSync(E).isDirectory()||/\.(js|jsx|ts|tsx)$/.test(d))return!0}catch{return!1}return!1});if(x.length===0)return;let b=n(l);x.forEach(d=>{let E=h(d),A=ie.join(a,d),S=fe.statSync(A).isDirectory();Array.from(b).some($=>!!($===`./${d}`||$===`./${E}`||$.startsWith(`./${E}/`)||S&&($===`./${E}/index`||$===`./${E}/index.js`||$===`./${E}/index.jsx`||$===`./${E}/index.ts`||$===`./${E}/index.tsx`)))||e.report({message:`Module "${d}" in "${u}" folder is not exported from index file. Add: export * from "./${E}"; or export { ... } from "./${E}";`,node:l})})};return{Program(l){let a=t.replace(/\\/g,"/"),u=a.match(/\/src\/([^/]+)\/index\.(js|jsx|ts|tsx)$/);if(u){let b=u[1];if(i.includes(b))return;if(s.includes(b)){let d=ie.dirname(t);f(l,d,b)}}let T=a.match(/\/src\/([^/]+)\/([^/]+)\.(js|jsx|ts|tsx)$/);if(T){let b=T[1],d=T[2];if(s.includes(b)&&d!=="index"){let E=ie.dirname(t),A=ie.join(E,"index.js"),S=ie.join(E,"index.jsx"),k=ie.join(E,"index.ts"),$=ie.join(E,"index.tsx");fe.existsSync(A)||fe.existsSync(S)||fe.existsSync(k)||fe.existsSync($)||e.report({message:`Module folder "${b}" is missing an index file. Create an index file to export all modules.`,node:l})}}let x=a.match(/\/src\/([^/]+)\/([^/]+)\/index\.(js|jsx|ts|tsx)$/);if(x){let b=x[1],d=x[2];if(i.includes(b))return;if(s.includes(b)){let E=ie.dirname(t);f(l,E,`${b}/${d}`)}}}}},meta:{docs:{description:"Ensure module folders have index files that export all contents"},schema:[{additionalProperties:!1,properties:{extraIgnorePatterns:{items:{type:"string"},type:"array"},extraLazyLoadFolders:{items:{type:"string"},type:"array"},extraModuleFolders:{items:{type:"string"},type:"array"},ignorePatterns:{items:{type:"string"},type:"array"},lazyLoadFolders:{items:{type:"string"},type:"array"},moduleFolders:{items:{type:"string"},type:"array"}},type:"object"}],type:"problem"}},gt={create(e){let I=(e.options[0]||{}).style||"shorthand",C=e.sourceCode||e.getSourceCode(),s=(e.filename||e.getFilename()).replace(/\\/g,"/");return/\/index\.(js|jsx|ts|tsx)$/.test(s)?{Program(i){let r=[],c=[],o=[],n=new Map;if(i.body.forEach(l=>{l.type==="ImportDeclaration"&&l.source&&(r.push(l),l.specifiers.forEach(a=>{a.local&&a.local.name&&n.set(a.local.name,{source:l.source.value,statement:l})})),l.type==="ExportNamedDeclaration"&&(l.source?c.push(l):l.specifiers&&l.specifiers.length>0&&!l.declaration&&o.push(l))}),c.length===0&&o.length===0)return;let h=c.length>0,f=o.length>0&&r.length>0;if(h&&f){e.report({message:`Mixed export styles detected. Use consistent "${I}" style throughout the index file.`,node:i});return}if(I==="shorthand"){if(o.length>0&&r.length>0){let l=[];o.forEach(a=>{a.specifiers.forEach(u=>{let T=u.local?u.local.name:u.exported.name,x=n.get(T);x&&l.push({exportStmt:a,exportedName:T,importInfo:x,localName:u.local?u.local.name:T,spec:u})})}),l.length>0&&e.report({fix(a){let u=[],T=new Map;l.forEach(({exportedName:d,importInfo:E,localName:A})=>{let S=E.source;T.has(S)||T.set(S,[]),d===A?T.get(S).push(d):T.get(S).push(`${A} as ${d}`)});let x=[];T.forEach((d,E)=>{x.push(`export { ${d.join(", ")} } from "${E}";`)}),o.forEach(d=>{u.push(a.remove(d))}),r.forEach(d=>{u.push(a.remove(d))});let b=i.body[0];return b&&u.push(a.insertTextBefore(b,x.join(`
|
|
135
135
|
`)+`
|
|
136
|
-
`)),u},message:'Use shorthand export style: export { ... } from "source" instead of import then export.',node:i})}for(let
|
|
137
|
-
`)},message:"No empty lines between shorthand exports in index files.",node:u})}}else if(I==="import-export"){
|
|
138
|
-
${
|
|
136
|
+
`)),u},message:'Use shorthand export style: export { ... } from "source" instead of import then export.',node:i})}for(let l=0;l<c.length-1;l+=1){let a=c[l],u=c[l+1],T=a.loc.end.line;u.loc.start.line-T>1&&e.report({fix(b){let d=C.getText().slice(a.range[1],u.range[0]);return b.replaceTextRange([a.range[1],u.range[0]],`
|
|
137
|
+
`)},message:"No empty lines between shorthand exports in index files.",node:u})}}else if(I==="import-export"){c.length>0&&e.report({fix(l){let a=[],u=[],T=[];c.forEach(d=>{let E=d.source.value,A=[];d.specifiers.forEach(S=>{let k=S.local?S.local.name:S.exported.name,$=S.exported.name;A.push(k),T.push($)}),u.push(`import { ${A.join(", ")} } from "${E}";`),a.push(l.remove(d))}),T.sort((d,E)=>d.localeCompare(E));let x;T.length<=3?x=`export { ${T.join(", ")} };`:x=`export {
|
|
138
|
+
${T.join(`,
|
|
139
139
|
`)},
|
|
140
|
-
};`;let
|
|
140
|
+
};`;let b=i.body[0];if(b){let d=u.join(`
|
|
141
141
|
`)+`
|
|
142
142
|
|
|
143
143
|
`+x+`
|
|
144
|
-
`;a.push(
|
|
144
|
+
`;a.push(l.insertTextBefore(b,d))}return a},message:"Use import-then-export style with a single export statement.",node:i}),o.length>1&&e.report({fix(l){let a=[],u=[];o.forEach(b=>{b.specifiers.forEach(d=>{let E=d.exported.name;u.push(E)}),a.push(l.remove(b))}),u.sort((b,d)=>b.localeCompare(d));let T;u.length<=3?T=`export { ${u.join(", ")} };`:T=`export {
|
|
145
145
|
${u.join(`,
|
|
146
146
|
`)},
|
|
147
|
-
};`;let x=r[r.length-1];return x&&a.push(
|
|
147
|
+
};`;let x=r[r.length-1];return x&&a.push(l.insertTextAfter(x,`
|
|
148
148
|
|
|
149
|
-
`+
|
|
150
|
-
`)},message:"No empty lines between imports in index files.",node:u})}}}}:{Program(i){let r=[];if(i.body.forEach(
|
|
149
|
+
`+T)),a},message:"Combine multiple export statements into a single export statement.",node:i});for(let l=0;l<r.length-1;l+=1){let a=r[l],u=r[l+1],T=a.loc.end.line;u.loc.start.line-T>1&&e.report({fix(b){return b.replaceTextRange([a.range[1],u.range[0]],`
|
|
150
|
+
`)},message:"No empty lines between imports in index files.",node:u})}}}}:{Program(i){let r=[];if(i.body.forEach(c=>{(c.type==="ExportNamedDeclaration"||c.type==="ExportDefaultDeclaration")&&r.push(c)}),!(r.length<2))for(let c=0;c<r.length-1;c+=1){let o=r[c],n=r[c+1],h=o.loc.end.line;n.loc.start.line-h<2&&e.report({fix(l){return l.replaceTextRange([o.range[1],n.range[0]],`
|
|
151
151
|
|
|
152
|
-
`)},message:"Require blank line between exports.",node:n})}}}},meta:{docs:{description:"Enforce export formatting: blank lines in regular files, no blank lines in index files with consistent style: shorthand (default) or import-export"},fixable:"code",schema:[{additionalProperties:!1,properties:{style:{enum:["shorthand","import-export"],type:"string"}},type:"object"}],type:"layout"}},mt={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/");if(!(/\/index\.(js|jsx|ts|tsx)$/.test(I)||/^index\.(js|jsx|ts|tsx)$/.test(I)))return{};let y=["actions","apis","assets","atoms","components","config","configs","constants","contexts","data","enums","helpers","hooks","interfaces","layouts","lib","middlewares","pages","providers","reducers","redux","requests","routes","schemas","services","store","strings","styles","theme","themes","thunks","types","ui","utils","utilities","views"],s=I.split("/"),g=s.length-1,i=!1;for(let n=0;n<g;n++)if(y.includes(s[n])){g-n>=2&&(i=!0);break}let r=n=>{let{type:h}=n;return h==="ImportDeclaration"?!0:h==="ExportNamedDeclaration"?!n.declaration:h==="ExportDefaultDeclaration"?n.declaration&&n.declaration.type==="Identifier":h==="ExportAllDeclaration"},
|
|
153
|
-
`+x),message:"JSX child should be on its own line",node:u}),o.loc.start.line===
|
|
154
|
-
`))return}e.report({fix:
|
|
155
|
-
`+
|
|
156
|
-
`+o),message:"JSX element child should be on its own line",node:f})});let h=
|
|
157
|
-
`+n),message:"Closing tag should be on its own line after JSX children",node:i})}}},meta:{docs:{description:"JSX children that are JSX elements must be on new lines"},fixable:"whitespace",schema:[],type:"layout"}},Tt={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>{let g=t.getTokenBefore(s),i=t.getTokenAfter(s);return g&&i&&g.value==="("&&i.value===")"},C=s=>{let g=t.getText(s);return I(s)?`(${g})`:g};return{LogicalExpression:s=>{if(s.operator!=="&&")return;let{left:g,right:i}=s;if(i.type!=="JSXElement"&&i.type!=="JSXFragment")return;let r=t.lines[s.loc.start.line-1].match(/^\s*/)[0],
|
|
158
|
-
`+
|
|
152
|
+
`)},message:"Require blank line between exports.",node:n})}}}},meta:{docs:{description:"Enforce export formatting: blank lines in regular files, no blank lines in index files with consistent style: shorthand (default) or import-export"},fixable:"code",schema:[{additionalProperties:!1,properties:{style:{enum:["shorthand","import-export"],type:"string"}},type:"object"}],type:"layout"}},mt={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/");if(!(/\/index\.(js|jsx|ts|tsx)$/.test(I)||/^index\.(js|jsx|ts|tsx)$/.test(I)))return{};let y=["actions","apis","assets","atoms","components","config","configs","constants","contexts","data","enums","helpers","hooks","interfaces","layouts","lib","middlewares","pages","providers","reducers","redux","requests","routes","schemas","services","store","strings","styles","theme","themes","thunks","types","ui","utils","utilities","views"],s=I.split("/"),g=s.length-1,i=!1;for(let n=0;n<g;n++)if(y.includes(s[n])){g-n>=2&&(i=!0);break}let r=n=>{let{type:h}=n;return h==="ImportDeclaration"?!0:h==="ExportNamedDeclaration"?!n.declaration:h==="ExportDefaultDeclaration"?n.declaration&&n.declaration.type==="Identifier":h==="ExportAllDeclaration"},c=n=>{let{type:h}=n;return h==="VariableDeclaration"||h==="FunctionDeclaration"||h==="ClassDeclaration"||h==="ExportNamedDeclaration"&&n.declaration?!0:h==="ExportDefaultDeclaration"?n.declaration&&n.declaration.type!=="Identifier":!1},o=n=>{switch(n.type){case"TSTypeAliasDeclaration":return"Type definition";case"TSInterfaceDeclaration":return"Interface definition";case"TSEnumDeclaration":return"Enum definition";case"VariableDeclaration":return"Variable declaration";case"FunctionDeclaration":return"Function declaration";case"ClassDeclaration":return"Class declaration";case"ExportNamedDeclaration":return n.declaration?o(n.declaration):"Export with inline declaration";case"ExportDefaultDeclaration":return"Default export with inline definition";default:return"Code"}};return{Program(n){if(i){if(!n.body.some(f=>c(f))){let f=s[g-1];e.report({message:`Subfolder index file "${f}/index" should contain component code, not just re-exports. Only the module root index file should be a barrel for imports and re-exports.`,node:n})}return}for(let h of n.body)if(!r(h)){let f=o(h);e.report({message:`${f} should not be in index files. Index files should only contain imports and re-exports. Move this to a separate file.`,node:h})}}}},meta:{docs:{description:"Enforce index files as barrels (re-exports only) at module root, and as component entry points (with code) in subfolders"},schema:[],type:"suggestion"}},dt={create(e){let I=(e.filename||e.getFilename()).replace(/\\/g,"/");if(/\/index\.(js|jsx|ts|tsx)$/.test(I)||/^index\.(js|jsx|ts|tsx)$/.test(I))return{};let y=e.sourceCode||e.getSourceCode();return{Program(s){let g=s.body.filter(r=>r.type==="ExportNamedDeclaration"&&!r.source&&!r.declaration&&r.specifiers.length>0);if(g.length===0)return;let i=new Map;s.body.forEach(r=>{r.type==="VariableDeclaration"?r.declarations.forEach(c=>{c.id&&c.id.type==="Identifier"&&i.set(c.id.name,{declarationNode:r,kind:r.kind})}):r.type==="FunctionDeclaration"&&r.id?i.set(r.id.name,{declarationNode:r,kind:"function"}):r.type==="ClassDeclaration"&&r.id&&i.set(r.id.name,{declarationNode:r,kind:"class"})}),g.forEach(r=>{r.specifiers.some(h=>h.local.name!==h.exported.name)||!r.specifiers.every(h=>i.has(h.local.name))||r.specifiers.some(h=>{let l=i.get(h.local.name).declarationNode,a=l.parent;return a&&a.type==="ExportNamedDeclaration"?!0:y.getText(l).startsWith("export ")})||e.report({fix(h){let f=[];r.specifiers.forEach(a=>{let T=i.get(a.local.name).declarationNode;f.push(h.insertTextBefore(T,"export "))});let l=y.getTokenBefore(r,{includeComments:!0});return l?f.push(h.removeRange([l.range[1],r.range[1]])):f.push(h.remove(r)),f},message:"Use inline export declarations (export const x = ...) instead of grouped export statements (export { x }).",node:r})})}}},meta:{docs:{description:"Enforce inline export declarations instead of grouped export statements in non-index files"},fixable:"code",schema:[],type:"layout"}};var yt={create(e){let t=e.sourceCode||e.getSourceCode(),I=r=>r?r.type==="Identifier"||r.type==="Literal"?!0:r.type==="MemberExpression"?r.object.type==="Identifier"&&r.property.type==="Identifier":!1:!1,C=r=>{if(!r||r.type==="Identifier"||r.type==="Literal")return!0;if(r.type==="ChainExpression")return C(r.expression);if(r.type==="MemberExpression"){let c=r;for(;c.type==="MemberExpression";){if(c.computed){if(c.property.type!=="Identifier"&&c.property.type!=="Literal")return!1}else if(c.property.type!=="Identifier")return!1;c=c.object}return c.type==="ChainExpression"?C(c.expression):c.type==="Identifier"}if(r.type==="CallExpression"){let{callee:c}=r;return c.type==="Identifier"||c.type==="MemberExpression"&&c.object.type==="Identifier"&&c.property.type==="Identifier"?!!(r.arguments.length===0||r.arguments.length===1&&I(r.arguments[0])):!1}if(r.type==="LogicalExpression"){let c=n=>n.type==="LogicalExpression"?c(n.left)+c(n.right):1;if(c(r)>2)return!1;let o=n=>n.type==="Identifier"||n.type==="Literal"?!0:n.type==="MemberExpression"?C(n):n.type==="ChainExpression"&&n.expression?o(n.expression):!1;return o(r.left)&&o(r.right)}return!1},y=r=>r.type==="JSXText"?!0:r.type==="JSXExpressionContainer"?C(r.expression):!1,s=(r,c,o)=>{let{children:n}=r;if(!o)return;let h=n.filter(d=>d.type==="JSXText"?d.value.trim()!=="":!0);if(h.length===0)return;let f=c.loc.start.line===o.loc.end.line,l=h.every(y);if(f&&l||h.length===1&&y(h[0]))return;let u=h[0],T=h[h.length-1],x=" ".repeat(c.loc.start.column+4),b=" ".repeat(c.loc.start.column);if(c.loc.end.line===u.loc.start.line&&e.report({fix:d=>d.replaceTextRange([c.range[1],u.range[0]],`
|
|
153
|
+
`+x),message:"JSX child should be on its own line",node:u}),o.loc.start.line===T.loc.end.line){if(T.type==="JSXText"){let d=T.value,E=d.trimEnd();if(d.slice(E.length).includes(`
|
|
154
|
+
`))return}e.report({fix:d=>d.replaceTextRange([T.range[1],o.range[0]],`
|
|
155
|
+
`+b),message:"Closing tag should be on its own line",node:o})}};return{JSXElement:r=>{s(r,r.openingElement,r.closingElement)},JSXFragment:r=>{s(r,r.openingFragment,r.closingFragment)}}},meta:{docs:{description:"Enforce JSX children on separate lines from parent tags"},fixable:"whitespace",schema:[],type:"layout"}},ht={create(e){let t=e.sourceCode||e.getSourceCode(),I=C=>{let y=t.getLastToken(C);if(!y||y.value!==">"&&y.value!=="/>")return;let s=t.getTokenBefore(y);if(s&&s.loc.end.line===y.loc.start.line&&y.range[0]-s.range[1]>0){let g=t.text.slice(s.range[1],y.range[0]);/^\s+$/.test(g)&&e.report({fix:i=>i.removeRange([s.range[1],y.range[0]]),message:`No space allowed before '${y.value}' in JSX tag`,node:y})}};return{JSXOpeningElement:I,JSXClosingElement:I}},meta:{docs:{description:"No space before > or /> in JSX tags"},fixable:"whitespace",schema:[],type:"layout"}},xt={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>s?s.type==="Identifier"||s.type==="Literal"?!0:s.type==="MemberExpression"?s.object.type==="Identifier"&&s.property.type==="Identifier":!1:!1,C=s=>{if(!s||s.type==="Identifier"||s.type==="Literal")return!0;if(s.type==="ChainExpression")return C(s.expression);if(s.type==="MemberExpression"){let g=s;for(;g.type==="MemberExpression";){if(g.computed){if(g.property.type!=="Identifier"&&g.property.type!=="Literal")return!1}else if(g.property.type!=="Identifier")return!1;g=g.object}return g.type==="ChainExpression"?C(g.expression):g.type==="Identifier"}if(s.type==="CallExpression"){let{callee:g}=s;return g.type==="Identifier"||g.type==="MemberExpression"&&g.object.type==="Identifier"&&g.property.type==="Identifier"?!!(s.arguments.length===0||s.arguments.length===1&&I(s.arguments[0])):!1}if(s.type==="LogicalExpression"){let g=r=>r.type==="LogicalExpression"?g(r.left)+g(r.right):1;if(g(s)>2)return!1;let i=r=>r.type==="Identifier"||r.type==="Literal"?!0:r.type==="MemberExpression"?C(r):r.type==="ChainExpression"&&r.expression?i(r.expression):!1;return i(s.left)&&i(s.right)}return!1},y=s=>s.type==="JSXElement"||s.type==="JSXFragment"?!0:s.type==="JSXExpressionContainer"?!C(s.expression):!1;return{JSXElement(s){let g=s.openingElement,i=s.closingElement;if(!i)return;let{children:r}=s,c=r.filter(y);if(c.length===0)return;let o=" ".repeat(g.loc.start.column+4),n=" ".repeat(g.loc.start.column);c.forEach(f=>{g.loc.end.line===f.loc.start.line&&e.report({fix:l=>l.replaceTextRange([g.range[1],f.range[0]],`
|
|
156
|
+
`+o),message:"JSX element child should be on its own line",node:f})});let h=c[c.length-1];h&&i.loc.start.line===h.loc.end.line&&e.report({fix:f=>f.replaceTextRange([h.range[1],i.range[0]],`
|
|
157
|
+
`+n),message:"Closing tag should be on its own line after JSX children",node:i})}}},meta:{docs:{description:"JSX children that are JSX elements must be on new lines"},fixable:"whitespace",schema:[],type:"layout"}},Tt={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>{let g=t.getTokenBefore(s),i=t.getTokenAfter(s);return g&&i&&g.value==="("&&i.value===")"},C=s=>{let g=t.getText(s);return I(s)?`(${g})`:g};return{LogicalExpression:s=>{if(s.operator!=="&&")return;let{left:g,right:i}=s;if(i.type!=="JSXElement"&&i.type!=="JSXFragment")return;let r=t.lines[s.loc.start.line-1].match(/^\s*/)[0],c=r+" ",o=i.loc.start.line===i.loc.end.line,n=C(g),h=t.getText(i);if(o&&g.loc.start.line===g.loc.end.line){s.loc.start.line!==s.loc.end.line&&e.report({fix:f=>f.replaceText(s,`${n} && ${h}`),message:"Simple logical expression with single-line JSX should be on one line",node:s});return}if(!o){let f=t.getTokenAfter(g,a=>a.value==="&&");if(!f)return;let l=t.getTokenAfter(f);if(l&&l.value==="("){let a=t.getTokenAfter(l);a&&a.loc.start.line-l.loc.end.line>1&&e.report({fix:T=>T.replaceTextRange([l.range[1],a.range[0]],`
|
|
158
|
+
`+c),message:"No empty lines after '(' in logical expression",node:a});let u=t.getTokenAfter(i);u&&u.value===")"&&u.loc.start.line-i.loc.end.line>1&&e.report({fix:T=>T.replaceTextRange([i.range[1],u.range[0]],`
|
|
159
159
|
`+r),message:"No empty lines before ')' in logical expression",node:u})}}}}},meta:{docs:{description:"Simplify logical expressions in JSX when right side is single-line, and check formatting for complex JSX"},fixable:"code",schema:[],type:"layout"}},bt={create(e){let t=e.sourceCode||e.getSourceCode();return{ArrowFunctionExpression:y=>{if(y.body.type!=="JSXElement"&&y.body.type!=="JSXFragment")return;let s=y.body,g=t.getTokenBefore(y.body,o=>o.value==="=>"),i=t.getTokenAfter(g);if(!i||i.value!=="(")return;let r=i;if(g.loc.end.line!==r.loc.start.line&&e.report({fix:o=>o.replaceTextRange([g.range[1],r.range[1]]," ("),message:"Opening parenthesis should be on the same line as arrow",node:r}),r.loc.end.line===s.loc.start.line){let o=" ".repeat(r.loc.start.column+4);e.report({fix:n=>n.replaceTextRange([r.range[1],s.range[0]],`
|
|
160
160
|
`+o),message:"JSX should start on a new line after opening parenthesis",node:s})}else if(s.loc.start.line-r.loc.end.line>1){let o=" ".repeat(s.loc.start.column);e.report({fix:n=>n.replaceTextRange([r.range[1],s.range[0]],`
|
|
161
|
-
`+o),message:"No empty line after opening parenthesis",node:s})}let
|
|
162
|
-
`+n),message:"No empty line before closing parenthesis",node:
|
|
163
|
-
`)||n.includes(" "))&&e.report({fix:h=>h.replaceTextRange([
|
|
161
|
+
`+o),message:"No empty line after opening parenthesis",node:s})}let c=t.getTokenAfter(s);if(c&&c.value===")"){if(c.loc.start.line-s.loc.end.line>1){let n=" ".repeat(c.loc.start.column);e.report({fix:h=>h.replaceTextRange([s.range[1],c.range[0]],`
|
|
162
|
+
`+n),message:"No empty line before closing parenthesis",node:c})}let o=t.getTokenAfter(c);if(o&&o.value==="}"){let n=t.text.slice(c.range[1],o.range[0]);(n.includes(`
|
|
163
|
+
`)||n.includes(" "))&&e.report({fix:h=>h.replaceTextRange([c.range[1],o.range[0]],""),message:"Closing parenthesis and brace should be together",node:o})}}},Property:y=>{if(!y.value||y.value.type!=="JSXElement"&&y.value.type!=="JSXFragment")return;let s=t.getTokenAfter(y.key,o=>o.value===":"),g=t.getTokenAfter(s);if(!g||g.value!=="(")return;let i=g,r=y.value;if(s.loc.end.line!==i.loc.start.line&&e.report({fix:o=>o.replaceTextRange([s.range[1],i.range[1]]," ("),message:"Opening parenthesis should be on the same line as colon with a space",node:i}),i.loc.end.line===r.loc.start.line){let o=" ".repeat(y.key.loc.start.column+4);e.report({fix:n=>n.replaceTextRange([i.range[1],r.range[0]],`
|
|
164
164
|
`+o),message:"JSX should start on a new line after opening parenthesis",node:r})}else if(r.loc.start.line-i.loc.end.line>1){let o=" ".repeat(r.loc.start.column);e.report({fix:n=>n.replaceTextRange([i.range[1],r.range[0]],`
|
|
165
|
-
`+o),message:"No empty line after opening parenthesis",node:r})}let
|
|
166
|
-
`+o),message:"No empty line before closing parenthesis",node:
|
|
167
|
-
`),A=[...
|
|
168
|
-
`+A.map(
|
|
165
|
+
`+o),message:"No empty line after opening parenthesis",node:r})}let c=t.getTokenAfter(r);if(c&&c.value===")"&&c.loc.start.line-r.loc.end.line>1){let o=" ".repeat(c.loc.start.column);e.report({fix:n=>n.replaceTextRange([r.range[1],c.range[0]],`
|
|
166
|
+
`+o),message:"No empty line before closing parenthesis",node:c})}}}},meta:{docs:{description:"Enforce opening parenthesis position for JSX in arrow functions and object properties"},fixable:"code",schema:[],type:"layout"}},kt={create(e){let t=/^[a-z][a-zA-Z0-9]*$/,I=["Icon","Component","FormComponent","Layout","Wrapper","Container","Provider","Element","Trigger","Content","Header","Footer","Body","Title","Overlay","Portal","Root","Item","Label","Input","Button","Action","Slot"];return{JSXAttribute(C){if(!C.name)return;let y=C.name.type==="JSXIdentifier"?C.name.name:C.name.name?.name;!y||y.startsWith("data-")||y.startsWith("aria-")||I.includes(y)||["Icon","Component","Element","Wrapper","Container","Layout","Provider"].some(g=>y.endsWith(g)&&y!==g)||t.test(y)||e.report({message:`JSX prop "${y}" should be camelCase`,node:C.name})}}},meta:{docs:{description:"Enforce camelCase naming for JSX props, with exceptions for component references"},schema:[],type:"suggestion"}},Et={create(e){let t=e.sourceCode||e.getSourceCode(),I=s=>s?s.type==="Identifier"||s.type==="Literal"?!0:s.type==="MemberExpression"?s.object.type==="Identifier"&&s.property.type==="Identifier":!1:!1,C=s=>{if(!s)return!1;if(s.type==="Identifier"||s.type==="Literal")return!0;if(s.type==="MemberExpression")return s.object.type==="Identifier"&&s.property.type==="Identifier";if(s.type==="CallExpression"){let{callee:g}=s;return g.type==="Identifier"||g.type==="MemberExpression"&&g.object.type==="Identifier"&&g.property.type==="Identifier"?!!(s.arguments.length===0||s.arguments.length===1&&I(s.arguments[0])):!1}return!1},y=s=>s.type==="JSXText"?s.value.trim().length>0:s.type==="JSXExpressionContainer"?C(s.expression):!1;return{JSXElement(s){let g=s.openingElement,i=s.closingElement;if(!i||g.loc.end.line===i.loc.start.line)return;let{children:r}=s,c=r.filter(l=>l.type==="JSXText"?l.value.trim()!=="":!0);if(c.length!==1)return;let o=c[0];if(!y(o)||g.loc.start.line!==g.loc.end.line)return;let n=t.getText(g),h=o.type==="JSXText"?o.value.trim():t.getText(o),f=t.getText(i);e.report({fix:l=>l.replaceText(s,`${n}${h}${f}`),message:"Simple JSX element with single text/expression child should be on one line",node:s})}}},meta:{docs:{description:"Simple JSX elements with only text/expression children should be on one line"},fixable:"whitespace",schema:[],type:"layout"}},St={create(e){let t=e.sourceCode||e.getSourceCode(),I=y=>y.quasis.map(s=>s.value.raw).join(" ").trim(),C=(y,s,g)=>{let{expressions:i,quasis:r}=y;if(i.length===0)return;let c=I(y);if(te(g,c))for(let o=0;o<i.length;o+=1){let n=r[o+1];if(n&&n.value.raw.trim().length>0){e.report({fix:f=>{let l=[],a=[];r.forEach(b=>{let d=b.value.raw.trim();d&&l.push(d)}),i.forEach(b=>{a.push(t.getText(b))});let u=pe(l.join(" ")),T=a.map(b=>`\${${b}}`).join(" "),x=u?`\`${u} ${T}\``:`\`${T}\``;return f.replaceText(y,x)},message:"Dynamic expressions (${...}) must be at the end of class strings. Use: `static-class ${dynamic}` not `${dynamic} static-class`",node:s||i[o]});return}}};return{JSXAttribute(y){!y.name||y.name.name!=="className"||y.value&&y.value.type==="JSXExpressionContainer"&&y.value.expression.type==="TemplateLiteral"&&C(y.value.expression,null,"className")},VariableDeclarator(y){!y.id||y.id.type!=="Identifier"||y.init&&y.init.type==="TemplateLiteral"&&C(y.init,y.init,y.id.name)}}},meta:{docs:{description:"Enforce dynamic expressions in className are placed at the end"},fixable:"code",schema:[],type:"layout"}},wt={create(e){let t=e.sourceCode||e.getSourceCode(),I=(y,s,g)=>{if(te(g,s)&&!/^\n/.test(s)&&/ +/.test(s)){let r=t.getText(y)[0],c=s.replace(/ +/g," ");e.report({fix:o=>o.replaceText(y,`${r}${c}${r}`),message:"Class string should not have multiple consecutive spaces",node:y})}},C=(y,s)=>{let{quasis:g}=y,i=g.map(n=>n.value.raw).join(" ").trim();if(!te(s,i))return;let r=g[0],c=r&&/^\n/.test(r.value.raw);if(!c&&r&&/^\s+/.test(r.value.raw)){e.report({fix:n=>{let f=t.getText(y).replace(/^`\s+/,"`");return n.replaceText(y,f)},message:"Class string should not have leading whitespace in template literal",node:r});return}let o=g[g.length-1];if(!c&&o&&/\s+$/.test(o.value.raw)){e.report({fix:n=>{let f=t.getText(y).replace(/\s+`$/,"`");return n.replaceText(y,f)},message:"Class string should not have trailing whitespace in template literal",node:o});return}c||g.forEach(n=>{let h=n.value.raw;/ +/.test(h)&&e.report({fix:f=>{let a=t.getText(y).replace(/ +/g," ");return f.replaceText(y,a)},message:"Class string should not have multiple consecutive spaces",node:n})})};return{JSXAttribute(y){!y.name||y.name.name!=="className"||(y.value&&y.value.type==="Literal"&&typeof y.value.value=="string"&&I(y.value,y.value.value,"className"),y.value&&y.value.type==="JSXExpressionContainer"&&y.value.expression.type==="TemplateLiteral"&&C(y.value.expression,"className"))},VariableDeclarator(y){if(!y.id||y.id.type!=="Identifier")return;let s=y.id.name;y.init&&y.init.type==="Literal"&&typeof y.init.value=="string"&&I(y.init,y.init.value,s),y.init&&y.init.type==="TemplateLiteral"&&C(y.init,s),y.init&&y.init.type==="ObjectExpression"&&y.init.properties.forEach(g=>{if(g.type==="Property"){if(g.value&&g.value.type==="Literal"&&typeof g.value.value=="string"){let i=g.value.value;if(!te(s,i))return;let c=t.getText(g.value)[0];if(/^\s+/.test(i)){let o=i.trimStart();e.report({fix:n=>n.replaceText(g.value,`${c}${o}${c}`),message:"Class string should not have leading whitespace",node:g.value});return}if(/\s+$/.test(i)){let o=i.trimEnd();e.report({fix:n=>n.replaceText(g.value,`${c}${o}${c}`),message:"Class string should not have trailing whitespace",node:g.value});return}if(/ +/.test(i)){let o=i.replace(/ +/g," ");e.report({fix:n=>n.replaceText(g.value,`${c}${o}${c}`),message:"Class string should not have multiple consecutive spaces",node:g.value})}}if(g.value&&g.value.type==="TemplateLiteral"){let i=g.value.quasis.map(r=>r.value.raw).join(" ").trim();te(s,i)&&C(g.value,s)}}})},ReturnStatement(y){y.argument&&(y.argument.type==="Literal"&&typeof y.argument.value=="string"&&I(y.argument,y.argument.value,"return"),y.argument.type==="TemplateLiteral"&&C(y.argument,"return"))}}},meta:{docs:{description:"Disallow extra/leading/trailing spaces in className values; smart detection for objects with Tailwind values and return statements"},fixable:"code",schema:[],type:"layout"}},vt={create(e){let t=e.sourceCode||e.getSourceCode(),I=(y,s,g)=>{if(!te(g,s)||!ye(s))return;let i=pe(s),c=t.getText(y)[0];e.report({fix:o=>o.replaceText(y,`${c}${i}${c}`),message:"Tailwind classes should follow recommended order: layout (flex, grid) \u2192 sizing (w, h) \u2192 spacing (p, m) \u2192 typography (text, font) \u2192 colors (bg, text) \u2192 effects (shadow, opacity) \u2192 states (hover, focus)",node:y})},C=(y,s)=>{let{expressions:g,quasis:i}=y,r=i.map(o=>o.value.raw).join(" ").trim();if(!te(s,r))return;let c=!1;for(let o of i){let n=o.value.raw.trim();if(n&&ye(n)){c=!0;break}}c&&e.report({fix:o=>{let n="`";for(let h=0;h<i.length;h+=1){let l=i[h].value.raw,a=l.match(/^\s*/)[0],u=l.match(/\s*$/)[0],T=l.trim(),x=/\n/.test(T),b;if(x&&T){let d=l.split(`
|
|
167
|
+
`),A=[...d.map(m=>m.trim()).filter(Boolean)].sort((m,w)=>{let L=me(m),R=me(w);return L!==R?L-R:m.localeCompare(w)}),S=d.find(m=>m.trim().length>0),k=S?S.match(/^\s*/)[0]:"",v=d[d.length-1].match(/^\s*/),p=v?v[0]:"";n+=`
|
|
168
|
+
`+A.map(m=>k+m).join(`
|
|
169
169
|
`)+`
|
|
170
|
-
`+p}else T
|
|
171
|
-
`)[f.loc.start.line-1];if(!u)return"";let
|
|
172
|
-
${
|
|
170
|
+
`+p}else b=T?pe(T):"",n+=a+b+u;h<g.length&&(n+="${"+t.getText(g[h])+"}")}return n+="`",o.replaceText(y,n)},message:"Tailwind classes should follow recommended order: layout (flex, grid) \u2192 sizing (w, h) \u2192 spacing (p, m) \u2192 typography (text, font) \u2192 colors (bg, text) \u2192 effects (shadow, opacity) \u2192 states (hover, focus)",node:y})};return{VariableDeclarator(y){if(!y.id||y.id.type!=="Identifier")return;let s=y.id.name;y.init&&y.init.type==="Literal"&&typeof y.init.value=="string"&&I(y.init,y.init.value,s),y.init&&y.init.type==="TemplateLiteral"&&C(y.init,s),y.init&&y.init.type==="ObjectExpression"&&y.init.properties.forEach(g=>{if(g.type==="Property"){if(g.value&&g.value.type==="Literal"&&typeof g.value.value=="string"){let i=g.value.value;if(!te(s,i))return;if(ye(i)){let r=pe(i),o=t.getText(g.value)[0];e.report({fix:n=>n.replaceText(g.value,`${o}${r}${o}`),message:"Tailwind classes should follow recommended order: layout (flex, grid) \u2192 sizing (w, h) \u2192 spacing (p, m) \u2192 typography (text, font) \u2192 colors (bg, text) \u2192 effects (shadow, opacity) \u2192 states (hover, focus)",node:g.value})}}if(g.value&&g.value.type==="TemplateLiteral"){let i=g.value.quasis.map(r=>r.value.raw).join(" ").trim();te(s,i)&&C(g.value,s)}}})},ReturnStatement(y){if(y.argument){if(y.argument.type==="Literal"&&typeof y.argument.value=="string"){let s=y.argument.value;if(de(s)&&ye(s)){let g=pe(s),r=t.getText(y.argument)[0];e.report({fix:c=>c.replaceText(y.argument,`${r}${g}${r}`),message:"Tailwind classes should follow recommended order: layout (flex, grid) \u2192 sizing (w, h) \u2192 spacing (p, m) \u2192 typography (text, font) \u2192 colors (bg, text) \u2192 effects (shadow, opacity) \u2192 states (hover, focus)",node:y.argument})}}y.argument.type==="TemplateLiteral"&&C(y.argument,"return")}}}},meta:{docs:{description:"Enforce Tailwind CSS class ordering in class strings; smart detection for objects with Tailwind values and return statements"},fixable:"code",schema:[],type:"layout"}},Ct={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxClassCount??be,y=I.maxLength??ke,s=f=>{let u=t.getText().split(`
|
|
171
|
+
`)[f.loc.start.line-1];if(!u)return"";let T=u.match(/^(\s*)/);return T?T[1]:""},g=(f,l,a)=>{let u=a+" ",T=f.map(x=>`${u}${x}`);return l.forEach(x=>{T.push(`${u}\${${x}}`)}),`\`
|
|
172
|
+
${T.join(`
|
|
173
173
|
`)}
|
|
174
|
-
${a}\``},i=(f,
|
|
175
|
-
${f.map(
|
|
174
|
+
${a}\``},i=(f,l)=>{let a=l+" ";return`"
|
|
175
|
+
${f.map(T=>`${a}${T}`).join(`
|
|
176
176
|
`)}
|
|
177
|
-
${
|
|
178
|
-
`);if(u[0].trim()!==""||u[u.length-1]!==
|
|
179
|
-
`+
|
|
180
|
-
`+x),message:"Closing ')' should be on new line",node:w}),A&&A.value==="}"&&w.loc.end.line!==A.loc.start.line&&e.report({fix:R=>R.replaceTextRange([w.range[1],A.range[0]],""),message:"Closing ')}' should be together",node:A})}return}if(!u&&
|
|
181
|
-
`+
|
|
182
|
-
`+x),message:"Closing ')' should be on new line after complex JSX",node:w}),w.loc.end.line!==E.loc.start.line&&e.report({fix:P=>P.replaceTextRange([w.range[1],E.range[0]]," "),message:"':' should be on same line as ')'",node:E})}let L=t.getTokenAfter(E);if(L&&L.value==="("){let R=t.getTokenAfter(h);if(R&&R.value===")"){let P=t.getText(h);e.report({fix:H=>H.replaceTextRange([E.range[1],R.range[1]],` ${P}`),message:"Simple JSX should not be wrapped in parentheses; put on same line as ':'",node:h});return}}E.loc.end.line!==h.loc.start.line&&e.report({fix:R=>R.replaceTextRange([E.range[1],h.range[0]]," "),message:"Simple JSX should be on same line as ':'",node:h}),A&&A.value==="}"&&h.loc.end.line!==A.loc.start.line&&e.report({fix:R=>R.replaceTextRange([h.range[1],A.range[0]],""),message:"'}' should be on same line as simple JSX",node:A});return}let S=!a&&(h.type==="Literal"||h.type==="Identifier"||h.type==="MemberExpression"&&h.loc.start.line===h.loc.end.line);if(!u&&
|
|
183
|
-
`+
|
|
184
|
-
`+
|
|
177
|
+
${l}"`},r=(f,l,a)=>f.length+l>C||a>y,c=(f,l)=>{if(!/\n/.test(f))return!1;let a=l+" ",u=f.split(`
|
|
178
|
+
`);if(u[0].trim()!==""||u[u.length-1]!==l)return!1;for(let T=1;T<u.length-1;T+=1){if(u[T].trim()===""||!u[T].startsWith(a))return!1;let x=u[T].slice(a.length);if(x.includes(" ")&&!x.startsWith("${"))return!1}return!0},o=f=>{let l=f;for(;l;){if(l.type==="JSXAttribute"){let a=s(l);return t.lines[l.loc.start.line-1].slice(0,l.loc.start.column).trim()?" ".repeat(l.loc.start.column):a}if(l.type==="VariableDeclarator"||l.type==="Property"||l.type==="ReturnStatement")return s(l);l=l.parent}return s(f)},n=(f,l,a)=>{if(!te(a,l))return;let u=l.trim().split(/\s+/).filter(Boolean),T=u.join(" "),x=/\n/.test(l);if(!r(u,0,T.length)){if(x){let E=t.getText(f)[0];e.report({fix:A=>A.replaceText(f,`${E}${T}${E}`),message:"Class string under threshold should be on a single line",node:f})}return}let b=o(f);c(l,b)||e.report({fix:d=>{let E=f.parent;return E&&E.type==="JSXAttribute"?d.replaceText(f,i(u,b)):d.replaceText(f,g(u,[],b))},message:`Class strings with >${C} classes or >${y} chars should be multiline with one class per line. Example: className="\\n flex\\n items-center\\n"`,node:f})},h=(f,l)=>{let{expressions:a,quasis:u}=f,T=u.map(v=>v.value.raw).join(" ").trim();if(!te(l,T))return;let x=T.split(/\s+/).filter(Boolean),b=a.map(v=>t.getText(v)),d=T.length+b.reduce((v,p)=>v+p.length+3,0),E=f.parent,A=E&&E.type==="JSXExpressionContainer"&&E.parent&&E.parent.type==="JSXAttribute";if(!r(x,b.length,d)){let v=u.map((p,m)=>p.value.raw+(m<a.length?`\${${b[m]}}`:"")).join("");if(/\n/.test(v)){let p=x.join(" ");if(A&&b.length===0)e.report({fix:m=>m.replaceText(E,`"${p}"`),message:"Class string under threshold should be on a single line",node:f});else if(b.length===0)e.report({fix:m=>m.replaceText(f,`\`${p}\``),message:"Class string under threshold should be on a single line",node:f});else{let m=[p,...b.map(w=>`\${${w}}`)];e.report({fix:w=>w.replaceText(f,`\`${m.join(" ")}\``),message:"Class string under threshold should be on a single line",node:f})}}return}let S=o(f);if(A&&b.length===0){let v=i(x,S);e.report({fix:p=>p.replaceText(E,v),message:"Use string literal instead of template literal for className with no dynamic expressions",node:f});return}let k=u.map((v,p)=>v.value.raw+(p<a.length?`\${${b[p]}}`:"")).join("");if(c(k,S))return;let $=g(x,b,S);e.report({fix:v=>v.replaceText(f,$),message:`Class strings with >${C} classes or >${y} chars should be multiline with one class per line. Example: className="\\n flex\\n items-center\\n"`,node:f})};return{JSXAttribute(f){!f.name||f.name.name!=="className"||(f.value&&f.value.type==="Literal"&&typeof f.value.value=="string"&&n(f.value,f.value.value,"className"),f.value&&f.value.type==="JSXExpressionContainer"&&f.value.expression.type==="TemplateLiteral"&&h(f.value.expression,"className"))},VariableDeclarator(f){if(!f.id||f.id.type!=="Identifier")return;let l=f.id.name;f.init&&f.init.type==="Literal"&&typeof f.init.value=="string"&&n(f.init,f.init.value,l),f.init&&f.init.type==="TemplateLiteral"&&h(f.init,l),f.init&&f.init.type==="ObjectExpression"&&f.init.properties.forEach(a=>{if(a.type==="Property"&&(a.value&&a.value.type==="Literal"&&typeof a.value.value=="string"&&te(l,a.value.value)&&n(a.value,a.value.value,l),a.value&&a.value.type==="TemplateLiteral")){let u=a.value.quasis.map(T=>T.value.raw).join(" ").trim();te(l,u)&&h(a.value,l)}})},CallExpression(f){if(!f.callee)return;let l=f.callee.name||f.callee.property&&f.callee.property.name;!l||!new Set(["cn","cva","clsx","twMerge","classnames","cx","tv","twJoin"]).has(l)||f.arguments.forEach(u=>{if(u.type==="Literal"&&typeof u.value=="string"&&n(u,u.value,"className"),u.type==="TemplateLiteral"&&h(u,"className"),u.type==="ObjectExpression"){let T=u.properties.find(x=>x.type==="Property"&&x.key&&(x.key.name==="variants"||x.key.value==="variants"));T&&T.value&&T.value.type==="ObjectExpression"&&T.value.properties.forEach(x=>{x.type!=="Property"||!x.value||x.value.type!=="ObjectExpression"||x.value.properties.forEach(b=>{b.type==="Property"&&(b.value&&b.value.type==="Literal"&&typeof b.value.value=="string"&&n(b.value,b.value.value,"className"),b.value&&b.value.type==="TemplateLiteral"&&h(b.value,"className"))})})}})},ReturnStatement(f){if(f.argument){if(f.argument.type==="Literal"&&typeof f.argument.value=="string"){let l=f.argument.value;de(l)&&n(f.argument,l,"return")}if(f.argument.type==="TemplateLiteral"){let l=f.argument.quasis.map(a=>a.value.raw).join(" ").trim();de(l)&&h(f.argument,"return")}}}}},meta:{docs:{description:"Enforce multiline formatting for long className strings; smart detection for objects with Tailwind values, return statements, and class utility calls (cn, cva, clsx)"},fixable:"code",schema:[{additionalProperties:!1,properties:{maxClassCount:{default:3,minimum:1,type:"integer"},maxLength:{default:80,minimum:1,type:"integer"}},type:"object"}],type:"layout"}},At={create(e){let t=e.sourceCode||e.getSourceCode();return{JSXAttribute:C=>{if(!C.value||C.value.type!=="Literal"||typeof C.value.value!="string")return;let y=C.value.value;if(C.name&&C.name.name==="className"&&/^\n/.test(y))return;let s=y.trim();if(y!==s){let i=t.getText(C.value)[0];e.report({fix:r=>r.replaceText(C.value,`${i}${s}${i}`),message:"JSX string value should not have leading or trailing whitespace",node:C.value})}}}},meta:{docs:{description:"Disallow leading/trailing whitespace in JSX string values"},fixable:"code",schema:[],type:"layout"}},$t={create(e){let t=e.sourceCode||e.getSourceCode(),I=i=>{let c=t.lines[i.loc.start.line-1].match(/^(\s*)/);return c?c[1]:""},C=i=>i.type!=="JSXElement"&&i.type!=="JSXFragment"?!1:i.loc.start.line===i.loc.end.line,y=i=>{let r=t.getTokenBefore(i),c=t.getTokenAfter(i);return r&&c&&r.value==="("&&c.value===")"},s=i=>{if(i.type==="BinaryExpression"){let r=i.left.loc.end.line,c=i.right.loc.start.line;return r!==c?!0:s(i.left)||s(i.right)}if(i.type==="LogicalExpression"){let r=i.left.loc.end.line,c=i.right.loc.start.line;return r!==c?!0:s(i.left)||s(i.right)}return!1},g=i=>t.getText(i).replace(/\s*\n\s*/g," ").trim();return{ConditionalExpression(i){let r=i.parent,c=r&&r.type==="JSXExpressionContainer",o=r&&r.type==="ReturnStatement",n=r&&r.type==="ArrowFunctionExpression"&&r.body===i;if(!c&&!o&&!n)return;let{alternate:h,consequent:f}=i,l=f.type==="JSXElement"||f.type==="JSXFragment",a=h.type==="JSXElement"||h.type==="JSXFragment";if(!l&&!a)return;let u=C(f),T=C(h),x=I(i),b=x+" ";if(s(i.test)){let m=g(i.test);e.report({fix:w=>w.replaceText(i.test,m),message:"Ternary condition should not be broken across multiple lines",node:i.test})}if(c){let m=t.getFirstToken(r);m&&m.value==="{"&&m.loc.end.line!==i.test.loc.start.line&&e.report({fix:w=>w.replaceTextRange([m.range[1],i.test.range[0]],""),message:"Ternary condition should be on same line as opening '{'",node:i.test})}let d=t.getTokenAfter(i.test,m=>m.value==="?");if(!d)return;let E=t.getTokenAfter(f,m=>m.value===":");if(!E)return;let A=c?t.getLastToken(r):null;if(u&&y(f)){let m=t.getTokenBefore(f),w=t.getTokenAfter(f);e.report({fix:L=>[L.remove(m),L.remove(w)],message:"Unnecessary parentheses around simple JSX element",node:f})}if(T&&y(h)){let m=t.getTokenBefore(h),w=t.getTokenAfter(h);e.report({fix:L=>[L.remove(m),L.remove(w)],message:"Unnecessary parentheses around simple JSX element",node:h})}if(u&&T){if(i.loc.start.line!==i.loc.end.line){let m=t.getText(i.test),w=t.getText(f),L=t.getText(h);e.report({fix:R=>R.replaceText(i,`${m} ? ${w} : ${L}`),message:"Simple ternary with single-line JSX should be on one line",node:i})}return}if(u&&l&&!a){i.test.loc.end.line!==d.loc.start.line&&e.report({fix:m=>m.replaceTextRange([i.test.range[1],d.range[0]]," "),message:"'?' should be on same line as condition",node:d}),d.loc.end.line!==f.loc.start.line&&e.report({fix:m=>m.replaceTextRange([d.range[1],f.range[0]]," "),message:"Simple JSX should be on same line as '?'",node:f}),f.loc.end.line!==E.loc.start.line&&e.report({fix:m=>m.replaceTextRange([f.range[1],E.range[0]]," "),message:"':' should be on same line as simple JSX",node:E}),E.loc.end.line!==h.loc.start.line&&e.report({fix:m=>m.replaceTextRange([E.range[1],h.range[0]]," "),message:"Expression should start on same line as ':'",node:h});return}if(u&&!T&&a){i.test.loc.end.line!==d.loc.start.line&&e.report({fix:L=>L.replaceTextRange([i.test.range[1],d.range[0]]," "),message:"'?' should be on same line as condition",node:d}),d.loc.end.line!==f.loc.start.line&&e.report({fix:L=>L.replaceTextRange([d.range[1],f.range[0]]," "),message:"Simple JSX should be on same line as '?'",node:f}),f.loc.end.line!==E.loc.start.line&&e.report({fix:L=>L.replaceTextRange([f.range[1],E.range[0]]," "),message:"':' should be on same line as simple JSX",node:E});let m=t.getTokenAfter(E);if(m&&m.value==="("){E.loc.end.line!==m.loc.start.line&&e.report({fix:R=>R.replaceTextRange([E.range[1],m.range[0]]," "),message:"'(' should be on same line as ':'",node:m});let L=t.getTokenAfter(m);L&&m.loc.end.line===L.loc.start.line&&e.report({fix:R=>R.replaceTextRange([m.range[1],L.range[0]],`
|
|
179
|
+
`+b),message:"Complex JSX should start on new line after '('",node:h})}let w=t.getLastToken(i);if(w&&w.value===")"){let L=t.getTokenBefore(w);L&&L.value!=="("&&L.loc.end.line===w.loc.start.line&&e.report({fix:R=>R.replaceTextRange([L.range[1],w.range[0]],`
|
|
180
|
+
`+x),message:"Closing ')' should be on new line",node:w}),A&&A.value==="}"&&w.loc.end.line!==A.loc.start.line&&e.report({fix:R=>R.replaceTextRange([w.range[1],A.range[0]],""),message:"Closing ')}' should be together",node:A})}return}if(!u&&T&&l){let m=t.getTokenAfter(d);if(m&&m.value==="("){i.test.loc.end.line!==d.loc.start.line&&e.report({fix:P=>P.replaceTextRange([i.test.range[1],d.range[0]]," "),message:"'?' should be on same line as condition",node:d}),d.loc.end.line!==m.loc.start.line&&e.report({fix:P=>P.replaceTextRange([d.range[1],m.range[0]]," "),message:"'(' should be on same line as '?'",node:m});let R=t.getTokenAfter(m);R&&m.loc.end.line===R.loc.start.line&&e.report({fix:P=>P.replaceTextRange([m.range[1],R.range[0]],`
|
|
181
|
+
`+b),message:"Complex JSX should start on new line after '('",node:f})}let w=t.getTokenBefore(E);if(w&&w.value===")"){let R=t.getTokenBefore(w);R&&R.loc.end.line===w.loc.start.line&&e.report({fix:P=>P.replaceTextRange([R.range[1],w.range[0]],`
|
|
182
|
+
`+x),message:"Closing ')' should be on new line after complex JSX",node:w}),w.loc.end.line!==E.loc.start.line&&e.report({fix:P=>P.replaceTextRange([w.range[1],E.range[0]]," "),message:"':' should be on same line as ')'",node:E})}let L=t.getTokenAfter(E);if(L&&L.value==="("){let R=t.getTokenAfter(h);if(R&&R.value===")"){let P=t.getText(h);e.report({fix:H=>H.replaceTextRange([E.range[1],R.range[1]],` ${P}`),message:"Simple JSX should not be wrapped in parentheses; put on same line as ':'",node:h});return}}E.loc.end.line!==h.loc.start.line&&e.report({fix:R=>R.replaceTextRange([E.range[1],h.range[0]]," "),message:"Simple JSX should be on same line as ':'",node:h}),A&&A.value==="}"&&h.loc.end.line!==A.loc.start.line&&e.report({fix:R=>R.replaceTextRange([h.range[1],A.range[0]],""),message:"'}' should be on same line as simple JSX",node:A});return}let S=!a&&(h.type==="Literal"||h.type==="Identifier"||h.type==="MemberExpression"&&h.loc.start.line===h.loc.end.line);if(!u&&l&&S){let m=t.getTokenAfter(d);if(m&&m.value==="("){i.test.loc.end.line!==d.loc.start.line&&e.report({fix:R=>R.replaceTextRange([i.test.range[1],d.range[0]]," "),message:"'?' should be on same line as condition",node:d}),d.loc.end.line!==m.loc.start.line&&e.report({fix:R=>R.replaceTextRange([d.range[1],m.range[0]]," "),message:"'(' should be on same line as '?'",node:m});let L=t.getTokenAfter(m);L&&m.loc.end.line===L.loc.start.line?e.report({fix:R=>R.replaceTextRange([m.range[1],L.range[0]],`
|
|
183
|
+
`+b),message:"Complex JSX should start on new line after '('",node:f}):L&&L.loc.start.line-m.loc.end.line>1&&e.report({fix:R=>R.replaceTextRange([m.range[1],L.range[0]],`
|
|
184
|
+
`+b),message:"No empty lines after '(' in ternary",node:L})}let w=t.getTokenBefore(E);if(w&&w.value===")"){let L=t.getTokenBefore(w);L&&L.loc.end.line===w.loc.start.line?e.report({fix:R=>R.replaceTextRange([L.range[1],w.range[0]],`
|
|
185
185
|
`+x),message:"Closing ')' should be on new line after complex JSX",node:w}):w.loc.start.line-L.loc.end.line>1&&e.report({fix:R=>R.replaceTextRange([L.range[1],w.range[0]],`
|
|
186
|
-
`+x),message:"No empty lines before ')' in ternary",node:w}),w.loc.end.line!==E.loc.start.line&&e.report({fix:R=>R.replaceTextRange([w.range[1],E.range[0]]," "),message:"':' should be on same line as ')'",node:E})}E.loc.end.line!==h.loc.start.line&&e.report({fix:L=>L.replaceTextRange([E.range[1],h.range[0]]," "),message:"Simple expression should be on same line as ':'",node:h});return}if(!
|
|
187
|
-
`+
|
|
188
|
-
`+
|
|
189
|
-
`+x),message:"Closing ')' should be on new line after complex JSX",node:$}):
|
|
190
|
-
`+x),message:"No empty lines before ')' in ternary",node:$}),$.loc.end.line!==E.loc.start.line&&e.report({fix:w=>w.replaceTextRange([$.range[1],E.range[0]]," "),message:"':' should be on same line as ')'",node:E})}if(v&&v.value==="("){E.loc.end.line!==v.loc.start.line&&e.report({fix:w=>w.replaceTextRange([E.range[1],v.range[0]]," "),message:"'(' should be on same line as ':'",node:v});let
|
|
191
|
-
`+
|
|
192
|
-
`+
|
|
193
|
-
`+x),message:"Closing ')' should be on new line",node:p}):
|
|
194
|
-
`+x),message:"No empty lines before ')' in ternary",node:p}),A&&A.value==="}"&&p.loc.end.line!==A.loc.start.line&&e.report({fix:w=>w.replaceTextRange([p.range[1],A.range[0]],""),message:"Closing ')}' should be together on same line",node:A})}}}},meta:{docs:{description:"Enforce consistent formatting for JSX ternary expressions"},fixable:"whitespace",schema:[],type:"layout"}},Lt={create(e){let t=e.sourceCode||e.getSourceCode(),I=i=>{let{children:r,closingElement:
|
|
195
|
-
`+" ".repeat(h.loc.start.column)),message:"No empty line after opening JSX tag",node:h}),
|
|
196
|
-
`+" ".repeat(
|
|
186
|
+
`+x),message:"No empty lines before ')' in ternary",node:w}),w.loc.end.line!==E.loc.start.line&&e.report({fix:R=>R.replaceTextRange([w.range[1],E.range[0]]," "),message:"':' should be on same line as ')'",node:E})}E.loc.end.line!==h.loc.start.line&&e.report({fix:L=>L.replaceTextRange([E.range[1],h.range[0]]," "),message:"Simple expression should be on same line as ':'",node:h});return}if(!l||!a)return;let k=t.getTokenAfter(d);if(k&&k.value==="("){i.test.loc.end.line!==d.loc.start.line&&e.report({fix:w=>w.replaceTextRange([i.test.range[1],d.range[0]]," "),message:"'?' should be on same line as condition",node:d}),d.loc.end.line!==k.loc.start.line&&e.report({fix:w=>w.replaceTextRange([d.range[1],k.range[0]]," "),message:"'(' should be on same line as '?'",node:k});let m=t.getTokenAfter(k);m&&k.loc.end.line===m.loc.start.line?e.report({fix:w=>w.replaceTextRange([k.range[1],m.range[0]],`
|
|
187
|
+
`+b),message:"Complex JSX should start on new line after '('",node:f}):m&&m.loc.start.line-k.loc.end.line>1&&e.report({fix:w=>w.replaceTextRange([k.range[1],m.range[0]],`
|
|
188
|
+
`+b),message:"No empty lines after '(' in ternary",node:m})}let $=t.getTokenBefore(E),v=t.getTokenAfter(E);if($&&$.value===")"){let m=t.getTokenBefore($);m&&m.loc.end.line===$.loc.start.line?e.report({fix:w=>w.replaceTextRange([m.range[1],$.range[0]],`
|
|
189
|
+
`+x),message:"Closing ')' should be on new line after complex JSX",node:$}):m&&$.loc.start.line-m.loc.end.line>1&&e.report({fix:w=>w.replaceTextRange([m.range[1],$.range[0]],`
|
|
190
|
+
`+x),message:"No empty lines before ')' in ternary",node:$}),$.loc.end.line!==E.loc.start.line&&e.report({fix:w=>w.replaceTextRange([$.range[1],E.range[0]]," "),message:"':' should be on same line as ')'",node:E})}if(v&&v.value==="("){E.loc.end.line!==v.loc.start.line&&e.report({fix:w=>w.replaceTextRange([E.range[1],v.range[0]]," "),message:"'(' should be on same line as ':'",node:v});let m=t.getTokenAfter(v);m&&v.loc.end.line===m.loc.start.line?e.report({fix:w=>w.replaceTextRange([v.range[1],m.range[0]],`
|
|
191
|
+
`+b),message:"Complex JSX should start on new line after '('",node:h}):m&&m.loc.start.line-v.loc.end.line>1&&e.report({fix:w=>w.replaceTextRange([v.range[1],m.range[0]],`
|
|
192
|
+
`+b),message:"No empty lines after '(' in ternary",node:m})}let p=t.getLastToken(i);if(p&&p.value===")"){let m=t.getTokenBefore(p);m&&m.value!=="("&&m.loc.end.line===p.loc.start.line?e.report({fix:w=>w.replaceTextRange([m.range[1],p.range[0]],`
|
|
193
|
+
`+x),message:"Closing ')' should be on new line",node:p}):m&&m.value!=="("&&p.loc.start.line-m.loc.end.line>1&&e.report({fix:w=>w.replaceTextRange([m.range[1],p.range[0]],`
|
|
194
|
+
`+x),message:"No empty lines before ')' in ternary",node:p}),A&&A.value==="}"&&p.loc.end.line!==A.loc.start.line&&e.report({fix:w=>w.replaceTextRange([p.range[1],A.range[0]],""),message:"Closing ')}' should be together on same line",node:A})}}}},meta:{docs:{description:"Enforce consistent formatting for JSX ternary expressions"},fixable:"whitespace",schema:[],type:"layout"}},Lt={create(e){let t=e.sourceCode||e.getSourceCode(),I=i=>{let{children:r,closingElement:c,openingElement:o}=i;if(!c)return;let n=r.filter(l=>l.type!=="JSXText"||l.value.trim()!=="");if(n.length===0)return;let h=n[0],f=n[n.length-1];h.loc.start.line-o.loc.end.line>1&&e.report({fix:l=>l.replaceTextRange([o.range[1],h.range[0]],`
|
|
195
|
+
`+" ".repeat(h.loc.start.column)),message:"No empty line after opening JSX tag",node:h}),c.loc.start.line-f.loc.end.line>1&&e.report({fix:l=>l.replaceTextRange([f.range[1],c.range[0]],`
|
|
196
|
+
`+" ".repeat(c.loc.start.column)),message:"No empty line before closing JSX tag",node:c})},C=i=>i.loc.start.line===i.loc.end.line;return{ArrowFunctionExpression:i=>{if(!i.body||i.body.type==="BlockStatement")return;let r=i.body,c=t.getTokenBefore(r,h=>h.value==="=>");if(!c)return;let o=t.getTokenAfter(c);o&&o.value==="("&&r.loc.start.line-o.loc.end.line>1&&e.report({fix:h=>h.replaceTextRange([o.range[1],r.range[0]],`
|
|
197
197
|
`+" ".repeat(r.loc.start.column)),message:"No empty line allowed after opening parenthesis in arrow function",node:r});let n=t.getTokenAfter(r);n&&n.value===")"&&n.loc.start.line-r.loc.end.line>1&&e.report({fix:h=>h.replaceTextRange([r.range[1],n.range[0]],`
|
|
198
|
-
`+" ".repeat(n.loc.start.column)),message:"No empty line allowed before closing parenthesis in arrow function",node:r})},JSXElement:I,JSXOpeningElement:i=>{let{attributes:r,name:
|
|
199
|
-
`))&&e.report({fix:
|
|
200
|
-
`+" ".repeat(h.loc.start.column)),message:"No empty line after JSX element name",node:h});let u=n.range[0],
|
|
201
|
-
`+" ".repeat(
|
|
202
|
-
`+" ".repeat(
|
|
198
|
+
`+" ".repeat(n.loc.start.column)),message:"No empty line allowed before closing parenthesis in arrow function",node:r})},JSXElement:I,JSXOpeningElement:i=>{let{attributes:r,name:c}=i,o=t.getFirstToken(c),n=t.getLastToken(i);if(r.length===0)return;let h=r[0],f=r[r.length-1],l=o.loc.start.line===n.loc.end.line,a=r.length===1&&C(h);if(!i.selfClosing&&a&&l){let x=t.getTokenBefore(n);if(x){let b=t.text.slice(x.range[1],n.range[0]);(b.includes(" ")||b.includes(`
|
|
199
|
+
`))&&e.report({fix:d=>d.replaceTextRange([x.range[1],n.range[0]],""),message:"No space before closing bracket in non-self-closing JSX element",node:n})}}if(r.length===1&&C(h)&&h.loc.start.line!==o.loc.end.line){let x=t.getText(h),b=i.selfClosing,d=n.range[0],E="";b&&(E=" /"),e.report({fix:A=>A.replaceTextRange([o.range[1],d],` ${x}${E}`),message:"Single simple JSX prop should be on the same line as element",node:h});return}h.loc.start.line-o.loc.end.line>1&&e.report({fix:x=>x.replaceTextRange([o.range[1],h.range[0]],`
|
|
200
|
+
`+" ".repeat(h.loc.start.column)),message:"No empty line after JSX element name",node:h});let u=n.range[0],T=n.loc.start.column;if(i.selfClosing){let x=t.getTokenBefore(n);x&&x.value==="/"&&(u=x.range[0],T=x.loc.start.column)}n.loc.start.line-f.loc.end.line>1&&e.report({fix:x=>x.replaceTextRange([f.range[1],u],`
|
|
201
|
+
`+" ".repeat(T)),message:"No empty line before closing bracket",node:f});for(let x=0;x<r.length-1;x+=1){let b=r[x],d=r[x+1];d.loc.start.line-b.loc.end.line>1&&e.report({fix:E=>E.replaceTextRange([b.range[1],d.range[0]],`
|
|
202
|
+
`+" ".repeat(d.loc.start.column)),message:"No empty line between JSX props",node:d})}},ReturnStatement:i=>{let r=i.argument;if(!r)return;let c=t.getText(),o=c.slice(i.range[0],r.range[0]),n=o.indexOf("(");n!==-1&&o.slice(n+1).split(`
|
|
203
203
|
`).length>2&&e.report({fix:a=>a.replaceTextRange([i.range[0]+n+1,r.range[0]],`
|
|
204
|
-
`+" ".repeat(r.loc.start.column)),message:"No empty line allowed after opening parenthesis in return",node:r});let h=
|
|
205
|
-
`).length>2){let a=r.range[1]+f,u=
|
|
206
|
-
`).pop().match(/^\s*/)[0];e.report({fix:
|
|
207
|
-
`+u),message:"No empty line allowed before closing parenthesis in return",node:i})}}}},meta:{docs:{description:"Disallow empty lines in JSX"},fixable:"whitespace",schema:[],type:"layout"}};var It={create(e){let t=e.sourceCode||e.getSourceCode(),I=(C,y=!1)=>{let{properties:s}=C;if(s.length===0||y&&C.typeAnnotation)return;let g=t.getFirstToken(C),i=t.getLastToken(C),r=s[0],
|
|
208
|
-
`+" ".repeat(r.loc.start.column)),message:"No empty line after opening brace",node:r}),i.loc.start.line-
|
|
209
|
-
`+" ".repeat(i.loc.start.column)),message:"No empty line before closing brace",node:
|
|
204
|
+
`+" ".repeat(r.loc.start.column)),message:"No empty line allowed after opening parenthesis in return",node:r});let h=c.slice(r.range[1],i.range[1]),f=h.lastIndexOf(")");if(f!==-1&&h.slice(0,f).split(`
|
|
205
|
+
`).length>2){let a=r.range[1]+f,u=c.slice(0,a).split(`
|
|
206
|
+
`).pop().match(/^\s*/)[0];e.report({fix:T=>T.replaceTextRange([r.range[1],a],`
|
|
207
|
+
`+u),message:"No empty line allowed before closing parenthesis in return",node:i})}}}},meta:{docs:{description:"Disallow empty lines in JSX"},fixable:"whitespace",schema:[],type:"layout"}};var It={create(e){let t=e.sourceCode||e.getSourceCode(),I=(C,y=!1)=>{let{properties:s}=C;if(s.length===0||y&&C.typeAnnotation)return;let g=t.getFirstToken(C),i=t.getLastToken(C),r=s[0],c=s[s.length-1];r.loc.start.line-g.loc.end.line>1&&e.report({fix:o=>o.replaceTextRange([g.range[1],r.range[0]],`
|
|
208
|
+
`+" ".repeat(r.loc.start.column)),message:"No empty line after opening brace",node:r}),i.loc.start.line-c.loc.end.line>1&&e.report({fix:o=>o.replaceTextRange([c.range[1],i.range[0]],`
|
|
209
|
+
`+" ".repeat(i.loc.start.column)),message:"No empty line before closing brace",node:c});for(let o=0;o<s.length-1;o+=1){let n=s[o],h=s[o+1];if(h.loc.start.line-n.loc.end.line>1){let f=t.getTokenAfter(n);for(;f&&f.value!==","&&f.range[0]<h.range[0];)f=t.getTokenAfter(f);let l=f&&f.value===","&&f.loc.start.line!==n.loc.end.line;e.report({fix:a=>l?a.replaceTextRange([n.range[1],h.range[0]],`,
|
|
210
210
|
`+" ".repeat(h.loc.start.column)):a.replaceTextRange([f&&f.value===","?f.range[1]:n.range[1],h.range[0]],`
|
|
211
|
-
`+" ".repeat(h.loc.start.column)),message:"No empty line between object properties",node:h})}}};return{ObjectExpression:C=>I(C,!1),ObjectPattern:C=>I(C,!0)}},meta:{docs:{description:"Disallow empty lines in objects"},fixable:"whitespace",schema:[],type:"layout"}},Rt={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.minProperties!==void 0?I.minProperties:2,y=i=>{if(!i||["Literal","Identifier","MemberExpression","UnaryExpression"].includes(i.type))return!0;if(i.type==="TemplateLiteral"||i.type==="CallExpression"||i.type==="ArrowFunctionExpression")return i.loc.start.line===i.loc.end.line;if(i.type==="ConditionalExpression")return t.getText(i).replace(/\s*\n\s*/g," ").trim().length<=80;if(i.type==="LogicalExpression")return t.getText(i).replace(/\s*\n\s*/g," ").trim().length<=80;if(i.type==="BinaryExpression")return t.getText(i).replace(/\s*\n\s*/g," ").trim().length<=80;if(i.type==="SpreadElement")return y(i.argument);if(i.type==="ArrayExpression")return i.loc.start.line===i.loc.end.line;if(i.type==="ObjectExpression"){let{properties:r}=i;return r.length===0?!0:r.length>=C?!1:r.every(
|
|
212
|
-
`+
|
|
213
|
-
`+x):
|
|
214
|
-
`+x)},message:"Closing brace should be on its own line for object with complex value",node:n})}return}let
|
|
215
|
-
`+a),message:`Objects with ${C}+ properties should have first property on its own line`,node:h}),n.loc.start.line===f.loc.end.line&&e.report({fix:u=>{let
|
|
216
|
-
`+
|
|
217
|
-
`+
|
|
218
|
-
`+a),message:"Each property should be on its own line",node:x})}}for(let u of r)if(u.type==="SpreadElement"&&u.argument){let
|
|
219
|
-
`){e.report({fix:i=>i.insertTextAfter(y," "),message:"Missing space after colon in object property",node:y});return}if(s.type==="ArrowFunctionExpression"||s.type==="FunctionExpression"){s.loc.start.line>y.loc.end.line&&e.report({fix:i=>i.replaceTextRange([y.range[1],s.range[0]]," "),message:"Arrow function should start on the same line as the colon",node:s});return}if(s.type==="JSXElement"||s.type==="JSXFragment"){let i=t.getTokenAfter(y),r=i&&i.value==="(",
|
|
220
|
-
${
|
|
211
|
+
`+" ".repeat(h.loc.start.column)),message:"No empty line between object properties",node:h})}}};return{ObjectExpression:C=>I(C,!1),ObjectPattern:C=>I(C,!0)}},meta:{docs:{description:"Disallow empty lines in objects"},fixable:"whitespace",schema:[],type:"layout"}},Rt={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.minProperties!==void 0?I.minProperties:2,y=i=>{if(!i||["Literal","Identifier","MemberExpression","UnaryExpression"].includes(i.type))return!0;if(i.type==="TemplateLiteral"||i.type==="CallExpression"||i.type==="ArrowFunctionExpression")return i.loc.start.line===i.loc.end.line;if(i.type==="ConditionalExpression")return t.getText(i).replace(/\s*\n\s*/g," ").trim().length<=80;if(i.type==="LogicalExpression")return t.getText(i).replace(/\s*\n\s*/g," ").trim().length<=80;if(i.type==="BinaryExpression")return t.getText(i).replace(/\s*\n\s*/g," ").trim().length<=80;if(i.type==="SpreadElement")return y(i.argument);if(i.type==="ArrayExpression")return i.loc.start.line===i.loc.end.line;if(i.type==="ObjectExpression"){let{properties:r}=i;return r.length===0?!0:r.length>=C?!1:r.every(c=>c.type==="SpreadElement"?y(c.argument):y(c.value))}return!1},s=i=>{if(!i)return"";if(i.type==="ArrayExpression")return t.getText(i).replace(/\s+/g," ").trim();if(i.type==="ObjectExpression"){let{properties:r}=i;return r.length===0?"{}":`{ ${r.map(o=>{if(o.type==="SpreadElement")return`...${s(o.argument)}`;let n=o.computed?`[${t.getText(o.key)}]`:t.getText(o.key),h=s(o.value);return o.shorthand?n:`${n}: ${h}`}).join(", ")} }`}return t.getText(i).trim()},g=i=>{let{properties:r}=i;if(r.length===0)return;if(i.type==="ObjectPattern"){let u=i.parent;for(;u;){if((u.type==="FunctionDeclaration"||u.type==="FunctionExpression"||u.type==="ArrowFunctionExpression")&&u.params&&u.params.includes(i))return;if(u.type==="Property"&&u.parent&&u.parent.type==="ObjectPattern"){u=u.parent;continue}if(u.type==="FunctionDeclaration"||u.type==="FunctionExpression"||u.type==="ArrowFunctionExpression"){let T=i,x=!1;for(;T&&T!==u;){if(u.params&&u.params.some(b=>b===T||c(b,T))){x=!0;break}T=T.parent}if(x)return}u=u.parent}}function c(u,T){let x=T;for(;x;){if(x===u)return!0;x=x.parent}return!1}let o=t.getFirstToken(i),n=t.getLastToken(i),h=r[0],f=r[r.length-1];if(!o||!n||o.value!=="{"||n.value!=="}")return;if(r.length<C){let u=o.loc.start.line!==n.loc.end.line,T=r.every(x=>x.type==="SpreadElement"?y(x.argument):y(x.value));if(u&&T){let x=r.map(b=>{if(b.type==="SpreadElement")return`...${s(b.argument)}`;let d=b.computed?`[${t.getText(b.key)}]`:t.getText(b.key),E=s(b.value);return b.shorthand?d:`${d}: ${E}`}).join(", ");e.report({fix:b=>b.replaceTextRange([o.range[0],n.range[1]],`{ ${x} }`),message:`Objects with <${C} properties should be single line: { key: value }. Multi-line only for ${C}+ properties`,node:i});return}if(!T&&u){let x=" ".repeat(o.loc.start.column),b=x+" ";o.loc.end.line===h.loc.start.line&&e.report({fix:d=>d.replaceTextRange([o.range[1],h.range[0]],`
|
|
212
|
+
`+b),message:"Property with complex value should be on its own line",node:h}),n.loc.start.line===f.loc.end.line&&e.report({fix:d=>{let E=t.getTokenAfter(f);return E&&E.value===","?d.replaceTextRange([E.range[1],n.range[0]],`
|
|
213
|
+
`+x):d.replaceTextRange([f.range[1],n.range[0]],`,
|
|
214
|
+
`+x)},message:"Closing brace should be on its own line for object with complex value",node:n})}return}let l=" ".repeat(o.loc.start.column),a=l+" ";o.loc.end.line===h.loc.start.line&&e.report({fix:u=>u.replaceTextRange([o.range[1],h.range[0]],`
|
|
215
|
+
`+a),message:`Objects with ${C}+ properties should have first property on its own line`,node:h}),n.loc.start.line===f.loc.end.line&&e.report({fix:u=>{let T=t.getLastToken(f),x=t.getTokenAfter(f);return x&&x.value===","?u.replaceTextRange([x.range[1],n.range[0]],`
|
|
216
|
+
`+l):u.replaceTextRange([T.range[1],n.range[0]],`,
|
|
217
|
+
`+l)},message:`Objects with ${C}+ properties should have closing brace on its own line`,node:n});for(let u=0;u<r.length-1;u+=1){let T=r[u],x=r[u+1];if(T.loc.end.line===x.loc.start.line){let b=t.getTokenAfter(T,d=>d.value===",");e.report({fix:d=>d.replaceTextRange([b.range[1],x.range[0]],`
|
|
218
|
+
`+a),message:"Each property should be on its own line",node:x})}}for(let u of r)if(u.type==="SpreadElement"&&u.argument){let T=u.argument,x=u.loc.start.line!==T.loc.start.line,b=T.type==="LogicalExpression"&&T.loc.start.line!==T.loc.end.line;if(x||b){if(T.type==="LogicalExpression"){if(T.right.type==="ObjectExpression"&&T.right.properties.length===1&&T.right.properties[0].type!=="SpreadElement"||T.right.type==="Identifier"){let E=t.getText(u).replace(/\s*\n\s*/g," ").replace(/\.\.\.\s+/,"...").trim();e.report({fix:A=>A.replaceText(u,E),message:"Spread element with logical expression should be on a single line",node:u})}}else if(x){let d=t.getText(u).replace(/\s*\n\s*/g," ").replace(/\.\.\.\s+/,"...").trim();e.report({fix:E=>E.replaceText(u,d),message:"Spread operator should be on the same line as its argument",node:u})}}}};return{ObjectExpression:g,ObjectPattern:g}},meta:{docs:{description:"Enforce object formatting: collapse to single line when < minProperties (including nested objects/arrays), expand to multiline when >= minProperties"},fixable:"whitespace",schema:[{additionalProperties:!1,properties:{minProperties:{default:2,description:"Minimum properties to enforce multiline formatting (default: 2)",minimum:1,type:"integer"}},type:"object"}],type:"layout"}},Pt={create(e){let t=e.sourceCode||e.getSourceCode();return{Property(I){let{value:C}=I;if(C.type!=="ObjectExpression")return;let y=t.getTokenBefore(C,g=>g.value===":");if(!y)return;let s=t.getFirstToken(C);!s||s.value!=="{"||y.loc.end.line!==s.loc.start.line&&e.report({fix:g=>g.replaceTextRange([y.range[1],s.range[0]]," "),message:"Opening brace should be on the same line as colon for object property values",node:s})}}},meta:{docs:{description:"Enforce opening brace on same line as colon for object property values"},fixable:"code",schema:[],type:"layout"}},Ft={create(e){let t=e.sourceCode||e.getSourceCode();return{Property:C=>{if(C.shorthand||C.computed)return;let y=t.getTokenAfter(C.key,i=>i.value===":");if(!y)return;let s=C.value,g=t.text.slice(y.range[1],y.range[1]+1);if(g!==" "&&g!==`
|
|
219
|
+
`){e.report({fix:i=>i.insertTextAfter(y," "),message:"Missing space after colon in object property",node:y});return}if(s.type==="ArrowFunctionExpression"||s.type==="FunctionExpression"){s.loc.start.line>y.loc.end.line&&e.report({fix:i=>i.replaceTextRange([y.range[1],s.range[0]]," "),message:"Arrow function should start on the same line as the colon",node:s});return}if(s.type==="JSXElement"||s.type==="JSXFragment"){let i=t.getTokenAfter(y),r=i&&i.value==="(",c=f=>{if(f.type==="JSXFragment"||f.openingElement.attributes.length>0)return!1;let a=(f.children||[]).filter(u=>u.type==="JSXText"?u.value.trim().length>0:!0);return a.length===0||a.length===1&&a[0].type==="JSXText"},o=f=>{let l=f.openingElement.name.name,u=(f.children||[]).filter(T=>T.type==="JSXText").map(T=>T.value.trim()).join("").trim();return u?`<${l}>${u}</${l}>`:`<${l} />`};if(c(s)){let f=o(s);if(!(t.getText(s)===f&&!r&&y.loc.end.line===s.loc.start.line)){let u=t.getTokenAfter(s);if(r){let d=t.getTokenAfter(s);u=t.getTokenAfter(d)}let T=u&&u.value===",",x=r?t.getTokenAfter(s):null,b=T?u.range[1]:x?x.range[1]:s.range[1];e.report({fix:d=>d.replaceTextRange([y.range[1],b],` ${f}${T?",":""}`),message:"Simple JSX should be inline with property",node:s})}return}if(s.loc.start.line!==s.loc.end.line&&!r){let f=t.getText(s),l=" ".repeat(y.loc.start.column),a=t.getTokenAfter(s),u=a&&a.value===",",T=u?a.range[1]:s.range[1],x=u?",":"";e.report({fix:b=>b.replaceTextRange([y.range[1],T],` (
|
|
220
|
+
${l} ${f.split(`
|
|
221
221
|
`).join(`
|
|
222
|
-
`+
|
|
223
|
-
${
|
|
222
|
+
`+l+" ")}
|
|
223
|
+
${l})${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"]),c=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},l=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,T=k=>{let $=u(k);return $&&/^use[A-Z]/.test($)},x=k=>k&&(k.type==="ArrowFunctionExpression"||k.type==="FunctionExpression"),b=k=>{if(k.type==="VariableDeclaration"){let $=k.declarations[0];if($&&$.init&&x($.init))return $.init.type!=="CallExpression"}return k.type==="FunctionDeclaration"},d=(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(T(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 m=u(p.init);if(m){if(C.has(m))return t.STATE;if(y.has(m))return t.REF;if(s.has(m))return t.REDUCER;if(c.has(m))return t.SELECTOR_DISPATCH;if(o.has(m))return t.ROUTER_HOOK;if(n.has(m))return t.CONTEXT_HOOK;if(i.has(m))return t.MEMO;if(r.has(m))return t.CALLBACK;if(T(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 m=p.init;for(;m.type==="MemberExpression";)m=m.object;if(m.type==="Identifier"&&$.has(m.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 m=p.init.callee;if(m&&m.type==="Identifier"&&!T(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 m=v.body;if(m.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=m.filter(L);if(F.length<2)return;let M=new Map,j=new Map;for(let B=0;B<m.length;B++){let O=m[B],X=R(O);for(let Z of X)j.set(Z,B)}for(let B=0;B<m.length;B++){let O=m[B],X=R(O),Z=H(O),Q=L(O)?d(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<m.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=d(B,w);O!==t.UNKNOWN&&(O<q&&!D&&(D=!0,_=B,Y=O,ne=q),q=O)}for(let B=0;B<m.length;B++){let O=N.get(B)||new Set;for(let X of O)if(X>B){z=!0,J=m[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<m.length;K++){let re=M.get(K),ee=re.category;if(ee===t.UNKNOWN){for(let oe=K+1;oe<m.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[m[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+=`
|
|
224
224
|
`);let ce=p.getText(ee.statement);Z+=X+ce.trim()+`
|
|
225
|
-
`,ae!==null&&(Q=ae)}let he=
|
|
225
|
+
`,ae!==null&&(Q=ae)}let he=m[0],xe=m[m.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 m=k.body;if(m.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(`
|
|
226
226
|
`)?L.range[1]+1:W.startsWith(`\r
|
|
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 _=
|
|
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 _=m.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};
|
|
228
228
|
|
|
229
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],`
|
|
230
230
|
|
|
231
|
-
`+Y+q+" "+z+";")),D};e.report({data:{name:P,type:$?"hook":"component"},fix:j,message:'Constant "{{name}}" should be declared inside the {{type}} as derived state, not at module level',node:R.id})}}},S=k=>{if(
|
|
231
|
+
`+Y+q+" "+z+";")),D};e.report({data:{name:P,type:$?"hook":"component"},fix:j,message:'Constant "{{name}}" should be declared inside the {{type}} as derived state, not at module level',node:R.id})}}},S=k=>{if(l(k)){E(k,!1),A(k,!1);return}a(k)&&(E(k,!0),A(k,!0))};return{ArrowFunctionExpression:S,FunctionDeclaration:S,FunctionExpression:S}},meta:{docs:{description:"Enforce consistent ordering of code blocks in React components and custom hooks"},fixable:"code",schema:[],type:"suggestion"}};var jt={create(e){let t=e.sourceCode||e.getSourceCode();return{VariableDeclaration:C=>{let y=t.getFirstToken(C);y&&C.declarations.forEach(s=>{let{id:g,init:i}=s;if(C.declarations[0]===s){if(g.type==="Identifier"&&y.loc.end.line!==g.loc.start.line){e.report({fix:o=>o.replaceTextRange([y.range[1],g.range[0]]," "),message:"Variable name should be on the same line as declaration keyword",node:g});return}if(g.type==="ObjectPattern"||g.type==="ArrayPattern"){let o=t.getFirstToken(g);if(y.loc.end.line!==o.loc.start.line){e.report({fix:n=>n.replaceTextRange([y.range[1],o.range[0]]," "),message:"Destructuring pattern should be on the same line as declaration keyword",node:o});return}}}if(!i)return;let c=t.getTokenBefore(i,o=>o.value==="=");if(c){if(g.loc.end.line!==c.loc.start.line){e.report({fix:o=>o.replaceTextRange([g.range[1],c.range[0]]," "),message:"Assignment operator should be on the same line as variable",node:c});return}i.loc.start.line>c.loc.end.line&&e.report({fix:o=>o.replaceTextRange([c.range[1],i.range[0]]," "),message:"Value should be on the same line as the assignment operator",node:i})}})}}},meta:{docs:{description:"Enforce assignment value on same line as equals sign"},fixable:"whitespace",schema:[],type:"layout"}},Ot={create(e){let t=e.sourceCode||e.getSourceCode(),I=(C,y,s)=>{let g=t.getTokenBefore(s),i=t.getTokenAfter(s);if(!g||g.value!=="["||!i||i.value!=="]")return;let r=t.getLastToken(y);if(r){let n=t.text.slice(r.range[1],g.range[0]);/\s/.test(n)&&e.report({fix:h=>h.replaceTextRange([r.range[1],g.range[0]],""),message:"No space before opening bracket in member expression",node:g})}let c=t.text.slice(g.range[1],s.range[0]);(c.includes(" ")||c.includes(`
|
|
232
232
|
`))&&e.report({fix:n=>n.replaceTextRange([g.range[1],s.range[0]],""),message:"No space after opening bracket in member expression",node:g});let o=t.text.slice(s.range[1],i.range[0]);(o.includes(" ")||o.includes(`
|
|
233
|
-
`))&&e.report({fix:n=>n.replaceTextRange([s.range[1],i.range[0]],""),message:"No space before closing bracket in member expression",node:i})};return{MemberExpression(C){C.computed&&I(C,C.object,C.property)},TSIndexedAccessType(C){I(C,C.objectType,C.indexType)}}},meta:{docs:{description:"Enforce no spaces inside brackets for member expressions"},fixable:"code",schema:[],type:"layout"}};var Mt={create(e){let t=e.options[0]||{},I=["accept","acceptCharset","accessKey","action","align","allow","allowFullScreen","alt","as","async","autoCapitalize","autoComplete","autoCorrect","autoFocus","autoPlay","capture","cellPadding","cellSpacing","charSet","className","clipPath","clipRule","colorInterpolation","colorInterpolationFilters","classNames","colSpan","contentEditable","controls","controlsList","coords","crossOrigin","d","data","data-*","dateTime","decoding","default","defer","dir","disabled","download","draggable","encType","enterKeyHint","fill","fillOpacity","fillRule","filter","filterUnits","floodColor","floodOpacity","for","form","formAction","formEncType","formMethod","formNoValidate","formTarget","frameBorder","headers","height","hidden","high","href","hrefLang","htmlFor","httpEquiv","gradientTransform","gradientUnits","icon","id","in","in2","imagesizes","imagesrcset","inputMode","integrity","is","itemID","itemProp","itemRef","itemScope","itemType","key","keyParams","keyType","kind","lang","list","loading","loop","low","marginHeight","marginWidth","markerEnd","markerMid","markerStart","markerUnits","mask","max","mode","maxLength","media","mediaGroup","method","min","minLength","multiple","muted","name","noModule","noValidate","nonce","open","optimum","pattern","patternContentUnits","patternTransform","patternUnits","ping","preserveAspectRatio","playsInline","poster","preload","profile","radioGroup","readOnly","referrerPolicy","rel","repeatCount","repeatDur","required","result","reversed","role","rowSpan","rows","sandbox","scope","scoped","scrolling","seamless","selected","shape","sizes","slot","span","spellCheck","src","srcDoc","srcLang","srcSet","start","step","spreadMethod","stdDeviation","stopColor","stopOpacity","stroke","strokeDasharray","strokeDashoffset","strokeLinecap","strokeLinejoin","strokeMiterlimit","strokeOpacity","strokeWidth","style","summary","tabIndex","target","testId","textAnchor","textDecoration","transform","translate","vectorEffect","useMap","value","viewBox","width","wmode","wrap","x","x1","x2","xmlns","y","y1","y2","baseFrequency","numOctaves","seed","stitchTiles","operator","k1","k2","k3","k4","surfaceScale","diffuseConstant","specularConstant","specularExponent","kernelMatrix","order","targetX","targetY","edgeMode","kernelUnitLength","bias","divisor","preserveAlpha","radius","azimuth","elevation","limitingConeAngle","pointsAtX","pointsAtY","pointsAtZ","cx","cy","r","rx","ry","points","pathLength","offset","dx","dy","rotate","lengthAdjust","textLength"],C=t.ignoreAttributes||[...I,...t.extraIgnoreAttributes||[]],y=[/^\s*$/,/^.$/,/^-?\d+(\.\d+)?(px|em|rem|%|vh|vw|vmin|vmax|ch|ex|cm|mm|in|pt|pc|deg|rad|turn|s|ms|fr)?$/,/^-?\d+(\.\d+)?e[+-]?\d+$/i,/^#[0-9a-fA-F]{3,8}$/,/^(rgb|rgba|hsl|hsla)\(.+\)$/,/^url\(#?.+\)$/,/^(round|butt|square|miter|bevel|none|normal|evenodd|nonzero|sRGB|linearRGB|userSpaceOnUse|objectBoundingBox|pad|reflect|repeat|auto|inherit|currentColor|meet|slice|xMinYMin|xMidYMin|xMaxYMin|xMinYMid|xMidYMid|xMaxYMid|xMinYMax|xMidYMax|xMaxYMax|stitch|noStitch|duplicate|wrap|arithmetic|atop|in|out|over|xor|dilate|erode|matrix|saturate|hueRotate|luminanceToAlpha|discrete|linear|gamma|table|identity|SourceGraphic|SourceAlpha|BackgroundImage|BackgroundAlpha|FillPaint|StrokePaint)$/,/^[a-zA-Z]+\d*[_a-zA-Z0-9]*(_[a-zA-Z0-9]+)+$/,/^(white|black|red|green|blue|yellow|orange|purple|pink|brown|gray|grey|cyan|magenta|transparent)$/i,/^(auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|vertical-text|alias|copy|move|no-drop|not-allowed|grab|grabbing|all-scroll|col-resize|row-resize|n-resize|e-resize|s-resize|w-resize|ne-resize|nw-resize|se-resize|sw-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|zoom-in|zoom-out)$/,/^(block|inline|inline-block|flex|inline-flex|grid|inline-grid|flow-root|contents|table|table-row|table-cell|list-item|none|visible|hidden|collapse)$/,/^(static|relative|absolute|fixed|sticky)$/,/^(visible|hidden|scroll|auto|clip)$/,/^(https?:\/\/|\/\/|\/|\.\/|\.\.\/)/,/^data:/,/^mailto:/,/^tel:/,/^\.[a-zA-Z0-9]+$/,/^[a-z]+\/[a-z0-9.+-]+$/,/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/,/^\d{1,2}:\d{2}(:\d{2})?(\s?(AM|PM|am|pm))?$/,/^[a-z]+[A-Z][a-zA-Z0-9]*$/,/^[a-z][a-z0-9]*_[a-z0-9_]*$/,/^[A-Z][A-Z0-9]*_[A-Z0-9_]+$/,/^(true|false|null|undefined|NaN|Infinity)$/,/^application\//,/^[a-z][a-zA-Z0-9_]*=/,/^[a-z]+-[a-z]+(-[a-z]+)*$/,/^-?[a-z]+-\d+(\.\d+)?(\/\d+)?$/,/^-?[a-z]+-[a-z]+-\d+(\.\d+)?(\/\d+)?$/,/^[a-z]+:[a-z][-a-z0-9/]*$/,/^[a-z]+-[a-z]+(-[a-z]+)*\/\d+$/,/^-?[a-z]+(-[a-z]+)*-\[.+\]$/,/^-[a-z]+-[a-z]+-\d+\/\d+$/,/^[a-z]+-(full|auto|screen|none|inherit|initial|px|fit|min|max)$/,/^(sm|md|lg|xl|2xl|hover|focus|active|disabled|first|last|odd|even|group-hover|dark|motion-safe|motion-reduce):[a-z][-a-z0-9/[\]]*$/,/^[\d,._]+$/,/^\d+\.\d+\.\d+/,/^[,;:|•·\-–—/\\]+$/,/^&[a-z]+;$/,/^[.!?,;:'"()\[\]{}]+$/,/^(rotate|translate|translateX|translateY|translateZ|translate3d|scale|scaleX|scaleY|scaleZ|scale3d|skew|skewX|skewY|matrix|matrix3d|perspective)\(.+\)$/,/^(rotate|translate|translateX|translateY|scale|scaleX|scaleY|skew|skewX|skewY|matrix)\([^)]+\)(\s+(rotate|translate|translateX|translateY|scale|scaleX|scaleY|skew|skewX|skewY|matrix)\([^)]+\))+$/,/^(linear-gradient|radial-gradient|conic-gradient|repeating-linear-gradient|repeating-radial-gradient)\(.+\)$/,/^[a-zA-Z][\w-]*\s+[\d.]+m?s\s+[\w-]+(\s+[\w-]+)*$/,/^(\d+%|center|top|bottom|left|right)(\s+(\d+%|center|top|bottom|left|right))?$/,/^calc\(.+\)$/,/^var\(.+\)$/,/^clamp\(.+\)$/,/^(min|max)\(.+\)$/],s=(t.ignorePatterns||[]).map(p=>typeof p=="string"?new RegExp(p):p),g=[...y,...s],i=/^-?[a-z]+(-[a-z0-9]+)*(\/\d+)?$|^-?[a-z]+(-[a-z0-9]+)*-\[.+\]$|^[a-z]+:[a-z][-a-z0-9/[\]]*$/,r=new Set(["block","contents","flex","flow","grid","hidden","inline","table","absolute","fixed","relative","static","sticky","collapse","invisible","visible","antialiased","capitalize","italic","lowercase","ordinal","overline","subpixel","truncate","underline","uppercase","container","isolate","grow","shrink","border","rounded","group","peer","resize","snap","touch","select","pointer","transition","animate","filter","backdrop","transform","appearance","cursor","outline","ring","shadow","opacity","blur","invert","sepia","grayscale","hue","saturate","brightness","contrast"]),l=p=>{let d=p.trim().split(/\s+/).filter(Boolean);return d.length===0||!d.some(L=>L.includes("-")||L.includes(":")||L.includes("/")||L.includes("["))?!1:d.every(L=>L.includes("${")||r.has(L)?!0:/^-?[a-z]+(-[a-z0-9.]+)+$/.test(L)||/^-?[a-z]+(-[a-z0-9.]+)*\/\d+$/.test(L)||/^[a-z][-a-z0-9]*(\[[-\w=]+\])?:[a-z][-a-z0-9./[\]]*$/.test(L)||/^\[.+\]:[a-z][-a-z0-9./[\]]*$/.test(L)||/^-?[a-z]+(-[a-z]+)*-?\[.+\]$/.test(L))},o=new Set(["button","checkbox","color","date","datetime-local","email","file","hidden","image","month","number","password","radio","range","reset","search","submit","tel","text","time","url","week"]),n=p=>o.has(p.toLowerCase()),h=p=>{let d=p.parent;for(;d;){if(d.type==="Property"&&d.parent&&d.parent.type==="ObjectExpression"){let w=d.parent;if(w.parent&&w.parent.type==="JSXExpressionContainer"){let L=w.parent;if(L.parent&&L.parent.type==="JSXAttribute"&&(L.parent.name&&L.parent.name.name)==="style")return!0}}d=d.parent}return!1},f=[/gradient/i,/transform/i,/animation/i,/transition/i,/color/i,/background/i,/border/i,/shadow/i,/filter/i,/clip/i,/mask/i,/font/i,/^style/i,/Style$/i,/css/i],c=p=>!!(/^(linear-gradient|radial-gradient|conic-gradient|repeating-linear-gradient|repeating-radial-gradient|rotate|translate|translateX|translateY|translateZ|translate3d|scale|scaleX|scaleY|scaleZ|scale3d|skew|skewX|skewY|matrix|matrix3d|perspective|calc|var|clamp|min|max|cubic-bezier|steps|url)\(/i.test(p)||/^(#[0-9a-fA-F]{3,8}|rgb|rgba|hsl|hsla)\(/i.test(p)||/^\d+(\.\d+)?(px|em|rem|%|vh|vw|vmin|vmax|deg|rad|turn|s|ms|fr)\s*/.test(p)),a=p=>{let d=p.parent;for(;d;){if(d.type==="VariableDeclarator"&&d.id&&d.id.name){let w=d.id.name;if(f.some(L=>L.test(w)))return!0}if(d.type==="Property"&&d.key){let w=d.key.name||d.key.value&&String(d.key.value);if(w&&f.some(L=>L.test(w)))return!0}d=d.parent}return!1},u=p=>{let d=p.parent,w=0;for(;d;){if(w++,d.type==="ExportNamedDeclaration"&&w<=3){let L=d.declaration;if(L&&L.type==="VariableDeclaration"){let R=L.declarations[0];if(R&&R.id&&R.id.name){let P=R.id.name;return!(/^[A-Z][A-Z0-9_]*$/.test(P)||/^(constants?|strings?|messages?|labels?|texts?|data)$/i.test(P))}}}if(d.type==="FunctionDeclaration"||d.type==="FunctionExpression"||d.type==="ArrowFunctionExpression")return!1;d=d.parent}return!1},b=(p,d="")=>{let w=p.length>30?`${p.substring(0,30)}...`:p,L=d?` in ${d}`:"",R=!/\s/.test(p)&&p.length<=30,P=/^[a-z_]+$/.test(p),H=d.includes("attribute");return R&&P?H?`Hardcoded "${w}"${L} should be imported from @/enums (preferred) or @/data to prevent typos (e.g., import { InputTypeEnum } from "@/enums")`:`Hardcoded "${w}"${L} should be imported from @/enums (preferred) or @/data (e.g., import { StatusEnum } from "@/enums")`:`Hardcoded UI string "${w}"${L} should be imported from @/strings or @/constants (e.g., import { strings } from "@/strings")`},x=new Set(["cn","cva","clsx","twMerge","classnames","cx","tv","twJoin"]),T=p=>{let d=p.parent,w=!1;for(;d;){if(d.type==="CallExpression"&&d.callee){let L=d.callee.name||d.callee.property&&d.callee.property.name;if(L&&x.has(L))return!0;w=!0}if(w&&d.type==="JSXAttribute"&&d.name){let L=d.name.name;if(L==="className"||L==="class")return!0}d=d.parent}return!1},m=(p,d)=>d&&T(d)||l(p)?!0:g.some(w=>w.test(p)),E=()=>{let d=(e.filename||e.getFilename()).replace(/\\/g,"/").toLowerCase();return/\/(constants|strings|@constants|@strings|data|@data|enums|@enums)(\/|\.)/i.test(d)||/\/data\/(constants|strings)/i.test(d)},A=new Set,S=p=>{let d=p.source.value;if(typeof d!="string")return;/@?\/?(@?constants|@?strings|@?data|@?enums|data\/constants|data\/strings)/i.test(d)&&p.specifiers.forEach(L=>{L.local&&L.local.name&&A.add(L.local.name)})},k=p=>p.type==="Identifier"?A.has(p.name):p.type==="MemberExpression"&&p.object.type==="Identifier"?A.has(p.object.name):!1,$=p=>{let d=p.parent;for(;d;){if(d.type==="FunctionDeclaration"||d.type==="FunctionExpression"||d.type==="ArrowFunctionExpression"){let w=null;return d.id&&d.id.name?w=d.id.name:d.parent&&d.parent.type==="VariableDeclarator"&&d.parent.id&&d.parent.id.name&&(w=d.parent.id.name),w&&(/^[A-Z]/.test(w)||/^use[A-Z]/.test(w)||/Handler$|Helper$|Util$|Utils$/i.test(w)),!0}if(d.type==="JSXElement"||d.type==="JSXFragment")return!0;d=d.parent}return!1},v=p=>{let d=p.parent,w=0;for(;d;){if(w++,d.type==="VariableDeclarator"){let L=d.id&&d.id.name;if(L&&(/^[A-Z][A-Z0-9_]*$/.test(L)||/^(constants?|strings?|messages?|labels?|texts?|data)$/i.test(L)))return!0}if(d.type==="ExportNamedDeclaration"&&w<=3){let L=d.declaration;if(L&&L.type==="VariableDeclaration"){let R=L.declarations[0];if(R&&R.init){let P=R.init.type;if(P==="Literal"||P==="ObjectExpression"||P==="ArrayExpression")return!0}}}if(d.type==="FunctionDeclaration"||d.type==="FunctionExpression"||d.type==="ArrowFunctionExpression")return!1;d=d.parent}return!1};return E()?{}:{ImportDeclaration:S,JSXText(p){let d=p.value.trim();d&&(m(d,p)||/[a-zA-Z]/.test(d)&&e.report({message:b(d,"JSX"),node:p}))},JSXExpressionContainer(p){let{expression:d}=p;if(!k(d)){if(p.parent&&p.parent.type==="JSXAttribute"){let w=p.parent.name.name||p.parent.name.namespace&&`${p.parent.name.namespace.name}:${p.parent.name.name.name}`;if(C.includes(w)||w&&(w.startsWith("data-")||w.startsWith("aria-")))return}if(d.type==="Literal"&&typeof d.value=="string"){let w=d.value;if(m(w,d)||!/[a-zA-Z]/.test(w))return;e.report({message:b(w,"JSX expression"),node:d})}d.type==="TemplateLiteral"&&d.quasis.forEach(w=>{let L=w.value.cooked||w.value.raw;m(L,d)||/[a-zA-Z]{2,}/.test(L)&&(/^[/.]|https?:\/\//.test(L)||e.report({message:b(L,"template literal"),node:w}))})}},JSXAttribute(p){if(!p.value)return;let d=p.name.name||p.name.namespace&&`${p.name.namespace.name}:${p.name.name.name}`;if(!C.includes(d)&&!(d&&d.startsWith("data-"))&&!(d&&d.startsWith("aria-"))){if(p.value.type==="Literal"&&typeof p.value.value=="string"){let w=p.value.value;if(m(w,p.value)||!/[a-zA-Z]/.test(w))return;e.report({message:b(w,`attribute "${d}"`),node:p.value})}if(p.value.type==="JSXExpressionContainer"){let{expression:w}=p.value;if(k(w))return;if(w.type==="Literal"&&typeof w.value=="string"){let L=w.value;if(m(L,w)||!/[a-zA-Z]/.test(L))return;e.report({message:b(L,`attribute "${d}"`),node:w})}}}},Literal(p){if(typeof p.value!="string")return;let d=p.value;if(!h(p)){if(u(p)){if(!/[a-zA-Z]/.test(d))return;e.report({message:b(d,"exported constant"),node:p});return}m(d,p)||$(p)&&(v(p)||p.parent.type==="JSXAttribute"||p.parent.type==="JSXExpressionContainer"||p.parent.type==="ImportDeclaration"||p.parent.type==="ExportNamedDeclaration"||p.parent.type==="ExportAllDeclaration"||p.parent.type==="Property"&&p.parent.key===p||/[a-zA-Z]/.test(d)&&e.report({message:b(d),node:p}))}},TemplateLiteral(p){if(p.parent.type!=="JSXExpressionContainer"&&!h(p)){if(a(p)){let d=p.quasis.map(w=>w.value.cooked||w.value.raw).join("");if(c(d))return}$(p)&&(v(p)||p.quasis.forEach(d=>{let w=d.value.cooked||d.value.raw;m(w,p)||/[a-zA-Z]{3,}/.test(w)&&(/^[/.]|^https?:\/\/|^[?&]/.test(w)||p.expressions.length>p.quasis.length||e.report({message:b(w,"template literal"),node:d}))}))}}}},meta:{docs:{description:"Enforce importing strings from constants/strings modules instead of hardcoding them"},schema:[{additionalProperties:!1,properties:{extraIgnoreAttributes:{description:"Additional JSX attributes to ignore (extends defaults)",items:{type:"string"},type:"array"},ignoreAttributes:{description:"JSX attributes to ignore (replaces defaults)",items:{type:"string"},type:"array"},ignorePatterns:{description:"Regex patterns for strings to ignore",items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}};var Nt={create(e){let t=e.sourceCode||e.getSourceCode(),I=new Map,C=l=>l.endsWith("Type")?l.slice(0,-4)+"Enum":null,y=l=>l.toUpperCase().replace(/-/g,"_"),s=l=>{if(!l)return null;let o=l.typeAnnotation;if(!o)return null;if(o.type==="TSTypeReference"&&o.typeName?.type==="Identifier"){let n=o.typeName.name;if(n.endsWith("Type"))return{enumName:C(n),typeName:n}}return null},g=l=>{l.forEach(o=>{if(o.type==="TSPropertySignature"&&o.key?.type==="Identifier"){let n=o.key.name,h=s(o.typeAnnotation);h&&I.set(n,h)}})},i=l=>{l.forEach(o=>{if(o.type==="ObjectPattern"&&o.typeAnnotation){let n=o.typeAnnotation.typeAnnotation;n&&n.type==="TSTypeLiteral"&&g(n.members),n&&n.type==="TSIntersectionType"&&n.types.forEach(h=>{h.type==="TSTypeLiteral"&&g(h.members)})}if(o.type==="Identifier"&&o.typeAnnotation){let n=s(o);n&&I.set(o.name,n)}})},r=(l,o)=>{let h=t.getScope?t.getScope(o):e.getScope();for(;h;){if(h.variables.some(f=>f.name===l))return!0;h=h.upper}return!1};return{"ArrowFunctionExpression, FunctionDeclaration, FunctionExpression"(l){i(l.params)},AssignmentPattern(l){if(l.left.type!=="Identifier")return;let o=l.left.name,n=I.get(o);if(n&&l.right.type==="Literal"&&typeof l.right.value=="string"){let h=l.right.value,f=y(h),c=`${n.enumName}.${f}`,a=r(n.enumName,l);e.report({fix:a?u=>u.replaceText(l.right,c):void 0,message:`Use "${c}" instead of string literal "${h}"`,node:l.right})}},BinaryExpression(l){if(l.operator!=="==="&&l.operator!=="!==")return;let o=null,n=null;if(l.left.type==="Identifier"&&l.right.type==="Literal"?(o=l.left,n=l.right):l.right.type==="Identifier"&&l.left.type==="Literal"&&(o=l.right,n=l.left),!o||!n||typeof n.value!="string")return;let h=I.get(o.name);if(!h)return;let f=n.value,c=y(f),a=`${h.enumName}.${c}`,u=r(h.enumName,l);e.report({fix:u?b=>b.replaceText(n,a):void 0,message:`Use "${a}" instead of string literal "${f}"`,node:n})},"ArrowFunctionExpression:exit"(){I.clear()},"FunctionDeclaration:exit"(){I.clear()},"FunctionExpression:exit"(){I.clear()}}},meta:{docs:{description:"Enforce using enum values instead of string literals for typed variables"},fixable:"code",schema:[],type:"suggestion"}},Dt={create(e){let t=e.options[0]||{},I=["is","has","with","without"],C=t.booleanPrefixes||[...I,...t.extendBooleanPrefixes||[]],y=t.allowPastVerbBoolean||!1,s=t.allowContinuousVerbBoolean||!1,g=t.callbackPrefix||"on",i=t.allowActionSuffix||!1,r=new RegExp(`^(${C.join("|")})[A-Z]`),l=new RegExp(`^${g}[A-Z]`),o=/^[a-z]+ed$/,n=/^[a-z]+ing$/,h=["children","content","data","error","errors","items","permission","permissions","value","values"],f=v=>{let p=v.toLowerCase();return(h.some(w=>p.includes(w))?"has":"is")+v[0].toUpperCase()+v.slice(1)},c=v=>{if(v.startsWith("handle")&&v.length>6){let p=v.slice(6);return g+p[0].toUpperCase()+p.slice(1)}if(v.endsWith("Handler")&&v.length>7){let p=v.slice(0,-7);return g+p[0].toUpperCase()+p.slice(1)}return g+v[0].toUpperCase()+v.slice(1)},a=v=>{if(!v)return!1;let p=v.typeAnnotation;return p?p.type==="TSBooleanKeyword"?!0:p.type==="TSUnionType"?p.types.some(d=>d.type==="TSBooleanKeyword"):!1:!1},u=["MouseEventHandler","ChangeEventHandler","FormEventHandler","KeyboardEventHandler","FocusEventHandler","TouchEventHandler","PointerEventHandler","DragEventHandler","WheelEventHandler","AnimationEventHandler","TransitionEventHandler","ClipboardEventHandler","CompositionEventHandler","UIEventHandler","ScrollEventHandler","EventHandler"],b=v=>{if(!v)return!1;let p=v.typeAnnotation;if(!p)return!1;if(p.type==="TSFunctionType")return!0;if(p.type==="TSTypeReference"){let d=p.typeName?.name;if(d==="Function"||d==="VoidFunction"||u.includes(d))return!0}return p.type==="TSUnionType"?p.types.some(d=>d.type==="TSFunctionType"||d.type==="TSTypeReference"&&(d.typeName?.name==="Function"||d.typeName?.name==="VoidFunction"||u.includes(d.typeName?.name))):!1},x=v=>{if(!v)return!1;let p=v.typeAnnotation;return p?p.type==="TSTypeLiteral":!1},T=v=>!!(r.test(v)||y&&o.test(v)||s&&n.test(v)),m=v=>!!(l.test(v)||i&&v.endsWith("Action")&&v.length>6),E=v=>{let p=v;for(;p;){if(p.type==="ArrowFunctionExpression"||p.type==="FunctionExpression"||p.type==="FunctionDeclaration")return p;p=p.parent}return null},A=(v,p)=>{if(!v||!v.params||v.params.length===0)return null;let d=v.params[0];if(d.type!=="ObjectPattern")return null;for(let w of d.properties)if(w.type==="Property"&&w.key&&w.key.type==="Identifier"&&w.key.name===p)return w;return null},S=(v,p,d,w)=>{let L=[v.replaceText(p.key,w)],R=E(p);if(!R)return L;let P=A(R,d);if(!P)return L;let H=P.value||P.key;if(!H||H.type!=="Identifier")return L;P.shorthand!==!1&&P.key===P.value?L.push(v.replaceText(P,`${d}: ${w}`)):L.push(v.replaceText(H,w));let M=e.sourceCode?e.sourceCode.getScope(R):e.getScope(),j=(D,z)=>{let q=D.variables.find(_=>_.name===z);return q||(D.upper?j(D.upper,z):null)},N=j(M,d);if(N){let D=new Set;N.references.forEach(z=>{if(z.identifier===H)return;let q=`${z.identifier.range[0]}-${z.identifier.range[1]}`;D.has(q)||(D.add(q),L.push(v.replaceText(z.identifier,w)))})}return L},k=v=>{if(v.type!=="TSPropertySignature"||!v.key||v.key.type!=="Identifier")return;let p=v.key.name;if(!p.startsWith("_")){if(x(v.typeAnnotation)){let d=v.typeAnnotation.typeAnnotation;d&&d.members&&d.members.forEach(k);return}if(a(v.typeAnnotation)){if(!T(p)){let d=f(p);e.report({fix:w=>S(w,v,p,d),message:`Boolean prop "${p}" should start with a valid prefix (${C.join(", ")}). Use "${d}" instead.`,node:v.key})}return}if(b(v.typeAnnotation)&&!m(p)){let d=c(p);e.report({fix:w=>S(w,v,p,d),message:`Callback prop "${p}" should start with "${g}" prefix. Use "${d}" instead.`,node:v.key})}}},$=v=>{v.members&&v.members.forEach(k)};return{TSInterfaceDeclaration(v){!v.body||!v.body.body||v.body.body.forEach(k)},TSTypeAliasDeclaration(v){v.typeAnnotation?.type==="TSTypeLiteral"&&$(v.typeAnnotation)},TSTypeLiteral(v){v.parent?.type!=="TSTypeAliasDeclaration"&&$(v)}}},meta:{docs:{description:"Enforce naming conventions: boolean props must start with is/has/with/without, callback props must start with on"},fixable:"code",schema:[{additionalProperties:!1,properties:{allowActionSuffix:{default:!1,description:"Allow 'xxxAction' pattern for callback props (e.g., submitAction, copyAction)",type:"boolean"},allowContinuousVerbBoolean:{default:!1,description:"Allow continuous verb boolean props without prefix (e.g., loading, saving, fetching, closing)",type:"boolean"},allowPastVerbBoolean:{default:!1,description:"Allow past verb boolean props without prefix (e.g., disabled, selected, checked, opened)",type:"boolean"},booleanPrefixes:{description:"Replace default boolean prefixes entirely. If not provided, defaults are used with extendBooleanPrefixes",items:{type:"string"},type:"array"},callbackPrefix:{default:"on",description:"Required prefix for callback props",type:"string"},extendBooleanPrefixes:{default:[],description:"Add additional prefixes to the defaults (is, has, with, without)",items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}},Jt={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxUnionMembers??2,y=I.maxLength??50,s=new Set(["any","bigint","boolean","never","null","number","object","string","symbol","undefined","unknown","void"]),g=new Set(["Array","BigInt","Boolean","Date","Error","Function","Map","Number","Object","Promise","ReadonlyArray","RegExp","Set","String","Symbol","WeakMap","WeakSet"]),i=n=>{if(!n)return!1;if(n.type==="TSStringKeyword"||n.type==="TSNumberKeyword"||n.type==="TSBooleanKeyword"||n.type==="TSNullKeyword"||n.type==="TSUndefinedKeyword"||n.type==="TSVoidKeyword"||n.type==="TSAnyKeyword"||n.type==="TSUnknownKeyword"||n.type==="TSNeverKeyword"||n.type==="TSObjectKeyword"||n.type==="TSSymbolKeyword"||n.type==="TSBigIntKeyword")return!0;if(n.type==="TSTypeReference"&&n.typeName){let h=n.typeName.name||n.typeName.type==="Identifier"&&n.typeName.name;if(h&&g.has(h))return!0}return n.type==="TSLiteralType"},r=n=>n.type!=="TSUnionType"?!1:n.types.every(h=>i(h)),l=n=>{if(n.type!=="TSUnionType")return 1;let h=0;for(let f of n.types)h+=l(f);return h},o=(n,h)=>{if(n){if(n.type==="TSUnionType"){if(r(n))return;let f=l(n),c=t.getText(n);(f>=C||c.length>y)&&e.report({message:`Inline union type with ${f} members is too complex. Extract to a named type in a types file.`,node:n});return}if(n.type==="TSIntersectionType"){for(let f of n.types)o(f,h);return}if(n.type==="TSTypeLiteral"){for(let f of n.members)if(f.type==="TSPropertySignature"&&f.typeAnnotation){let c=f.typeAnnotation.typeAnnotation,a=f.key&&f.key.name?f.key.name:"unknown";if(c&&c.type==="TSUnionType"){let u=l(c),b=t.getText(c);(u>=C||b.length>y)&&e.report({message:`Property "${a}" has inline union type with ${u} members. Extract to a named type in a types file.`,node:c})}}}}};return{ArrowFunctionExpression(n){for(let h of n.params)if(h.typeAnnotation&&h.typeAnnotation.typeAnnotation){let f=h.type==="Identifier"?h.name:"param";o(h.typeAnnotation.typeAnnotation,f)}},FunctionDeclaration(n){for(let h of n.params)if(h.typeAnnotation&&h.typeAnnotation.typeAnnotation){let f=h.type==="Identifier"?h.name:"param";o(h.typeAnnotation.typeAnnotation,f)}},FunctionExpression(n){for(let h of n.params)if(h.typeAnnotation&&h.typeAnnotation.typeAnnotation){let f=h.type==="Identifier"?h.name:"param";o(h.typeAnnotation.typeAnnotation,f)}}}},meta:{docs:{description:"Enforce extracting inline union types to named types in type files"},schema:[{additionalProperties:!1,properties:{maxLength:{default:50,description:"Maximum character length for inline union types (default: 50)",minimum:1,type:"integer"},maxUnionMembers:{default:2,description:"Maximum union members to keep inline (default: 2)",minimum:1,type:"integer"}},type:"object"}],type:"suggestion"}},Xt={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.minUnionMembersForMultiline!==void 0?I.minUnionMembersForMultiline:5,y=/^[A-Z][a-zA-Z0-9]*$/,s=/^[a-z][a-zA-Z0-9]*$/,g=l=>/^[A-Z][A-Z0-9_]*$/.test(l)?l.toLowerCase().replace(/_([a-z0-9])/g,(o,n)=>n.toUpperCase()):/_/.test(l)?l.toLowerCase().replace(/_([a-z0-9])/g,(o,n)=>n.toUpperCase()):/^[A-Z]/.test(l)?l[0].toLowerCase()+l.slice(1):l,i=(l,o,n)=>{if(n.length===0)return;let f=t.lines[l.loc.start.line-1].match(/^\s*/)[0],c=f+" ",a=t.getFirstToken(o),u=t.getLastToken(o),b=n[0];b.loc.start.line-a.loc.end.line>1&&e.report({fix:T=>T.replaceTextRange([a.range[1],b.range[0]],`
|
|
234
|
-
`+
|
|
235
|
-
`+f),message:"No empty line before closing brace in type",node:x}),n.length>=2&&u.loc.start.line===x.loc.end.line&&e.report({fix:
|
|
236
|
-
`+f),message:"Closing brace should be on its own line in multiline type literal",node:u}),n.length>1&&
|
|
237
|
-
`+
|
|
238
|
-
`+
|
|
239
|
-
`);return k.replaceTextRange([S.range[1],
|
|
240
|
-
`,
|
|
233
|
+
`))&&e.report({fix:n=>n.replaceTextRange([s.range[1],i.range[0]],""),message:"No space before closing bracket in member expression",node:i})};return{MemberExpression(C){C.computed&&I(C,C.object,C.property)},TSIndexedAccessType(C){I(C,C.objectType,C.indexType)}}},meta:{docs:{description:"Enforce no spaces inside brackets for member expressions"},fixable:"code",schema:[],type:"layout"}};var Mt={create(e){let t=e.options[0]||{},I=["accept","acceptCharset","accessKey","action","align","allow","allowFullScreen","alt","as","async","autoCapitalize","autoComplete","autoCorrect","autoFocus","autoPlay","capture","cellPadding","cellSpacing","charSet","className","clipPath","clipRule","colorInterpolation","colorInterpolationFilters","classNames","colSpan","contentEditable","controls","controlsList","coords","crossOrigin","d","data","data-*","dateTime","decoding","default","defer","dir","disabled","download","draggable","encType","enterKeyHint","fill","fillOpacity","fillRule","filter","filterUnits","floodColor","floodOpacity","for","form","formAction","formEncType","formMethod","formNoValidate","formTarget","frameBorder","headers","height","hidden","high","href","hrefLang","htmlFor","httpEquiv","gradientTransform","gradientUnits","icon","id","in","in2","imagesizes","imagesrcset","inputMode","integrity","is","itemID","itemProp","itemRef","itemScope","itemType","key","keyParams","keyType","kind","lang","list","loading","loop","low","marginHeight","marginWidth","markerEnd","markerMid","markerStart","markerUnits","mask","max","mode","maxLength","media","mediaGroup","method","min","minLength","multiple","muted","name","noModule","noValidate","nonce","open","optimum","pattern","patternContentUnits","patternTransform","patternUnits","ping","preserveAspectRatio","playsInline","poster","preload","profile","radioGroup","readOnly","referrerPolicy","rel","repeatCount","repeatDur","required","result","reversed","role","rowSpan","rows","sandbox","scope","scoped","scrolling","seamless","selected","shape","sizes","slot","span","spellCheck","src","srcDoc","srcLang","srcSet","start","step","spreadMethod","stdDeviation","stopColor","stopOpacity","stroke","strokeDasharray","strokeDashoffset","strokeLinecap","strokeLinejoin","strokeMiterlimit","strokeOpacity","strokeWidth","style","summary","tabIndex","target","testId","textAnchor","textDecoration","transform","translate","vectorEffect","useMap","value","viewBox","width","wmode","wrap","x","x1","x2","xmlns","y","y1","y2","baseFrequency","numOctaves","seed","stitchTiles","operator","k1","k2","k3","k4","surfaceScale","diffuseConstant","specularConstant","specularExponent","kernelMatrix","order","targetX","targetY","edgeMode","kernelUnitLength","bias","divisor","preserveAlpha","radius","azimuth","elevation","limitingConeAngle","pointsAtX","pointsAtY","pointsAtZ","cx","cy","r","rx","ry","points","pathLength","offset","dx","dy","rotate","lengthAdjust","textLength"],C=t.ignoreAttributes||[...I,...t.extraIgnoreAttributes||[]],y=[/^\s*$/,/^.$/,/^-?\d+(\.\d+)?(px|em|rem|%|vh|vw|vmin|vmax|ch|ex|cm|mm|in|pt|pc|deg|rad|turn|s|ms|fr)?$/,/^-?\d+(\.\d+)?e[+-]?\d+$/i,/^#[0-9a-fA-F]{3,8}$/,/^(rgb|rgba|hsl|hsla)\(.+\)$/,/^url\(#?.+\)$/,/^(round|butt|square|miter|bevel|none|normal|evenodd|nonzero|sRGB|linearRGB|userSpaceOnUse|objectBoundingBox|pad|reflect|repeat|auto|inherit|currentColor|meet|slice|xMinYMin|xMidYMin|xMaxYMin|xMinYMid|xMidYMid|xMaxYMid|xMinYMax|xMidYMax|xMaxYMax|stitch|noStitch|duplicate|wrap|arithmetic|atop|in|out|over|xor|dilate|erode|matrix|saturate|hueRotate|luminanceToAlpha|discrete|linear|gamma|table|identity|SourceGraphic|SourceAlpha|BackgroundImage|BackgroundAlpha|FillPaint|StrokePaint)$/,/^[a-zA-Z]+\d*[_a-zA-Z0-9]*(_[a-zA-Z0-9]+)+$/,/^(white|black|red|green|blue|yellow|orange|purple|pink|brown|gray|grey|cyan|magenta|transparent)$/i,/^(auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|vertical-text|alias|copy|move|no-drop|not-allowed|grab|grabbing|all-scroll|col-resize|row-resize|n-resize|e-resize|s-resize|w-resize|ne-resize|nw-resize|se-resize|sw-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|zoom-in|zoom-out)$/,/^(block|inline|inline-block|flex|inline-flex|grid|inline-grid|flow-root|contents|table|table-row|table-cell|list-item|none|visible|hidden|collapse)$/,/^(static|relative|absolute|fixed|sticky)$/,/^(visible|hidden|scroll|auto|clip)$/,/^(https?:\/\/|\/\/|\/|\.\/|\.\.\/)/,/^data:/,/^mailto:/,/^tel:/,/^\.[a-zA-Z0-9]+$/,/^[a-z]+\/[a-z0-9.+-]+$/,/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,/^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?/,/^\d{1,2}:\d{2}(:\d{2})?(\s?(AM|PM|am|pm))?$/,/^[a-z]+[A-Z][a-zA-Z0-9]*$/,/^[a-z][a-z0-9]*_[a-z0-9_]*$/,/^[A-Z][A-Z0-9]*_[A-Z0-9_]+$/,/^(true|false|null|undefined|NaN|Infinity)$/,/^application\//,/^[a-z][a-zA-Z0-9_]*=/,/^[a-z]+-[a-z]+(-[a-z]+)*$/,/^-?[a-z]+-\d+(\.\d+)?(\/\d+)?$/,/^-?[a-z]+-[a-z]+-\d+(\.\d+)?(\/\d+)?$/,/^[a-z]+:[a-z][-a-z0-9/]*$/,/^[a-z]+-[a-z]+(-[a-z]+)*\/\d+$/,/^-?[a-z]+(-[a-z]+)*-\[.+\]$/,/^-[a-z]+-[a-z]+-\d+\/\d+$/,/^[a-z]+-(full|auto|screen|none|inherit|initial|px|fit|min|max)$/,/^(sm|md|lg|xl|2xl|hover|focus|active|disabled|first|last|odd|even|group-hover|dark|motion-safe|motion-reduce):[a-z][-a-z0-9/[\]]*$/,/^[\d,._]+$/,/^\d+\.\d+\.\d+/,/^[,;:|•·\-–—/\\]+$/,/^&[a-z]+;$/,/^[.!?,;:'"()\[\]{}]+$/,/^(rotate|translate|translateX|translateY|translateZ|translate3d|scale|scaleX|scaleY|scaleZ|scale3d|skew|skewX|skewY|matrix|matrix3d|perspective)\(.+\)$/,/^(rotate|translate|translateX|translateY|scale|scaleX|scaleY|skew|skewX|skewY|matrix)\([^)]+\)(\s+(rotate|translate|translateX|translateY|scale|scaleX|scaleY|skew|skewX|skewY|matrix)\([^)]+\))+$/,/^(linear-gradient|radial-gradient|conic-gradient|repeating-linear-gradient|repeating-radial-gradient)\(.+\)$/,/^[a-zA-Z][\w-]*\s+[\d.]+m?s\s+[\w-]+(\s+[\w-]+)*$/,/^(\d+%|center|top|bottom|left|right)(\s+(\d+%|center|top|bottom|left|right))?$/,/^calc\(.+\)$/,/^var\(.+\)$/,/^clamp\(.+\)$/,/^(min|max)\(.+\)$/],s=(t.ignorePatterns||[]).map(p=>typeof p=="string"?new RegExp(p):p),g=[...y,...s],i=/^-?[a-z]+(-[a-z0-9]+)*(\/\d+)?$|^-?[a-z]+(-[a-z0-9]+)*-\[.+\]$|^[a-z]+:[a-z][-a-z0-9/[\]]*$/,r=new Set(["block","contents","flex","flow","grid","hidden","inline","table","absolute","fixed","relative","static","sticky","collapse","invisible","visible","antialiased","capitalize","italic","lowercase","ordinal","overline","subpixel","truncate","underline","uppercase","container","isolate","grow","shrink","border","rounded","group","peer","resize","snap","touch","select","pointer","transition","animate","filter","backdrop","transform","appearance","cursor","outline","ring","shadow","opacity","blur","invert","sepia","grayscale","hue","saturate","brightness","contrast"]),c=p=>{let m=p.trim().split(/\s+/).filter(Boolean);return m.length===0||!m.some(L=>L.includes("-")||L.includes(":")||L.includes("/")||L.includes("["))?!1:m.every(L=>L.includes("${")||r.has(L)?!0:/^-?[a-z]+(-[a-z0-9.]+)+$/.test(L)||/^-?[a-z]+(-[a-z0-9.]+)*\/\d+$/.test(L)||/^[a-z][-a-z0-9]*(\[[-\w=]+\])?:[a-z][-a-z0-9./[\]]*$/.test(L)||/^\[.+\]:[a-z][-a-z0-9./[\]]*$/.test(L)||/^-?[a-z]+(-[a-z]+)*-?\[.+\]$/.test(L))},o=new Set(["button","checkbox","color","date","datetime-local","email","file","hidden","image","month","number","password","radio","range","reset","search","submit","tel","text","time","url","week"]),n=p=>o.has(p.toLowerCase()),h=p=>{let m=p.parent;for(;m;){if(m.type==="Property"&&m.parent&&m.parent.type==="ObjectExpression"){let w=m.parent;if(w.parent&&w.parent.type==="JSXExpressionContainer"){let L=w.parent;if(L.parent&&L.parent.type==="JSXAttribute"&&(L.parent.name&&L.parent.name.name)==="style")return!0}}m=m.parent}return!1},f=[/gradient/i,/transform/i,/animation/i,/transition/i,/color/i,/background/i,/border/i,/shadow/i,/filter/i,/clip/i,/mask/i,/font/i,/^style/i,/Style$/i,/css/i],l=p=>!!(/^(linear-gradient|radial-gradient|conic-gradient|repeating-linear-gradient|repeating-radial-gradient|rotate|translate|translateX|translateY|translateZ|translate3d|scale|scaleX|scaleY|scaleZ|scale3d|skew|skewX|skewY|matrix|matrix3d|perspective|calc|var|clamp|min|max|cubic-bezier|steps|url)\(/i.test(p)||/^(#[0-9a-fA-F]{3,8}|rgb|rgba|hsl|hsla)\(/i.test(p)||/^\d+(\.\d+)?(px|em|rem|%|vh|vw|vmin|vmax|deg|rad|turn|s|ms|fr)\s*/.test(p)),a=p=>{let m=p.parent;for(;m;){if(m.type==="VariableDeclarator"&&m.id&&m.id.name){let w=m.id.name;if(f.some(L=>L.test(w)))return!0}if(m.type==="Property"&&m.key){let w=m.key.name||m.key.value&&String(m.key.value);if(w&&f.some(L=>L.test(w)))return!0}m=m.parent}return!1},u=p=>{let m=p.parent,w=0;for(;m;){if(w++,m.type==="ExportNamedDeclaration"&&w<=3){let L=m.declaration;if(L&&L.type==="VariableDeclaration"){let R=L.declarations[0];if(R&&R.id&&R.id.name){let P=R.id.name;return!(/^[A-Z][A-Z0-9_]*$/.test(P)||/^(constants?|strings?|messages?|labels?|texts?|data)$/i.test(P))}}}if(m.type==="FunctionDeclaration"||m.type==="FunctionExpression"||m.type==="ArrowFunctionExpression")return!1;m=m.parent}return!1},T=(p,m="")=>{let w=p.length>30?`${p.substring(0,30)}...`:p,L=m?` in ${m}`:"",R=!/\s/.test(p)&&p.length<=30,P=/^[a-z_]+$/.test(p),H=m.includes("attribute");return R&&P?H?`Hardcoded "${w}"${L} should be imported from @/enums (preferred) or @/data to prevent typos (e.g., import { InputTypeEnum } from "@/enums")`:`Hardcoded "${w}"${L} should be imported from @/enums (preferred) or @/data (e.g., import { StatusEnum } from "@/enums")`:`Hardcoded UI string "${w}"${L} should be imported from @/strings or @/constants (e.g., import { strings } from "@/strings")`},x=new Set(["cn","cva","clsx","twMerge","classnames","cx","tv","twJoin"]),b=p=>{let m=p.parent,w=!1;for(;m;){if(m.type==="CallExpression"&&m.callee){let L=m.callee.name||m.callee.property&&m.callee.property.name;if(L&&x.has(L))return!0;w=!0}if(w&&m.type==="JSXAttribute"&&m.name){let L=m.name.name;if(L==="className"||L==="class")return!0}m=m.parent}return!1},d=(p,m)=>m&&b(m)||c(p)?!0:g.some(w=>w.test(p)),E=()=>{let m=(e.filename||e.getFilename()).replace(/\\/g,"/").toLowerCase();return/\/(constants|strings|@constants|@strings|data|@data|enums|@enums)(\/|\.)/i.test(m)||/\/data\/(constants|strings)/i.test(m)},A=new Set,S=p=>{let m=p.source.value;if(typeof m!="string")return;/@?\/?(@?constants|@?strings|@?data|@?enums|data\/constants|data\/strings)/i.test(m)&&p.specifiers.forEach(L=>{L.local&&L.local.name&&A.add(L.local.name)})},k=p=>p.type==="Identifier"?A.has(p.name):p.type==="MemberExpression"&&p.object.type==="Identifier"?A.has(p.object.name):!1,$=p=>{let m=p.parent;for(;m;){if(m.type==="FunctionDeclaration"||m.type==="FunctionExpression"||m.type==="ArrowFunctionExpression"){let w=null;return m.id&&m.id.name?w=m.id.name:m.parent&&m.parent.type==="VariableDeclarator"&&m.parent.id&&m.parent.id.name&&(w=m.parent.id.name),w&&(/^[A-Z]/.test(w)||/^use[A-Z]/.test(w)||/Handler$|Helper$|Util$|Utils$/i.test(w)),!0}if(m.type==="JSXElement"||m.type==="JSXFragment")return!0;m=m.parent}return!1},v=p=>{let m=p.parent,w=0;for(;m;){if(w++,m.type==="VariableDeclarator"){let L=m.id&&m.id.name;if(L&&(/^[A-Z][A-Z0-9_]*$/.test(L)||/^(constants?|strings?|messages?|labels?|texts?|data)$/i.test(L)))return!0}if(m.type==="ExportNamedDeclaration"&&w<=3){let L=m.declaration;if(L&&L.type==="VariableDeclaration"){let R=L.declarations[0];if(R&&R.init){let P=R.init.type;if(P==="Literal"||P==="ObjectExpression"||P==="ArrayExpression")return!0}}}if(m.type==="FunctionDeclaration"||m.type==="FunctionExpression"||m.type==="ArrowFunctionExpression")return!1;m=m.parent}return!1};return E()?{}:{ImportDeclaration:S,JSXText(p){let m=p.value.trim();m&&(d(m,p)||/[a-zA-Z]/.test(m)&&e.report({message:T(m,"JSX"),node:p}))},JSXExpressionContainer(p){let{expression:m}=p;if(!k(m)){if(p.parent&&p.parent.type==="JSXAttribute"){let w=p.parent.name.name||p.parent.name.namespace&&`${p.parent.name.namespace.name}:${p.parent.name.name.name}`;if(C.includes(w)||w&&(w.startsWith("data-")||w.startsWith("aria-")))return}if(m.type==="Literal"&&typeof m.value=="string"){let w=m.value;if(d(w,m)||!/[a-zA-Z]/.test(w))return;e.report({message:T(w,"JSX expression"),node:m})}m.type==="TemplateLiteral"&&m.quasis.forEach(w=>{let L=w.value.cooked||w.value.raw;d(L,m)||/[a-zA-Z]{2,}/.test(L)&&(/^[/.]|https?:\/\//.test(L)||e.report({message:T(L,"template literal"),node:w}))})}},JSXAttribute(p){if(!p.value)return;let m=p.name.name||p.name.namespace&&`${p.name.namespace.name}:${p.name.name.name}`;if(!C.includes(m)&&!(m&&m.startsWith("data-"))&&!(m&&m.startsWith("aria-"))){if(p.value.type==="Literal"&&typeof p.value.value=="string"){let w=p.value.value;if(d(w,p.value)||!/[a-zA-Z]/.test(w))return;e.report({message:T(w,`attribute "${m}"`),node:p.value})}if(p.value.type==="JSXExpressionContainer"){let{expression:w}=p.value;if(k(w))return;if(w.type==="Literal"&&typeof w.value=="string"){let L=w.value;if(d(L,w)||!/[a-zA-Z]/.test(L))return;e.report({message:T(L,`attribute "${m}"`),node:w})}}}},Literal(p){if(typeof p.value!="string")return;let m=p.value;if(!h(p)){if(u(p)){if(!/[a-zA-Z]/.test(m))return;e.report({message:T(m,"exported constant"),node:p});return}d(m,p)||$(p)&&(v(p)||p.parent.type==="JSXAttribute"||p.parent.type==="JSXExpressionContainer"||p.parent.type==="ImportDeclaration"||p.parent.type==="ExportNamedDeclaration"||p.parent.type==="ExportAllDeclaration"||p.parent.type==="Property"&&p.parent.key===p||/[a-zA-Z]/.test(m)&&e.report({message:T(m),node:p}))}},TemplateLiteral(p){if(p.parent.type!=="JSXExpressionContainer"&&!h(p)){if(a(p)){let m=p.quasis.map(w=>w.value.cooked||w.value.raw).join("");if(l(m))return}$(p)&&(v(p)||p.quasis.forEach(m=>{let w=m.value.cooked||m.value.raw;d(w,p)||/[a-zA-Z]{3,}/.test(w)&&(/^[/.]|^https?:\/\/|^[?&]/.test(w)||p.expressions.length>p.quasis.length||e.report({message:T(w,"template literal"),node:m}))}))}}}},meta:{docs:{description:"Enforce importing strings from constants/strings modules instead of hardcoding them"},schema:[{additionalProperties:!1,properties:{extraIgnoreAttributes:{description:"Additional JSX attributes to ignore (extends defaults)",items:{type:"string"},type:"array"},ignoreAttributes:{description:"JSX attributes to ignore (replaces defaults)",items:{type:"string"},type:"array"},ignorePatterns:{description:"Regex patterns for strings to ignore",items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}};var Nt={create(e){let t=e.sourceCode||e.getSourceCode(),I=new Map,C=c=>c.endsWith("Type")?c.slice(0,-4)+"Enum":null,y=c=>c.toUpperCase().replace(/-/g,"_"),s=c=>{if(!c)return null;let o=c.typeAnnotation;if(!o)return null;if(o.type==="TSTypeReference"&&o.typeName?.type==="Identifier"){let n=o.typeName.name;if(n.endsWith("Type"))return{enumName:C(n),typeName:n}}return null},g=c=>{c.forEach(o=>{if(o.type==="TSPropertySignature"&&o.key?.type==="Identifier"){let n=o.key.name,h=s(o.typeAnnotation);h&&I.set(n,h)}})},i=c=>{c.forEach(o=>{if(o.type==="ObjectPattern"&&o.typeAnnotation){let n=o.typeAnnotation.typeAnnotation;n&&n.type==="TSTypeLiteral"&&g(n.members),n&&n.type==="TSIntersectionType"&&n.types.forEach(h=>{h.type==="TSTypeLiteral"&&g(h.members)})}if(o.type==="Identifier"&&o.typeAnnotation){let n=s(o);n&&I.set(o.name,n)}})},r=(c,o)=>{let h=t.getScope?t.getScope(o):e.getScope();for(;h;){if(h.variables.some(f=>f.name===c))return!0;h=h.upper}return!1};return{"ArrowFunctionExpression, FunctionDeclaration, FunctionExpression"(c){i(c.params)},AssignmentPattern(c){if(c.left.type!=="Identifier")return;let o=c.left.name,n=I.get(o);if(n&&c.right.type==="Literal"&&typeof c.right.value=="string"){let h=c.right.value,f=y(h),l=`${n.enumName}.${f}`,a=r(n.enumName,c);e.report({fix:a?u=>u.replaceText(c.right,l):void 0,message:`Use "${l}" instead of string literal "${h}"`,node:c.right})}},BinaryExpression(c){if(c.operator!=="==="&&c.operator!=="!==")return;let o=null,n=null;if(c.left.type==="Identifier"&&c.right.type==="Literal"?(o=c.left,n=c.right):c.right.type==="Identifier"&&c.left.type==="Literal"&&(o=c.right,n=c.left),!o||!n||typeof n.value!="string")return;let h=I.get(o.name);if(!h)return;let f=n.value,l=y(f),a=`${h.enumName}.${l}`,u=r(h.enumName,c);e.report({fix:u?T=>T.replaceText(n,a):void 0,message:`Use "${a}" instead of string literal "${f}"`,node:n})},"ArrowFunctionExpression:exit"(){I.clear()},"FunctionDeclaration:exit"(){I.clear()},"FunctionExpression:exit"(){I.clear()}}},meta:{docs:{description:"Enforce using enum values instead of string literals for typed variables"},fixable:"code",schema:[],type:"suggestion"}},Dt={create(e){let t=e.options[0]||{},I=["is","has","with","without"],C=t.booleanPrefixes||[...I,...t.extendBooleanPrefixes||[]],y=t.allowPastVerbBoolean||!1,s=t.allowContinuousVerbBoolean||!1,g=t.callbackPrefix||"on",i=t.allowActionSuffix||!1,r=new RegExp(`^(${C.join("|")})[A-Z]`),c=new RegExp(`^${g}[A-Z]`),o=/^[a-z]+ed$/,n=/^[a-z]+ing$/,h=["children","content","data","error","errors","items","permission","permissions","value","values"],f=v=>{let p=v.toLowerCase();return(h.some(w=>p.includes(w))?"has":"is")+v[0].toUpperCase()+v.slice(1)},l=v=>{if(v.startsWith("handle")&&v.length>6){let p=v.slice(6);return g+p[0].toUpperCase()+p.slice(1)}if(v.endsWith("Handler")&&v.length>7){let p=v.slice(0,-7);return g+p[0].toUpperCase()+p.slice(1)}return g+v[0].toUpperCase()+v.slice(1)},a=v=>{if(!v)return!1;let p=v.typeAnnotation;return p?p.type==="TSBooleanKeyword"?!0:p.type==="TSUnionType"?p.types.some(m=>m.type==="TSBooleanKeyword"):!1:!1},u=["MouseEventHandler","ChangeEventHandler","FormEventHandler","KeyboardEventHandler","FocusEventHandler","TouchEventHandler","PointerEventHandler","DragEventHandler","WheelEventHandler","AnimationEventHandler","TransitionEventHandler","ClipboardEventHandler","CompositionEventHandler","UIEventHandler","ScrollEventHandler","EventHandler"],T=v=>{if(!v)return!1;let p=v.typeAnnotation;if(!p)return!1;if(p.type==="TSFunctionType")return!0;if(p.type==="TSTypeReference"){let m=p.typeName?.name;if(m==="Function"||m==="VoidFunction"||u.includes(m))return!0}return p.type==="TSUnionType"?p.types.some(m=>m.type==="TSFunctionType"||m.type==="TSTypeReference"&&(m.typeName?.name==="Function"||m.typeName?.name==="VoidFunction"||u.includes(m.typeName?.name))):!1},x=v=>{if(!v)return!1;let p=v.typeAnnotation;return p?p.type==="TSTypeLiteral":!1},b=v=>!!(r.test(v)||y&&o.test(v)||s&&n.test(v)),d=v=>!!(c.test(v)||i&&v.endsWith("Action")&&v.length>6),E=v=>{let p=v;for(;p;){if(p.type==="ArrowFunctionExpression"||p.type==="FunctionExpression"||p.type==="FunctionDeclaration")return p;p=p.parent}return null},A=(v,p)=>{if(!v||!v.params||v.params.length===0)return null;let m=v.params[0];if(m.type!=="ObjectPattern")return null;for(let w of m.properties)if(w.type==="Property"&&w.key&&w.key.type==="Identifier"&&w.key.name===p)return w;return null},S=(v,p,m,w)=>{let L=[v.replaceText(p.key,w)],R=E(p);if(!R)return L;let P=A(R,m);if(!P)return L;let H=P.value||P.key;if(!H||H.type!=="Identifier")return L;P.shorthand!==!1&&P.key===P.value?L.push(v.replaceText(P,`${m}: ${w}`)):L.push(v.replaceText(H,w));let M=e.sourceCode?e.sourceCode.getScope(R):e.getScope(),j=(D,z)=>{let q=D.variables.find(_=>_.name===z);return q||(D.upper?j(D.upper,z):null)},N=j(M,m);if(N){let D=new Set;N.references.forEach(z=>{if(z.identifier===H)return;let q=`${z.identifier.range[0]}-${z.identifier.range[1]}`;D.has(q)||(D.add(q),L.push(v.replaceText(z.identifier,w)))})}return L},k=v=>{if(v.type!=="TSPropertySignature"||!v.key||v.key.type!=="Identifier")return;let p=v.key.name;if(!p.startsWith("_")){if(x(v.typeAnnotation)){let m=v.typeAnnotation.typeAnnotation;m&&m.members&&m.members.forEach(k);return}if(a(v.typeAnnotation)){if(!b(p)){let m=f(p);e.report({fix:w=>S(w,v,p,m),message:`Boolean prop "${p}" should start with a valid prefix (${C.join(", ")}). Use "${m}" instead.`,node:v.key})}return}if(T(v.typeAnnotation)&&!d(p)){let m=l(p);e.report({fix:w=>S(w,v,p,m),message:`Callback prop "${p}" should start with "${g}" prefix. Use "${m}" instead.`,node:v.key})}}},$=v=>{v.members&&v.members.forEach(k)};return{TSInterfaceDeclaration(v){!v.body||!v.body.body||v.body.body.forEach(k)},TSTypeAliasDeclaration(v){v.typeAnnotation?.type==="TSTypeLiteral"&&$(v.typeAnnotation)},TSTypeLiteral(v){v.parent?.type!=="TSTypeAliasDeclaration"&&$(v)}}},meta:{docs:{description:"Enforce naming conventions: boolean props must start with is/has/with/without, callback props must start with on"},fixable:"code",schema:[{additionalProperties:!1,properties:{allowActionSuffix:{default:!1,description:"Allow 'xxxAction' pattern for callback props (e.g., submitAction, copyAction)",type:"boolean"},allowContinuousVerbBoolean:{default:!1,description:"Allow continuous verb boolean props without prefix (e.g., loading, saving, fetching, closing)",type:"boolean"},allowPastVerbBoolean:{default:!1,description:"Allow past verb boolean props without prefix (e.g., disabled, selected, checked, opened)",type:"boolean"},booleanPrefixes:{description:"Replace default boolean prefixes entirely. If not provided, defaults are used with extendBooleanPrefixes",items:{type:"string"},type:"array"},callbackPrefix:{default:"on",description:"Required prefix for callback props",type:"string"},extendBooleanPrefixes:{default:[],description:"Add additional prefixes to the defaults (is, has, with, without)",items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}},Jt={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.maxUnionMembers??2,y=I.maxLength??50,s=new Set(["any","bigint","boolean","never","null","number","object","string","symbol","undefined","unknown","void"]),g=new Set(["Array","BigInt","Boolean","Date","Error","Function","Map","Number","Object","Promise","ReadonlyArray","RegExp","Set","String","Symbol","WeakMap","WeakSet"]),i=n=>{if(!n)return!1;if(n.type==="TSStringKeyword"||n.type==="TSNumberKeyword"||n.type==="TSBooleanKeyword"||n.type==="TSNullKeyword"||n.type==="TSUndefinedKeyword"||n.type==="TSVoidKeyword"||n.type==="TSAnyKeyword"||n.type==="TSUnknownKeyword"||n.type==="TSNeverKeyword"||n.type==="TSObjectKeyword"||n.type==="TSSymbolKeyword"||n.type==="TSBigIntKeyword")return!0;if(n.type==="TSTypeReference"&&n.typeName){let h=n.typeName.name||n.typeName.type==="Identifier"&&n.typeName.name;if(h&&g.has(h))return!0}return n.type==="TSLiteralType"},r=n=>n.type!=="TSUnionType"?!1:n.types.every(h=>i(h)),c=n=>{if(n.type!=="TSUnionType")return 1;let h=0;for(let f of n.types)h+=c(f);return h},o=(n,h)=>{if(n){if(n.type==="TSUnionType"){if(r(n))return;let f=c(n),l=t.getText(n);(f>=C||l.length>y)&&e.report({message:`Inline union type with ${f} members is too complex. Extract to a named type in a types file.`,node:n});return}if(n.type==="TSIntersectionType"){for(let f of n.types)o(f,h);return}if(n.type==="TSTypeLiteral"){for(let f of n.members)if(f.type==="TSPropertySignature"&&f.typeAnnotation){let l=f.typeAnnotation.typeAnnotation,a=f.key&&f.key.name?f.key.name:"unknown";if(l&&l.type==="TSUnionType"){let u=c(l),T=t.getText(l);(u>=C||T.length>y)&&e.report({message:`Property "${a}" has inline union type with ${u} members. Extract to a named type in a types file.`,node:l})}}}}};return{ArrowFunctionExpression(n){for(let h of n.params)if(h.typeAnnotation&&h.typeAnnotation.typeAnnotation){let f=h.type==="Identifier"?h.name:"param";o(h.typeAnnotation.typeAnnotation,f)}},FunctionDeclaration(n){for(let h of n.params)if(h.typeAnnotation&&h.typeAnnotation.typeAnnotation){let f=h.type==="Identifier"?h.name:"param";o(h.typeAnnotation.typeAnnotation,f)}},FunctionExpression(n){for(let h of n.params)if(h.typeAnnotation&&h.typeAnnotation.typeAnnotation){let f=h.type==="Identifier"?h.name:"param";o(h.typeAnnotation.typeAnnotation,f)}}}},meta:{docs:{description:"Enforce extracting inline union types to named types in type files"},schema:[{additionalProperties:!1,properties:{maxLength:{default:50,description:"Maximum character length for inline union types (default: 50)",minimum:1,type:"integer"},maxUnionMembers:{default:2,description:"Maximum union members to keep inline (default: 2)",minimum:1,type:"integer"}},type:"object"}],type:"suggestion"}},Xt={create(e){let t=e.sourceCode||e.getSourceCode(),I=e.options[0]||{},C=I.minUnionMembersForMultiline!==void 0?I.minUnionMembersForMultiline:5,y=/^[A-Z][a-zA-Z0-9]*$/,s=/^[a-z][a-zA-Z0-9]*$/,g=c=>/^[A-Z][A-Z0-9_]*$/.test(c)?c.toLowerCase().replace(/_([a-z0-9])/g,(o,n)=>n.toUpperCase()):/_/.test(c)?c.toLowerCase().replace(/_([a-z0-9])/g,(o,n)=>n.toUpperCase()):/^[A-Z]/.test(c)?c[0].toLowerCase()+c.slice(1):c,i=(c,o,n)=>{if(n.length===0)return;let f=t.lines[c.loc.start.line-1].match(/^\s*/)[0],l=f+" ",a=t.getFirstToken(o),u=t.getLastToken(o),T=n[0];T.loc.start.line-a.loc.end.line>1&&e.report({fix:b=>b.replaceTextRange([a.range[1],T.range[0]],`
|
|
234
|
+
`+l),message:"No empty line after opening brace in type",node:T});let x=n[n.length-1];u.loc.start.line-x.loc.end.line>1&&e.report({fix:b=>b.replaceTextRange([x.range[1],u.range[0]],`
|
|
235
|
+
`+f),message:"No empty line before closing brace in type",node:x}),n.length>=2&&u.loc.start.line===x.loc.end.line&&e.report({fix:b=>b.replaceTextRange([x.range[1],u.range[0]],`
|
|
236
|
+
`+f),message:"Closing brace should be on its own line in multiline type literal",node:u}),n.length>1&&T.loc.start.line===a.loc.end.line&&e.report({fix:b=>b.replaceTextRange([a.range[1],T.range[0]],`
|
|
237
|
+
`+l),message:"First type property must be on a new line when there are multiple properties",node:T}),n.forEach((b,d)=>{if(b.type==="TSPropertySignature"&&b.key&&b.key.type==="Identifier"){let S=b.key.name;if(!s.test(S)){let k=g(S);e.report({fix:$=>$.replaceText(b.key,k),message:`Type property "${S}" must be camelCase. Use "${k}" instead.`,node:b.key})}}let E=null;if(b.type==="TSPropertySignature"&&b.typeAnnotation?.typeAnnotation){let S=b.typeAnnotation.typeAnnotation;S.type==="TSTypeLiteral"?E=S:S.type==="TSArrayType"&&S.elementType?.type==="TSTypeLiteral"&&(E=S.elementType)}if(E){let S=E;if(S.members&&S.members.length===1){let k=t.getFirstToken(S),$=t.getLastToken(S);if(k.loc.end.line!==$.loc.start.line){let p=S.members[0],m=t.getText(p).trim();(m.endsWith(",")||m.endsWith(";"))&&(m=m.slice(0,-1)),e.report({fix:w=>w.replaceTextRange([k.range[0],$.range[1]],`{ ${m} }`),message:"Single property nested object type should be on one line",node:S})}}else S.members&&S.members.length>=2&&i(b,S,S.members)}if(b.type==="TSPropertySignature"&&b.optional){let S=t.getFirstToken(b),k=t.getTokenAfter(S);k&&k.value==="?"&&t.getText().slice(S.range[1],k.range[0])!==""&&e.report({fix:v=>v.replaceTextRange([S.range[1],k.range[0]],""),message:'No space allowed before "?" in optional property',node:b})}let A=t.getText(b);if(A.trimEnd().endsWith(";")&&e.report({fix(S){let k=A.lastIndexOf(";"),$=b.range[0]+k;return S.replaceTextRange([$,$+1],",")},message:"Type properties must end with comma (,) not semicolon (;)",node:b}),n.length>=2&&d===n.length-1){let S=A.trimEnd();!S.endsWith(",")&&!S.endsWith(";")&&e.report({fix:k=>k.insertTextAfter(b,","),message:"Last type property must have trailing comma",node:b})}if(n.length>1&&d>0){let S=n[d-1];b.loc.start.line===S.loc.end.line&&e.report({fix:k=>{let $=t.getTokenAfter(S);for(;$&&$.value!==","&&$.range[0]<b.range[0];)$=t.getTokenAfter($);let v=$&&$.value===","?$.range[1]:S.range[1];return k.replaceTextRange([v,b.range[0]],`
|
|
238
|
+
`+l)},message:"Each type property must be on its own line when there are multiple properties",node:b}),b.loc.start.line-S.loc.end.line>1&&e.report({fix(k){let v=t.getText().slice(S.range[1],b.range[0]).replace(/\n\s*\n/g,`
|
|
239
|
+
`);return k.replaceTextRange([S.range[1],b.range[0]],v)},message:"No empty lines allowed between type properties",node:b})}})},r=(c,o)=>{let{members:n}=c;if(n.length===0)return;let h=t.getFirstToken(c),f=t.getLastToken(c),l=h.loc.start.line!==f.loc.end.line;if(n.length===1){let T=n[0],x=t.getText(T);if(x.trimEnd().endsWith(",")){e.report({fix:b=>{let d=T.range[1]-1,A=t.getText().slice(T.range[0],T.range[1]).lastIndexOf(",");return A!==-1?b.removeRange([T.range[0]+A,T.range[0]+A+1]):null},message:"Single property inline type should not have trailing comma",node:T});return}if(l){let b=`{ ${x.trim().replace(/,$/,"")} }`;e.report({fix:d=>d.replaceText(c,b),message:"Single property inline type should be on one line",node:c})}return}if(!l){let T=t.getTokenBefore(c),x=t.getText().lastIndexOf(`
|
|
240
|
+
`,T.range[0])+1,d=t.getText().slice(x,T.range[0]).match(/^\s*/)[0],E=d+" ",S=`{
|
|
241
241
|
${n.map(k=>{let $=t.getText(k).trim();return $.endsWith(";")?$=$.slice(0,-1)+",":$.endsWith(",")||($+=","),E+$}).join(`
|
|
242
242
|
`)}
|
|
243
|
-
${
|
|
244
|
-
`+" ".repeat(
|
|
245
|
-
`+" ".repeat(a.loc.start.column)),message:"No empty line after opening brace in inline type",node:a}),n.length>=2&&h.loc.end.line===a.loc.start.line){let
|
|
246
|
-
`+x),message:"First property of multiline inline type should be on its own line",node:a})}let u=n[n.length-1];if(f.loc.start.line-u.loc.end.line>1){let
|
|
247
|
-
`+
|
|
248
|
-
`,
|
|
249
|
-
`+
|
|
243
|
+
${d} }`;e.report({fix:k=>k.replaceText(c,S),message:"Inline type with 2+ properties should be multiline with trailing commas",node:c});return}n.forEach((T,x)=>{let b=t.getText(T);if(b.trimEnd().endsWith(";")){let d=b.lastIndexOf(";");e.report({fix:E=>E.replaceTextRange([T.range[0]+d,T.range[0]+d+1],","),message:"Type properties must end with comma (,) not semicolon (;)",node:T})}else x===n.length-1&&!b.trimEnd().endsWith(",")&&e.report({fix:d=>d.insertTextAfter(T,","),message:"Last property in multiline inline type should have trailing comma",node:T});if(x<n.length-1){let d=n[x+1];d.loc.start.line-T.loc.end.line>1&&e.report({fix:E=>E.replaceTextRange([T.range[1],d.range[0]],`
|
|
244
|
+
`+" ".repeat(d.loc.start.column)),message:"No empty lines between type properties",node:d})}});let a=n[0];if(a.loc.start.line-h.loc.end.line>1&&e.report({fix:T=>T.replaceTextRange([h.range[1],a.range[0]],`
|
|
245
|
+
`+" ".repeat(a.loc.start.column)),message:"No empty line after opening brace in inline type",node:a}),n.length>=2&&h.loc.end.line===a.loc.start.line){let T=n[n.length-1],x=" ".repeat(T.loc.start.column);e.report({fix:b=>b.replaceTextRange([h.range[1],a.range[0]],`
|
|
246
|
+
`+x),message:"First property of multiline inline type should be on its own line",node:a})}let u=n[n.length-1];if(f.loc.start.line-u.loc.end.line>1){let T=" ".repeat(f.loc.start.column);e.report({fix:x=>x.replaceTextRange([u.range[1],f.range[0]],`
|
|
247
|
+
`+T),message:"No empty line before closing brace in inline type",node:f})}if(n.length>=2&&f.loc.start.line===u.loc.end.line){let T=t.getTokenBefore(c,x=>x.value==="as");if(T){let x=t.getText().lastIndexOf(`
|
|
248
|
+
`,T.range[0])+1,d=t.getText().slice(x,T.range[0]).match(/^\s*/)[0];e.report({fix:E=>E.replaceTextRange([u.range[1],f.range[0]],`
|
|
249
|
+
`+d+" "),message:"Closing brace should be on its own line in multiline type literal",node:f})}}};return{TSAsExpression(c){let{typeAnnotation:o}=c,n=t.getTokenBefore(o,h=>h.value==="as");if(n&&o){let h=t.getFirstToken(o),f=t.text.slice(n.range[1],h.range[0]);h.value==="{"?f!==" "&&e.report({fix:l=>l.replaceTextRange([n.range[1],h.range[0]]," "),message:"Type assertion should have exactly one space after 'as' and opening brace on same line",node:h}):n.loc.end.line!==h.loc.start.line&&e.report({fix:l=>l.replaceTextRange([n.range[1],h.range[0]]," "),message:"Type should be on same line as 'as' keyword",node:h})}o&&o.type==="TSTypeLiteral"&&r(o,c)},TSTypeAliasDeclaration(c){let o=c.id.name;if(y.test(o)?o.endsWith("Type")||e.report({fix(n){return n.replaceText(c.id,`${o}Type`)},message:`Type name "${o}" must end with "Type" suffix. Use "${o}Type" instead of "${o}"`,node:c.id}):e.report({message:`Type name "${o}" must be PascalCase`,node:c.id}),c.typeAnnotation&&c.typeAnnotation.type==="TSTypeLiteral"){let{members:n}=c.typeAnnotation;if(n.length===1){let h=t.getFirstToken(c.typeAnnotation),f=t.getLastToken(c.typeAnnotation),l=h.loc.start.line!==f.loc.end.line,a=n[0],u=t.getText(a).trim();if((u.endsWith(",")||u.endsWith(";"))&&(u=u.slice(0,-1)),l){let T=t.getTokenAfter(c.id);e.report({fix:x=>x.replaceTextRange([T.range[0],f.range[1]],`= { ${u} }`),message:"Single property type should be on one line",node:c.typeAnnotation})}else{let T=t.getText(a);if(T.trimEnd().endsWith(",")){let x=T.lastIndexOf(",");e.report({fix:b=>b.removeRange([a.range[0]+x,a.range[0]+x+1]),message:"Single property inline type should not have trailing comma",node:a})}else if(T.trimEnd().endsWith(";")){let x=T.lastIndexOf(";");e.report({fix:b=>b.replaceTextRange([a.range[0]+x,a.range[0]+x+1],","),message:"Type properties must end with comma (,) not semicolon (;)",node:a})}}}else{let h=t.getFirstToken(c.typeAnnotation);h&&h.loc.start.line!==c.id.loc.end.line&&e.report({fix:f=>{let l=t.getTokenAfter(c.id);return f.replaceTextRange([l.range[1],h.range[0]]," ")},message:"Opening brace must be on the same line as type name",node:h}),i(c,c.typeAnnotation,c.typeAnnotation.members)}}if(c.typeAnnotation&&c.typeAnnotation.type==="TSIntersectionType"){let n=c.typeAnnotation.types,h=t.getTokenAfter(c.id);n.forEach(f=>{if(f.type!=="TSTypeLiteral")return;let{members:l}=f;if(l.length!==0)if(l.length===1){let a=t.getFirstToken(f),u=t.getLastToken(f),T=l[0];if(a.loc.start.line!==u.loc.end.line){let b=t.getText(T).trim();(b.endsWith(",")||b.endsWith(";"))&&(b=b.slice(0,-1)),e.report({fix:d=>d.replaceTextRange([a.range[0],u.range[1]],`{ ${b} }`),message:"Single property type in intersection should be inline",node:f})}else{let b=t.getText(T);if(b.trimEnd().endsWith(",")){let d=b.lastIndexOf(",");e.report({fix:E=>E.removeRange([T.range[0]+d,T.range[0]+d+1]),message:"Single property inline type should not have trailing comma",node:T})}else if(b.trimEnd().endsWith(";")){let d=b.lastIndexOf(";");e.report({fix:E=>E.replaceTextRange([T.range[0]+d,T.range[0]+d+1],","),message:"Type properties must end with comma (,) not semicolon (;)",node:T})}}}else i(c,f,l)}),h&&n[0]&&n[0].loc.start.line!==h.loc.end.line&&e.report({fix:f=>f.replaceTextRange([h.range[1],n[0].range[0]]," "),message:"First intersection member should be on same line as '='",node:n[0]});for(let f=1;f<n.length;f++){let l=n[f-1],a=n[f],u=t.getTokenBefore(a,T=>T.value==="&");u&&(u.loc.start.line!==l.loc.end.line&&e.report({fix:T=>T.replaceTextRange([l.range[1],u.range[0]]," "),message:"'&' should be on same line as previous intersection member",node:u}),a.loc.start.line!==u.loc.start.line&&e.report({fix:T=>T.replaceTextRange([u.range[1],a.range[0]]," "),message:"Intersection member should be on same line as '&'",node:a}))}}if(c.typeAnnotation&&c.typeAnnotation.type==="TSUnionType"){let n=c.typeAnnotation,h=n.types,f=C,u=t.lines[c.loc.start.line-1].match(/^\s*/)[0]+" ",T=t.getTokenAfter(c.id),x=h[0],b=h[h.length-1],d=x.loc.start.line===b.loc.end.line&&T.loc.end.line===x.loc.start.line,E=x.loc.start.line>T.loc.end.line;if(h.length>=f){let A=!1;if(E||(A=!0),!A){for(let S=1;S<h.length;S++)if(h[S].loc.start.line===h[S-1].loc.end.line){A=!0;break}}if(!A)for(let S=1;S<h.length;S++){let k=t.getTokenBefore(h[S]);if(k&&k.value==="|"&&k.loc.start.line!==h[S].loc.start.line){A=!0;break}}if(A){let k=`=
|
|
250
250
|
${h.map(($,v)=>{let p=t.getText($);return v===0?u+p:u+"| "+p}).join(`
|
|
251
|
-
`)}`;e.report({fix:$=>$.replaceTextRange([
|
|
252
|
-
`)&&e.report({fix:g=>g.replaceTextRange([C.range[1],y.range[0]]," "),message:"Should have exactly one space after async keyword",node:C})}}},FunctionExpression(I){if(I.async){let C=t.getFirstToken(I,s=>s.value==="async"),y=t.getTokenAfter(C,s=>s.value==="function");if(y){let s=t.getTokenAfter(y,g=>g.value==="(");s&&t.text.slice(y.range[1],s.range[0])===""&&e.report({fix:i=>i.insertTextAfter(y," "),message:"Missing space after function keyword",node:y})}}},TSArrayType(I){let C=I.elementType,y=t.getTokenAfter(C,s=>s.value==="[");y&&t.text.slice(C.range[1],y.range[0])!==""&&e.report({fix:g=>g.removeRange([C.range[1],y.range[0]]),message:"No space allowed before [] in array type",node:y})},TSTypeReference(I){if(I.typeArguments||I.typeParameters){let C=I.typeArguments||I.typeParameters,y=t.getFirstToken(C);if(y&&y.value==="<"){let s=t.getTokenBefore(y);s&&t.text.slice(s.range[1],y.range[0])!==""&&e.report({fix:i=>i.removeRange([s.range[1],y.range[0]]),message:"No space allowed before < in generic type",node:y})}}},TSTypeAnnotation(I){let C=t.getFirstToken(I);if(!C||C.value!==":")return;let y=t.getTokenBefore(C);if(y&&t.getText().slice(y.range[1],C.range[0])!==""){e.report({fix:i=>i.removeRange([y.range[1],C.range[0]]),message:"No space allowed before colon in type annotation",node:C});return}let s=I.typeAnnotation;if(s&&t.text.slice(C.range[1],s.range[0])===""){e.report({fix:i=>i.insertTextAfter(C," "),message:"Missing space after colon in type annotation",node:C});return}s&&C.loc.end.line!==s.loc.start.line&&e.report({fix:g=>g.replaceTextRange([C.range[1],s.range[0]]," "),message:"Type should be on the same line as colon in type annotation",node:s})},TSTypeParameterInstantiation(I){let C=t.getFirstToken(I),y=t.getLastToken(I);if(!C||!y||C.value!=="<"||y.value!==">")return;let s=I.params[0],g=s&&C.loc.end.line===y.loc.start.line;if(s&&g){let o=t.getText().slice(C.range[1],s.range[0]);o.trim()===""&&o!==""&&e.report({fix:n=>n.removeRange([C.range[1],s.range[0]]),message:"No space allowed after < in generic type",node:C})}let i=I.params[I.params.length-1];if(i&&g){let o=t.getText().slice(i.range[1],y.range[0]);o.trim()===""&&o!==""&&e.report({fix:n=>n.removeRange([i.range[1],y.range[0]]),message:"No space allowed before > in generic type",node:y})}let r=I.params;if(r.length===1){let o=r[0];if(C.loc.end.line!==y.loc.start.line){let f=t.getText(o).trim(),
|
|
251
|
+
`)}`;e.report({fix:$=>$.replaceTextRange([T.range[0],b.range[1]],k),message:`Union type with ${h.length} members should be multiline with each member on its own line`,node:n})}}else{let A=h.some(S=>S.type==="TSTypeLiteral"&&S.members&&S.members.length>=2);if(!d&&!A){let k=`= ${h.map($=>t.getText($)).join(" | ")}`;e.report({fix:$=>$.replaceTextRange([T.range[0],b.range[1]],k),message:`Union type with ${h.length} members should be on a single line`,node:n})}}}},TSTypeLiteral(c){if(c.parent?.type==="TSTypeAliasDeclaration"||c.parent?.type==="TSAsExpression"||c.parent?.type==="TSTypeAnnotation"&&c.parent.parent?.type==="TSPropertySignature"&&c.parent.parent.parent?.type==="TSTypeLiteral"&&(c.parent.parent.parent.parent?.type==="TSTypeAliasDeclaration"||c.parent.parent.parent.parent?.type==="TSIntersectionType")||!c.members||c.members.length===0)return;let o=c.parent;for(;o&&!o.loc;)o=o.parent;o&&i(o,c,c.members)}}},meta:{docs:{description:"Enforce type naming (PascalCase + Type suffix), camelCase properties, proper formatting, union type formatting, and trailing commas"},fixable:"code",schema:[{additionalProperties:!1,properties:{minUnionMembersForMultiline:{default:5,description:"Minimum number of union members to require multiline format",minimum:2,type:"integer"}},type:"object"}],type:"suggestion"}},zt={create(e){let t=e.sourceCode||e.getSourceCode();return{ArrowFunctionExpression(I){if(I.async){let C=t.getFirstToken(I,s=>s.value==="async"),y=t.getTokenAfter(C,s=>s.value==="(");if(C&&y){let s=t.text.slice(C.range[1],y.range[0]);s===""?e.report({fix:g=>g.insertTextAfter(C," "),message:"Missing space after async keyword",node:C}):s!==" "&&!s.includes(`
|
|
252
|
+
`)&&e.report({fix:g=>g.replaceTextRange([C.range[1],y.range[0]]," "),message:"Should have exactly one space after async keyword",node:C})}}},FunctionExpression(I){if(I.async){let C=t.getFirstToken(I,s=>s.value==="async"),y=t.getTokenAfter(C,s=>s.value==="function");if(y){let s=t.getTokenAfter(y,g=>g.value==="(");s&&t.text.slice(y.range[1],s.range[0])===""&&e.report({fix:i=>i.insertTextAfter(y," "),message:"Missing space after function keyword",node:y})}}},TSArrayType(I){let C=I.elementType,y=t.getTokenAfter(C,s=>s.value==="[");y&&t.text.slice(C.range[1],y.range[0])!==""&&e.report({fix:g=>g.removeRange([C.range[1],y.range[0]]),message:"No space allowed before [] in array type",node:y})},TSTypeReference(I){if(I.typeArguments||I.typeParameters){let C=I.typeArguments||I.typeParameters,y=t.getFirstToken(C);if(y&&y.value==="<"){let s=t.getTokenBefore(y);s&&t.text.slice(s.range[1],y.range[0])!==""&&e.report({fix:i=>i.removeRange([s.range[1],y.range[0]]),message:"No space allowed before < in generic type",node:y})}}},TSTypeAnnotation(I){let C=t.getFirstToken(I);if(!C||C.value!==":")return;let y=t.getTokenBefore(C);if(y&&t.getText().slice(y.range[1],C.range[0])!==""){e.report({fix:i=>i.removeRange([y.range[1],C.range[0]]),message:"No space allowed before colon in type annotation",node:C});return}let s=I.typeAnnotation;if(s&&t.text.slice(C.range[1],s.range[0])===""){e.report({fix:i=>i.insertTextAfter(C," "),message:"Missing space after colon in type annotation",node:C});return}s&&C.loc.end.line!==s.loc.start.line&&e.report({fix:g=>g.replaceTextRange([C.range[1],s.range[0]]," "),message:"Type should be on the same line as colon in type annotation",node:s})},TSTypeParameterInstantiation(I){let C=t.getFirstToken(I),y=t.getLastToken(I);if(!C||!y||C.value!=="<"||y.value!==">")return;let s=I.params[0],g=s&&C.loc.end.line===y.loc.start.line;if(s&&g){let o=t.getText().slice(C.range[1],s.range[0]);o.trim()===""&&o!==""&&e.report({fix:n=>n.removeRange([C.range[1],s.range[0]]),message:"No space allowed after < in generic type",node:C})}let i=I.params[I.params.length-1];if(i&&g){let o=t.getText().slice(i.range[1],y.range[0]);o.trim()===""&&o!==""&&e.report({fix:n=>n.removeRange([i.range[1],y.range[0]]),message:"No space allowed before > in generic type",node:y})}let r=I.params;if(r.length===1){let o=r[0];if(C.loc.end.line!==y.loc.start.line){let f=t.getText(o).trim(),l=f.endsWith(",")?f.slice(0,-1):f;e.report({fix:a=>a.replaceTextRange([C.range[1],y.range[0]],l),message:"Single generic type parameter should be inline",node:I});return}let h=t.getText(o);if(h.trimEnd().endsWith(",")){let f=h.lastIndexOf(",");e.report({fix:l=>l.removeRange([o.range[0]+f,o.range[0]+f+1]),message:"Single generic type parameter should not have trailing comma",node:o});return}}else if(r.length>=2){if(t.getText().slice(C.range[0],y.range[1]).length<=80&&C.loc.start.line===y.loc.end.line)return;let h=t.lines[I.loc.start.line-1].match(/^\s*/)[0],f=h+" ",l=s.loc.start.line>C.loc.end.line,a=y.loc.start.line>i.loc.end.line,u=!l||!a;if(!u){for(let T=1;T<r.length;T++)if(r[T].loc.start.line===r[T-1].loc.end.line){u=!0;break}}if(!u){for(let T=0;T<r.length-1;T++){let x=t.getTokenAfter(r[T]);if(!x||x.value!==","){u=!0;break}}if(!u){let T=t.getTokenAfter(i);T&&T.value===","&&(u=!0)}}if(u){let T=r.map((x,b)=>{let d=t.getText(x).trim(),E=b<r.length-1?",":"";return f+d+E}).join(`
|
|
253
253
|
`);e.report({fix:x=>x.replaceTextRange([C.range[1],y.range[0]],`
|
|
254
|
-
`+
|
|
255
|
-
`+h),message:"Generic type parameters should each be on their own line",node:I});return}}I.params.forEach(o=>{if(o.type==="TSTypeLiteral"&&o.members&&o.members.length>0){let n=t.getFirstToken(o),h=t.getLastToken(o);if(!n||!h||n.value!=="{"||h.value!=="}")return;let f=o.members,
|
|
256
|
-
`,I.range[0])+1,
|
|
257
|
-
${f.map(S=>{let k=t.getText(S).trim();return k.endsWith(";")?k=k.slice(0,-1)+",":k.endsWith(",")||(k+=","),
|
|
254
|
+
`+T+`
|
|
255
|
+
`+h),message:"Generic type parameters should each be on their own line",node:I});return}}I.params.forEach(o=>{if(o.type==="TSTypeLiteral"&&o.members&&o.members.length>0){let n=t.getFirstToken(o),h=t.getLastToken(o);if(!n||!h||n.value!=="{"||h.value!=="}")return;let f=o.members,l=n.loc.start.line!==h.loc.end.line;if(f.length===1){let T=f[0],x=t.getText(T).trim(),b=x;if((x.endsWith(",")||x.endsWith(";"))&&(x=x.slice(0,-1)),l){let d=`{ ${x} }`;e.report({fix:E=>E.replaceText(o,d),message:"Single property generic type literal should be on one line",node:o});return}if(b.endsWith(",")||b.endsWith(";")){let d=`{ ${x} }`;e.report({fix:E=>E.replaceText(o,d),message:"Single property generic type literal should not have trailing punctuation",node:o})}return}if(!l){let T=t.getText().lastIndexOf(`
|
|
256
|
+
`,I.range[0])+1,b=t.getText().slice(T,I.range[0]).match(/^\s*/)[0],d=b+" ",A=`{
|
|
257
|
+
${f.map(S=>{let k=t.getText(S).trim();return k.endsWith(";")?k=k.slice(0,-1)+",":k.endsWith(",")||(k+=","),d+k}).join(`
|
|
258
258
|
`)}
|
|
259
|
-
${
|
|
260
|
-
`);return
|
|
261
|
-
`);return
|
|
262
|
-
`+" ".repeat(
|
|
263
|
-
`)){let
|
|
264
|
-
`)&&e.report({fix:
|
|
265
|
-
`,I.range[0])+1,n=t.text.slice(
|
|
266
|
-
${s.map(u=>{let
|
|
259
|
+
${b}}`;e.report({fix:S=>S.replaceText(o,A),message:"Generic type literal with 2+ properties should be multiline",node:o});return}let a=f[0],u=f[f.length-1];a&&n.loc.end.line<a.loc.start.line-1&&e.report({fix:T=>{let b=t.text.slice(n.range[1],a.range[0]).replace(/\n\s*\n/,`
|
|
260
|
+
`);return T.replaceTextRange([n.range[1],a.range[0]],b)},message:"No empty line allowed after opening brace in generic type literal",node:n}),u&&u.loc.end.line<h.loc.start.line-1&&e.report({fix:T=>{let b=t.text.slice(u.range[1],h.range[0]).replace(/\n\s*\n/,`
|
|
261
|
+
`);return T.replaceTextRange([u.range[1],h.range[0]],b)},message:"No empty line allowed before closing brace in generic type literal",node:h}),f.forEach((T,x)=>{let b=t.getText(T);if(b.trimEnd().endsWith(";")){let d=b.lastIndexOf(";");e.report({fix:E=>E.replaceTextRange([T.range[0]+d,T.range[0]+d+1],","),message:"Type properties must end with comma (,) not semicolon (;)",node:T})}else x===f.length-1&&!b.trimEnd().endsWith(",")&&e.report({fix:d=>d.insertTextAfter(T,","),message:"Last property in generic type literal should have trailing comma",node:T});if(x<f.length-1){let d=f[x+1];d.loc.start.line-T.loc.end.line>1&&e.report({fix:E=>E.replaceTextRange([T.range[1],d.range[0]],`
|
|
262
|
+
`+" ".repeat(d.loc.start.column)),message:"No empty lines between type properties in generic",node:d})}})}});let c=I.parent;if(c&&c.type==="CallExpression"&&c.typeArguments===I){let o=c.arguments;if(o&&o.length>0){let n=t.getTokenAfter(y,h=>h.value==="(");if(n&&(y.loc.end.line!==n.loc.start.line&&e.report({fix:h=>h.replaceTextRange([y.range[1],n.range[0]],""),message:"Opening parenthesis should be on same line as closing > in generic call",node:n}),o.length===1)){let h=o[0];if(h&&(h.type==="ObjectExpression"||h.type==="ArrayExpression")){let f=t.getFirstToken(h);f&&n.loc.end.line!==f.loc.start.line&&e.report({fix:u=>u.replaceTextRange([n.range[1],f.range[0]],""),message:"First argument should be on same line as opening parenthesis in generic call",node:h});let l=t.getLastToken(h),a=t.getTokenAfter(h,u=>u.value===")");if(l&&a){let u=t.text.slice(l.range[1],a.range[0]);if(u.includes(`
|
|
263
|
+
`)){let T=u.trim()===",";e.report({fix:x=>T?x.replaceTextRange([l.range[1],a.range[0]],""):x.replaceTextRange([l.range[1],a.range[0]],""),message:"Closing parenthesis should be on same line as closing brace in generic call",node:a})}}}}}}},VariableDeclaration(I){let C=t.getLastToken(I);if(C&&C.value===";"){let y=t.getTokenBefore(C);y&&C.loc.start.line>y.loc.end.line&&e.report({fix:s=>s.replaceTextRange([y.range[1],C.range[1]],";"),message:"Semicolon should be on the same line as statement",node:C})}},TSFunctionType(I){let C=t.getTokens(I),y=C.find(i=>i.value==="=>");if(y){let i=t.getTokenAfter(y);if(i){let r=t.text.slice(y.range[1],i.range[0]);r===""?e.report({fix:c=>c.insertTextAfter(y," "),message:"Missing space after => in function type",node:y}):r!==" "&&!r.includes(`
|
|
264
|
+
`)&&e.report({fix:c=>c.replaceTextRange([y.range[1],i.range[0]]," "),message:"Should have exactly one space after => in function type",node:y})}}let s=I.params,g=C.find(i=>i.value==="(");if(g&&y){let i=t.getTokenBefore(y,r=>r.value===")");if(i){let r=g.loc.start.line!==i.loc.end.line;if(s&&s.length>=3&&!r){let c=t.text.lastIndexOf(`
|
|
265
|
+
`,I.range[0])+1,n=t.text.slice(c,I.range[0]).match(/^(\s*)/),h=n?n[1]:"",f=h+" ",a=`(
|
|
266
|
+
${s.map(u=>{let T=t.getText(u);return f+T}).join(`,
|
|
267
267
|
`)},
|
|
268
|
-
${h})`;e.report({fix:u=>u.replaceTextRange([g.range[0],i.range[1]],a),message:"Function type with 3+ parameters should have each parameter on its own line",node:I})}else if(s&&s.length<=2&&r){let o=`(${s.map(n=>t.getText(n).trim()).join(", ")})`;e.report({fix:n=>n.replaceTextRange([g.range[0],i.range[1]],o),message:"Function type with 2 or fewer parameters should be on one line",node:I})}}}},VariableDeclarator(I){if(I.id&&I.id.typeAnnotation){let C=I.id.typeAnnotation.typeAnnotation;if(C&&C.type==="TSTypeReference"&&C.typeArguments){let y=C.typeName,s=C.typeArguments;t.getText().slice(y.range[1],s.range[0])!==""&&e.report({fix:i=>i.removeRange([y.range[1],s.range[0]]),message:"No space allowed between type name and generic parameters",node:s})}}}}},meta:{docs:{description:"Enforce proper spacing in TypeScript type annotations"},fixable:"whitespace",schema:[],type:"layout"}},Wt={create(e){let t=e.sourceCode||e.getSourceCode(),I=/^[A-Z][a-zA-Z0-9]*$/,C=/^[A-Z][A-Z0-9_]*$/;return{TSEnumDeclaration(y){let s=y.id.name;I.test(s)?s.endsWith("Enum")||e.report({fix(a){return a.replaceText(y.id,`${s}Enum`)},message:`Enum name "${s}" must end with "Enum" suffix. Use "${s}Enum" instead of "${s}"`,node:y.id}):e.report({message:`Enum name "${s}" must be PascalCase`,node:y.id});let g=t.getTokenAfter(y.id,{filter:a=>a.value==="{"});g&&g.loc.start.line!==y.id.loc.end.line&&e.report({fix:a=>a.replaceTextRange([y.id.range[1],g.range[0]]," "),message:"Opening brace must be on the same line as enum name",node:g});let i=y.members;if(i.length===0)return;let
|
|
268
|
+
${h})`;e.report({fix:u=>u.replaceTextRange([g.range[0],i.range[1]],a),message:"Function type with 3+ parameters should have each parameter on its own line",node:I})}else if(s&&s.length<=2&&r){let o=`(${s.map(n=>t.getText(n).trim()).join(", ")})`;e.report({fix:n=>n.replaceTextRange([g.range[0],i.range[1]],o),message:"Function type with 2 or fewer parameters should be on one line",node:I})}}}},VariableDeclarator(I){if(I.id&&I.id.typeAnnotation){let C=I.id.typeAnnotation.typeAnnotation;if(C&&C.type==="TSTypeReference"&&C.typeArguments){let y=C.typeName,s=C.typeArguments;t.getText().slice(y.range[1],s.range[0])!==""&&e.report({fix:i=>i.removeRange([y.range[1],s.range[0]]),message:"No space allowed between type name and generic parameters",node:s})}}}}},meta:{docs:{description:"Enforce proper spacing in TypeScript type annotations"},fixable:"whitespace",schema:[],type:"layout"}},Wt={create(e){let t=e.sourceCode||e.getSourceCode(),I=/^[A-Z][a-zA-Z0-9]*$/,C=/^[A-Z][A-Z0-9_]*$/;return{TSEnumDeclaration(y){let s=y.id.name;I.test(s)?s.endsWith("Enum")||e.report({fix(a){return a.replaceText(y.id,`${s}Enum`)},message:`Enum name "${s}" must end with "Enum" suffix. Use "${s}Enum" instead of "${s}"`,node:y.id}):e.report({message:`Enum name "${s}" must be PascalCase`,node:y.id});let g=t.getTokenAfter(y.id,{filter:a=>a.value==="{"});g&&g.loc.start.line!==y.id.loc.end.line&&e.report({fix:a=>a.replaceTextRange([y.id.range[1],g.range[0]]," "),message:"Opening brace must be on the same line as enum name",node:g});let i=y.members;if(i.length===0)return;let c=t.lines[y.loc.start.line-1].match(/^\s*/)[0],o=c+" ",n=t.getLastToken(y),h=i[0];g&&h.loc.start.line-g.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([g.range[1],h.range[0]],`
|
|
269
269
|
`+o),message:"No empty line after opening brace in enum",node:h});let f=i[i.length-1];if(n&&n.loc.start.line-f.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([f.range[1],n.range[0]],`
|
|
270
|
-
`+
|
|
271
|
-
`+o),message:"First enum member must be on a new line when there are multiple members",node:h});let
|
|
272
|
-
`+o)},message:"Each enum member must be on its own line when there are multiple members",node:a}),a.loc.start.line-x.loc.end.line>1&&e.report({fix(
|
|
273
|
-
`);return
|
|
274
|
-
`+
|
|
275
|
-
`+
|
|
276
|
-
`+
|
|
277
|
-
`+n),message:"No empty line after opening brace in interface",node:f});let
|
|
278
|
-
`+o),message:"No empty line before closing brace in interface",node:
|
|
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
|
|
280
|
-
`+n)},message:"Each interface property must be on its own line when there are multiple properties",node:a}),a.loc.start.line-x.loc.end.line>1&&e.report({fix(
|
|
281
|
-
`);return
|
|
282
|
-
`+o),message:"Last interface property must end with comma and closing brace must be on its own line",node:
|
|
283
|
-
`+o),message:"Last interface property must have trailing comma and closing brace must be on its own line",node:
|
|
284
|
-
`+o),message:"Closing brace must be on its own line",node:h}):e.report({fix:E=>E.insertTextAfter(
|
|
270
|
+
`+c),message:"No empty line before closing brace in enum",node:f}),i.length===1){let a=i[0],u=t.getText(a);if(g.loc.end.line!==n.loc.start.line){let x=u.trim();x.endsWith(",")&&(x=x.slice(0,-1));let b=`{ ${x} }`;e.report({fix:d=>d.replaceTextRange([g.range[0],n.range[1]],b),message:"Single member enum should be on one line without trailing comma",node:y});return}if(u.trimEnd().endsWith(",")){let x=u.lastIndexOf(",");e.report({fix:b=>b.removeRange([a.range[0]+x,a.range[0]+x+1]),message:"Single member enum should not have trailing comma",node:a})}return}g&&h.loc.start.line===g.loc.end.line&&e.report({fix:a=>a.replaceTextRange([g.range[1],h.range[0]],`
|
|
271
|
+
`+o),message:"First enum member must be on a new line when there are multiple members",node:h});let l=a=>a.replace(/([a-z0-9])([A-Z])/g,"$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").toUpperCase();if(i.forEach((a,u)=>{if(a.id&&a.id.type==="Identifier"){let x=a.id.name;if(!C.test(x)){let b=l(x);e.report({fix:d=>d.replaceText(a.id,b),message:`Enum member "${x}" must be UPPER_CASE (e.g., ${b})`,node:a.id})}}if(!(u===i.length-1)||i.length===1){let x=t.getText(a);x.trimEnd().endsWith(";")&&e.report({fix(b){let d=x.lastIndexOf(";"),E=a.range[0]+d;return b.replaceTextRange([E,E+1],",")},message:"Enum members must end with comma (,) not semicolon (;)",node:a})}if(i.length>1&&u>0){let x=i[u-1];a.loc.start.line===x.loc.end.line&&e.report({fix:b=>{let d=t.getTokenAfter(x);for(;d&&d.value!==","&&d.range[0]<a.range[0];)d=t.getTokenAfter(d);let E=d&&d.value===","?d.range[1]:x.range[1];return b.replaceTextRange([E,a.range[0]],`
|
|
272
|
+
`+o)},message:"Each enum member must be on its own line when there are multiple members",node:a}),a.loc.start.line-x.loc.end.line>1&&e.report({fix(b){let E=t.getText().slice(x.range[1],a.range[0]).replace(/\n\s*\n/g,`
|
|
273
|
+
`);return b.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(),T=t.getTokenAfter(f),x=u.endsWith(",")||T&&T.value===",",b=u.endsWith(";"),d=n&&n.loc.start.line===f.loc.end.line;if(b){let E=a.lastIndexOf(";"),A=f.range[0]+E;d?e.report({fix:S=>S.replaceTextRange([A,n.range[0]],`,
|
|
274
|
+
`+c),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&&d?e.report({fix:E=>E.replaceTextRange([f.range[1],n.range[0]],`,
|
|
275
|
+
`+c),message:"Last enum member must have trailing comma and closing brace must be on its own line",node:f}):x?d&&e.report({fix:E=>E.replaceTextRange([f.range[1],n.range[0]],`
|
|
276
|
+
`+c),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]],`
|
|
277
|
+
`+n),message:"No empty line after opening brace in interface",node:f});let l=r[r.length-1];if(h.loc.start.line-l.loc.end.line>1&&e.report({fix:a=>a.replaceTextRange([l.range[1],h.range[0]],`
|
|
278
|
+
`+o),message:"No empty line before closing brace in interface",node:l}),r.length===1){let a=r[0],u=i.loc.end.line!==h.loc.start.line,T=a.typeAnnotation?.typeAnnotation,x=T?.type==="TSTypeLiteral",b=x&&T.members?.length>=2,d=x&&T.members?.length===1,E=T?.type==="TSFunctionType"&&T.loc.start.line!==T.loc.end.line;if(u&&!b&&!E){let S;if(d){let $=T.members[0],v=t.getText($).trim();(v.endsWith(",")||v.endsWith(";"))&&(v=v.slice(0,-1));let p=a.key.name,m=a.optional?"?":"";S=`${p}${m}: { ${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]],`
|
|
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 b=y(x);e.report({fix:d=>d.replaceText(a.key,b),message:`Interface property "${x}" must be camelCase. Use "${b}" 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 b=t.getFirstToken(x),d=t.getLastToken(x);if(b.loc.end.line!==d.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([b.range[0],d.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),b=t.getTokenAfter(x);b&&b.value==="?"&&t.getText().slice(x.range[1],b.range[0])!==""&&e.report({fix:E=>E.replaceTextRange([x.range[1],b.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(b){let d=x.lastIndexOf(";"),E=a.range[0]+d;return b.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:b=>{let d=t.getTokenAfter(x);for(;d&&d.value!==","&&d.range[0]<a.range[0];)d=t.getTokenAfter(d);let E=d&&d.value===","?d.range[1]:x.range[1];return b.replaceTextRange([E,a.range[0]],`
|
|
280
|
+
`+n)},message:"Each interface property must be on its own line when there are multiple properties",node:a}),a.loc.start.line-x.loc.end.line>1&&e.report({fix(b){let E=t.getText().slice(x.range[1],a.range[0]).replace(/\n\s*\n/g,`
|
|
281
|
+
`);return b.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(l),u=a.trimEnd(),T=t.getTokenAfter(l),x=u.endsWith(",")||T&&T.value===",",b=u.endsWith(";"),d=h.loc.start.line===l.loc.end.line;if(b){let E=a.lastIndexOf(";"),A=l.range[0]+E;d?e.report({fix:S=>S.replaceTextRange([A,h.range[0]],`,
|
|
282
|
+
`+o),message:"Last interface property must end with comma and closing brace must be on its own line",node:l}):e.report({fix:S=>S.replaceTextRange([A,A+1],","),message:"Interface properties must end with comma (,) not semicolon (;)",node:l})}else!x&&d?e.report({fix:E=>E.replaceTextRange([l.range[1],h.range[0]],`,
|
|
283
|
+
`+o),message:"Last interface property must have trailing comma and closing brace must be on its own line",node:l}):x?d&&e.report({fix:E=>E.replaceTextRange([l.range[1],h.range[0]],`
|
|
284
|
+
`+o),message:"Closing brace must be on its own line",node:h}):e.report({fix:E=>E.insertTextAfter(l,","),message:"Last interface property must have trailing comma",node:l})}}}},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=d=>/^[A-Z][A-Z0-9_]*$/.test(d)?d.toLowerCase().replace(/_([a-z0-9])/g,(E,A)=>A.toUpperCase()):/_/.test(d)?d.toLowerCase().replace(/_([a-z0-9])/g,(E,A)=>A.toUpperCase()):/^[A-Z]/.test(d)?d[0].toLowerCase()+d.slice(1):d,i=d=>{let A=(t.getScope?t.getScope(d):e.getScope()).variables.find(S=>S.name===d.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"],c=d=>{if(!d||d.type!=="CallExpression")return!1;let{callee:E}=d;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=d=>{if(d.type!=="CallExpression")return!1;let{callee:E}=d;return E.type==="Identifier"&&E.name==="styled"},n=d=>{if(!d)return!1;if(d.type==="ArrowFunctionExpression"||d.type==="FunctionExpression")return!0;if(d.type==="CallExpression"&&d.callee){let E=d.callee.name||d.callee.property&&d.callee.property.name;return["memo","forwardRef","lazy","createContext"].includes(E)}return!1},h=d=>{if(!d.init)return!1;let E=d.id.name;if(/^[A-Z]/.test(E)&&n(d.init)||/^[A-Z]/.test(E)&&d.init.type==="MemberExpression"&&d.init.object.type==="Identifier"&&/^[A-Z]/.test(d.init.object.name))return!0;if(/^[A-Z]/.test(E)&&d.init.type==="ConditionalExpression"){let{consequent:A,alternate:S}=d.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=d=>{if(!d.init)return!1;let E=d.id.name;return E.startsWith("use")&&/^use[A-Z]/.test(E)&&n(d.init)},l=["Icon","Component","FormComponent","Layout","Wrapper","Container","Provider"],a=(d,E)=>{if(d.type==="Identifier"){let A=d.name;if(A.startsWith("_")||s.test(A)||r.includes(A)||l.includes(A))return;I.test(A)||e.report({message:`${E} "${A}" should be camelCase`,node:d})}else d.type==="ObjectPattern"?d.properties.forEach(A=>{A.type==="Property"?a(A.value,E):A.type==="RestElement"&&a(A.argument,E)}):d.type==="ArrayPattern"?d.elements.forEach(A=>{A&&a(A,E)}):d.type==="AssignmentPattern"?a(d.left,E):d.type==="RestElement"&&a(d.argument,E)},u=d=>{if(d.id.type!=="Identifier"){a(d.id,"Variable");return}let E=d.id.name;if(c(d.init)){C.test(E)||e.report({message:`Styled component "${E}" should be PascalCase (e.g., StyledCard instead of styledCard)`,node:d.id});return}if(E.startsWith("_")||h(d))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(d)){y.test(E)||e.report({message:`Hook "${E}" should start with "use" followed by PascalCase (e.g., useEventsList)`,node:d.id});return}if(!([/^[A-Z][a-zA-Z]*Data$/,/^[A-Z][a-zA-Z]*Config$/,/^Routes$/].some(k=>k.test(E))&&d.init&&(d.init.type==="ArrayExpression"||d.init.type==="ObjectExpression"||d.init.type==="CallExpression"))&&!I.test(E)){let k=g(E),$=i(d.id);e.report({fix:v=>{let p=[];return $.forEach(m=>{p.push(v.replaceText(m,k))}),p},message:`Variable "${E}" should be camelCase (e.g., ${k} instead of ${E})`,node:d.id})}},T=d=>{if(d.computed||d.key.type!=="Identifier")return;let E=d.key.name;if(!(E.startsWith("_")||r.includes(E))){if(d.value&&d.value.type==="Identifier"){let A=d.value.name;if(C.test(A)&&C.test(E))return}if(!l.includes(E)&&!E.startsWith("Mui")&&!I.test(E)){let A=g(E);e.report({fix:S=>S.replaceText(d.key,A),message:`Property "${E}" should be camelCase (e.g., ${A} instead of ${E})`,node:d.key})}}},x=d=>{d.params.forEach(E=>a(E,"Parameter"))};return{ArrowFunctionExpression:x,CallExpression:d=>{o(d)||d.arguments.forEach(E=>{if(E.type==="Identifier"){let A=E.name;if(A.startsWith("_")||s.test(A)||r.includes(A)||l.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=[],m=new Set;return v.references.forEach(w=>{let L=`${w.identifier.range[0]}-${w.identifier.range[1]}`;m.has(L)||(m.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:T,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.18"},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};
|