@nfq/eslint-config 4.0.0-beta.3 → 4.0.0-beta.5

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.
@@ -135,7 +135,31 @@ const stylistic = {
135
135
  overrides: {}
136
136
  }],
137
137
  '@stylistic/object-curly-newline': ['error', {
138
- multiline: true
138
+ ExportDeclaration: {
139
+ minProperties: 2,
140
+ multiline: true
141
+ },
142
+ ImportDeclaration: {
143
+ minProperties: 2,
144
+ multiline: true
145
+ },
146
+ ObjectExpression: {
147
+ minProperties: 2,
148
+ multiline: true
149
+ },
150
+ ObjectPattern: {
151
+ minProperties: 2,
152
+ multiline: true
153
+ },
154
+ TSEnumBody: {
155
+ consistent: true
156
+ },
157
+ TSInterfaceBody: {
158
+ consistent: true
159
+ },
160
+ TSTypeLiteral: {
161
+ consistent: true
162
+ }
139
163
  }],
140
164
  '@stylistic/object-curly-spacing': ['error', 'never'],
141
165
  '@stylistic/object-property-newline': 'off',
@@ -1 +1 @@
1
- {"version":3,"file":"stylistic.js","sources":["../../../../../src/rules/common/plugins/stylistic.ts"],"sourcesContent":["export const stylistic = {\n '@stylistic/array-bracket-newline': ['error', 'consistent'],\n '@stylistic/array-bracket-spacing': ['error', 'never'],\n '@stylistic/array-element-newline': ['error', 'consistent'],\n '@stylistic/arrow-parens': ['error', 'as-needed'],\n '@stylistic/arrow-spacing': ['error', {\n after: true,\n before: true\n }],\n '@stylistic/block-spacing': ['error', 'never'],\n '@stylistic/brace-style': ['error', '1tbs', {allowSingleLine: false}],\n '@stylistic/comma-dangle': ['error', 'never'],\n '@stylistic/comma-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/comma-style': [\n 'error',\n 'last',\n {\n exceptions: {\n ArrayExpression: false,\n ArrayPattern: false,\n ArrowFunctionExpression: false,\n CallExpression: false,\n FunctionDeclaration: false,\n FunctionExpression: false,\n ImportDeclaration: false,\n NewExpression: false,\n ObjectExpression: false,\n ObjectPattern: false,\n VariableDeclaration: false\n }\n }\n ],\n '@stylistic/computed-property-spacing': ['error', 'never'],\n '@stylistic/dot-location': ['error', 'property'],\n '@stylistic/eol-last': ['error', 'never'],\n '@stylistic/function-call-argument-newline': ['error', 'consistent'],\n '@stylistic/function-call-spacing': ['error', 'never'],\n '@stylistic/function-paren-newline': ['error', 'consistent'],\n '@stylistic/generator-star-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/implicit-arrow-linebreak': ['error', 'beside'],\n '@stylistic/indent': [\n 'error',\n 4,\n {\n ArrayExpression: 'first',\n CallExpression: {arguments: 'first'},\n flatTernaryExpressions: false,\n FunctionDeclaration: {\n body: 1,\n parameters: 'first'\n },\n FunctionExpression: {\n body: 1,\n parameters: 'first'\n },\n ignoreComments: false,\n ignoredNodes: [\n 'JSXElement',\n 'JSXElement > *',\n 'JSXAttribute',\n 'JSXIdentifier',\n 'JSXNamespacedName',\n 'JSXMemberExpression',\n 'JSXSpreadAttribute',\n 'JSXExpressionContainer',\n 'JSXOpeningElement',\n 'JSXClosingElement',\n 'JSXFragment',\n 'JSXOpeningFragment',\n 'JSXClosingFragment',\n 'JSXText',\n 'JSXEmptyExpression',\n 'JSXSpreadChild'\n ],\n ImportDeclaration: 'first',\n ObjectExpression: 'first',\n outerIIFEBody: 1,\n SwitchCase: 1,\n VariableDeclarator: 'first'\n }\n ],\n '@stylistic/indent-binary-ops': ['error', 4],\n '@stylistic/jsx-quotes': ['error', 'prefer-double'],\n '@stylistic/key-spacing': [\n 'error',\n {\n afterColon: true,\n beforeColon: false,\n mode: 'minimum'\n }\n ],\n '@stylistic/keyword-spacing': ['error', {\n after: true,\n before: true\n }],\n '@stylistic/line-comment-position': [\n 'off',\n {\n applyDefaultPatterns: true,\n ignorePattern: '',\n position: 'above'\n }\n ],\n '@stylistic/linebreak-style': ['error', 'unix'],\n '@stylistic/lines-around-comment': 'off',\n '@stylistic/lines-between-class-members': [\n 'error',\n 'always',\n {exceptAfterSingleLine: false}\n ],\n '@stylistic/max-len': [\n 'error',\n {\n code: 120,\n ignoreComments: true,\n ignoreRegExpLiterals: true,\n ignoreTemplateLiterals: true,\n ignoreUrls: true\n }\n ],\n '@stylistic/max-statements-per-line': ['error', {max: 1}],\n '@stylistic/member-delimiter-style': [\n 'error',\n {\n multiline: {\n delimiter: 'semi',\n requireLast: true\n },\n multilineDetection: 'brackets',\n singleline: {\n delimiter: 'semi',\n requireLast: false\n }\n }\n ],\n '@stylistic/multiline-ternary': ['off', 'never'],\n '@stylistic/new-parens': ['error', 'always'],\n '@stylistic/newline-per-chained-call': ['error', {ignoreChainWithDepth: 4}],\n '@stylistic/no-confusing-arrow': ['error', {allowParens: true}],\n '@stylistic/no-extra-parens': 'off',\n '@stylistic/no-extra-semi': 'error',\n '@stylistic/no-floating-decimal': 'error',\n '@stylistic/no-mixed-operators': [\n 'error',\n {\n allowSamePrecedence: false,\n groups: [\n ['%', '**'],\n ['%', '+'],\n ['%', '-'],\n ['%', '*'],\n ['%', '/'],\n ['/', '*'],\n ['&', '|', '<<', '>>', '>>>'],\n ['==', '!=', '===', '!=='],\n ['&&', '||']\n ]\n }\n ],\n '@stylistic/no-mixed-spaces-and-tabs': 'error',\n '@stylistic/no-multi-spaces': 'error',\n '@stylistic/no-multiple-empty-lines': ['error', {\n max: 1,\n maxBOF: 0,\n maxEOF: 0\n }],\n '@stylistic/no-tabs': 'error',\n '@stylistic/no-trailing-spaces': 'error',\n '@stylistic/no-whitespace-before-property': 'error',\n '@stylistic/nonblock-statement-body-position': ['error', 'beside', {overrides: {}}],\n '@stylistic/object-curly-newline': ['error', {multiline: true}],\n '@stylistic/object-curly-spacing': ['error', 'never'],\n '@stylistic/object-property-newline': 'off',\n '@stylistic/one-var-declaration-per-line': ['error', 'always'],\n '@stylistic/operator-linebreak': ['error', 'before'],\n '@stylistic/padded-blocks': ['error', 'never'],\n '@stylistic/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: '*',\n prev: ['const', 'let', 'var']\n },\n {\n blankLine: 'any',\n next: ['const', 'let', 'var'],\n prev: ['const', 'let', 'var']\n },\n {\n blankLine: 'always',\n next: '*',\n prev: 'directive'\n },\n {\n blankLine: 'any',\n next: 'directive',\n prev: 'directive'\n },\n {\n blankLine: 'always',\n next: 'return',\n prev: '*'\n }\n ],\n '@stylistic/quote-props': [\n 'error',\n 'as-needed',\n {\n keywords: false,\n numbers: false,\n unnecessary: true\n }\n ],\n '@stylistic/quotes': ['error', 'single', {avoidEscape: true}],\n '@stylistic/rest-spread-spacing': ['error', 'never'],\n '@stylistic/semi': ['error', 'always'],\n '@stylistic/semi-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/semi-style': ['error', 'last'],\n '@stylistic/space-before-blocks': ['error', 'always'],\n '@stylistic/space-before-function-paren': [\n 'error',\n {\n anonymous: 'never',\n asyncArrow: 'always',\n named: 'never'\n }\n ],\n '@stylistic/space-in-parens': ['error', 'never'],\n '@stylistic/space-infix-ops': 'error',\n '@stylistic/space-unary-ops': [\n 'error',\n {\n nonwords: false,\n overrides: {},\n words: true\n }\n ],\n '@stylistic/spaced-comment': [\n 'error',\n 'always',\n {\n block: {\n balanced: true,\n exceptions: ['-', '+'],\n markers: ['=', '!', ':', '::']\n },\n line: {\n exceptions: ['-', '+'],\n markers: ['=', '!', '/']\n }\n }\n ],\n '@stylistic/switch-colon-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/template-curly-spacing': ['error', 'never'],\n '@stylistic/template-tag-spacing': ['error', 'never'],\n '@stylistic/type-annotation-spacing': 'error',\n '@stylistic/type-generic-spacing': 'error',\n '@stylistic/type-named-tuple-spacing': 'error',\n '@stylistic/wrap-iife': ['error', 'outside', {functionPrototypeMethods: false}],\n '@stylistic/wrap-regex': 'error',\n '@stylistic/yield-star-spacing': ['error', 'after']\n};"],"names":["stylistic","after","before","allowSingleLine","exceptions","ArrayExpression","ArrayPattern","ArrowFunctionExpression","CallExpression","FunctionDeclaration","FunctionExpression","ImportDeclaration","NewExpression","ObjectExpression","ObjectPattern","VariableDeclaration","arguments","flatTernaryExpressions","body","parameters","ignoreComments","ignoredNodes","outerIIFEBody","SwitchCase","VariableDeclarator","afterColon","beforeColon","mode","applyDefaultPatterns","ignorePattern","position","exceptAfterSingleLine","code","ignoreRegExpLiterals","ignoreTemplateLiterals","ignoreUrls","max","multiline","delimiter","requireLast","multilineDetection","singleline","ignoreChainWithDepth","allowParens","allowSamePrecedence","groups","maxBOF","maxEOF","overrides","blankLine","next","prev","keywords","numbers","unnecessary","avoidEscape","anonymous","asyncArrow","named","nonwords","words","block","balanced","markers","line","functionPrototypeMethods"],"mappings":"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"}
1
+ {"version":3,"file":"stylistic.js","sources":["../../../../../src/rules/common/plugins/stylistic.ts"],"sourcesContent":["export const stylistic = {\n '@stylistic/array-bracket-newline': ['error', 'consistent'],\n '@stylistic/array-bracket-spacing': ['error', 'never'],\n '@stylistic/array-element-newline': ['error', 'consistent'],\n '@stylistic/arrow-parens': ['error', 'as-needed'],\n '@stylistic/arrow-spacing': ['error', {\n after: true,\n before: true\n }],\n '@stylistic/block-spacing': ['error', 'never'],\n '@stylistic/brace-style': ['error', '1tbs', {allowSingleLine: false}],\n '@stylistic/comma-dangle': ['error', 'never'],\n '@stylistic/comma-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/comma-style': [\n 'error',\n 'last',\n {\n exceptions: {\n ArrayExpression: false,\n ArrayPattern: false,\n ArrowFunctionExpression: false,\n CallExpression: false,\n FunctionDeclaration: false,\n FunctionExpression: false,\n ImportDeclaration: false,\n NewExpression: false,\n ObjectExpression: false,\n ObjectPattern: false,\n VariableDeclaration: false\n }\n }\n ],\n '@stylistic/computed-property-spacing': ['error', 'never'],\n '@stylistic/dot-location': ['error', 'property'],\n '@stylistic/eol-last': ['error', 'never'],\n '@stylistic/function-call-argument-newline': ['error', 'consistent'],\n '@stylistic/function-call-spacing': ['error', 'never'],\n '@stylistic/function-paren-newline': ['error', 'consistent'],\n '@stylistic/generator-star-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/implicit-arrow-linebreak': ['error', 'beside'],\n '@stylistic/indent': [\n 'error',\n 4,\n {\n ArrayExpression: 'first',\n CallExpression: {arguments: 'first'},\n flatTernaryExpressions: false,\n FunctionDeclaration: {\n body: 1,\n parameters: 'first'\n },\n FunctionExpression: {\n body: 1,\n parameters: 'first'\n },\n ignoreComments: false,\n ignoredNodes: [\n 'JSXElement',\n 'JSXElement > *',\n 'JSXAttribute',\n 'JSXIdentifier',\n 'JSXNamespacedName',\n 'JSXMemberExpression',\n 'JSXSpreadAttribute',\n 'JSXExpressionContainer',\n 'JSXOpeningElement',\n 'JSXClosingElement',\n 'JSXFragment',\n 'JSXOpeningFragment',\n 'JSXClosingFragment',\n 'JSXText',\n 'JSXEmptyExpression',\n 'JSXSpreadChild'\n ],\n ImportDeclaration: 'first',\n ObjectExpression: 'first',\n outerIIFEBody: 1,\n SwitchCase: 1,\n VariableDeclarator: 'first'\n }\n ],\n '@stylistic/indent-binary-ops': ['error', 4],\n '@stylistic/jsx-quotes': ['error', 'prefer-double'],\n '@stylistic/key-spacing': [\n 'error',\n {\n afterColon: true,\n beforeColon: false,\n mode: 'minimum'\n }\n ],\n '@stylistic/keyword-spacing': ['error', {\n after: true,\n before: true\n }],\n '@stylistic/line-comment-position': [\n 'off',\n {\n applyDefaultPatterns: true,\n ignorePattern: '',\n position: 'above'\n }\n ],\n '@stylistic/linebreak-style': ['error', 'unix'],\n '@stylistic/lines-around-comment': 'off',\n '@stylistic/lines-between-class-members': [\n 'error',\n 'always',\n {exceptAfterSingleLine: false}\n ],\n '@stylistic/max-len': [\n 'error',\n {\n code: 120,\n ignoreComments: true,\n ignoreRegExpLiterals: true,\n ignoreTemplateLiterals: true,\n ignoreUrls: true\n }\n ],\n '@stylistic/max-statements-per-line': ['error', {max: 1}],\n '@stylistic/member-delimiter-style': [\n 'error',\n {\n multiline: {\n delimiter: 'semi',\n requireLast: true\n },\n multilineDetection: 'brackets',\n singleline: {\n delimiter: 'semi',\n requireLast: false\n }\n }\n ],\n '@stylistic/multiline-ternary': ['off', 'never'],\n '@stylistic/new-parens': ['error', 'always'],\n '@stylistic/newline-per-chained-call': ['error', {ignoreChainWithDepth: 4}],\n '@stylistic/no-confusing-arrow': ['error', {allowParens: true}],\n '@stylistic/no-extra-parens': 'off',\n '@stylistic/no-extra-semi': 'error',\n '@stylistic/no-floating-decimal': 'error',\n '@stylistic/no-mixed-operators': [\n 'error',\n {\n allowSamePrecedence: false,\n groups: [\n ['%', '**'],\n ['%', '+'],\n ['%', '-'],\n ['%', '*'],\n ['%', '/'],\n ['/', '*'],\n ['&', '|', '<<', '>>', '>>>'],\n ['==', '!=', '===', '!=='],\n ['&&', '||']\n ]\n }\n ],\n '@stylistic/no-mixed-spaces-and-tabs': 'error',\n '@stylistic/no-multi-spaces': 'error',\n '@stylistic/no-multiple-empty-lines': ['error', {\n max: 1,\n maxBOF: 0,\n maxEOF: 0\n }],\n '@stylistic/no-tabs': 'error',\n '@stylistic/no-trailing-spaces': 'error',\n '@stylistic/no-whitespace-before-property': 'error',\n '@stylistic/nonblock-statement-body-position': ['error', 'beside', {overrides: {}}],\n '@stylistic/object-curly-newline': [\n 'error', {\n ExportDeclaration: {\n minProperties: 2,\n multiline: true\n },\n ImportDeclaration: {\n minProperties: 2,\n multiline: true\n },\n ObjectExpression: {\n minProperties: 2,\n multiline: true\n },\n ObjectPattern: {\n minProperties: 2,\n multiline: true\n },\n TSEnumBody: {consistent: true},\n TSInterfaceBody: {consistent: true},\n TSTypeLiteral: {consistent: true}\n }\n ],\n '@stylistic/object-curly-spacing': ['error', 'never'],\n '@stylistic/object-property-newline': 'off',\n '@stylistic/one-var-declaration-per-line': ['error', 'always'],\n '@stylistic/operator-linebreak': ['error', 'before'],\n '@stylistic/padded-blocks': ['error', 'never'],\n '@stylistic/padding-line-between-statements': [\n 'error',\n {\n blankLine: 'always',\n next: '*',\n prev: ['const', 'let', 'var']\n },\n {\n blankLine: 'any',\n next: ['const', 'let', 'var'],\n prev: ['const', 'let', 'var']\n },\n {\n blankLine: 'always',\n next: '*',\n prev: 'directive'\n },\n {\n blankLine: 'any',\n next: 'directive',\n prev: 'directive'\n },\n {\n blankLine: 'always',\n next: 'return',\n prev: '*'\n }\n ],\n '@stylistic/quote-props': [\n 'error',\n 'as-needed',\n {\n keywords: false,\n numbers: false,\n unnecessary: true\n }\n ],\n '@stylistic/quotes': ['error', 'single', {avoidEscape: true}],\n '@stylistic/rest-spread-spacing': ['error', 'never'],\n '@stylistic/semi': ['error', 'always'],\n '@stylistic/semi-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/semi-style': ['error', 'last'],\n '@stylistic/space-before-blocks': ['error', 'always'],\n '@stylistic/space-before-function-paren': [\n 'error',\n {\n anonymous: 'never',\n asyncArrow: 'always',\n named: 'never'\n }\n ],\n '@stylistic/space-in-parens': ['error', 'never'],\n '@stylistic/space-infix-ops': 'error',\n '@stylistic/space-unary-ops': [\n 'error',\n {\n nonwords: false,\n overrides: {},\n words: true\n }\n ],\n '@stylistic/spaced-comment': [\n 'error',\n 'always',\n {\n block: {\n balanced: true,\n exceptions: ['-', '+'],\n markers: ['=', '!', ':', '::']\n },\n line: {\n exceptions: ['-', '+'],\n markers: ['=', '!', '/']\n }\n }\n ],\n '@stylistic/switch-colon-spacing': ['error', {\n after: true,\n before: false\n }],\n '@stylistic/template-curly-spacing': ['error', 'never'],\n '@stylistic/template-tag-spacing': ['error', 'never'],\n '@stylistic/type-annotation-spacing': 'error',\n '@stylistic/type-generic-spacing': 'error',\n '@stylistic/type-named-tuple-spacing': 'error',\n '@stylistic/wrap-iife': ['error', 'outside', {functionPrototypeMethods: false}],\n '@stylistic/wrap-regex': 'error',\n '@stylistic/yield-star-spacing': ['error', 'after']\n};"],"names":["stylistic","after","before","allowSingleLine","exceptions","ArrayExpression","ArrayPattern","ArrowFunctionExpression","CallExpression","FunctionDeclaration","FunctionExpression","ImportDeclaration","NewExpression","ObjectExpression","ObjectPattern","VariableDeclaration","arguments","flatTernaryExpressions","body","parameters","ignoreComments","ignoredNodes","outerIIFEBody","SwitchCase","VariableDeclarator","afterColon","beforeColon","mode","applyDefaultPatterns","ignorePattern","position","exceptAfterSingleLine","code","ignoreRegExpLiterals","ignoreTemplateLiterals","ignoreUrls","max","multiline","delimiter","requireLast","multilineDetection","singleline","ignoreChainWithDepth","allowParens","allowSamePrecedence","groups","maxBOF","maxEOF","overrides","ExportDeclaration","minProperties","TSEnumBody","consistent","TSInterfaceBody","TSTypeLiteral","blankLine","next","prev","keywords","numbers","unnecessary","avoidEscape","anonymous","asyncArrow","named","nonwords","words","block","balanced","markers","line","functionPrototypeMethods"],"mappings":"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"}
@@ -1,7 +1,11 @@
1
1
  import { ESLintUtils } from '@typescript-eslint/utils';
2
- import { getComponentInfoFromStatement, getTypeDeclarationInfo, collectTypeReferences, isDisplayNameAssignment, isComponentExport, isStyledDeclaration } from './utils/component-file-structure-utils.js';
2
+ import { getComponentInfoFromStatement, getTypeDeclarationInfo, isDefaultComponentExport, collectTypeReferences, isDisplayNameAssignment, isComponentExport, isStyledDeclaration } from './utils/component-file-structure-utils.js';
3
3
 
4
4
  const createRule$b = ESLintUtils.RuleCreator(name => `https://github.com/nfqde/eslint-config-nfq/blob/master/docs/rules/${name}.md`);
5
+ const ORDER_LABELS = ['Imports', 'Optional declarations', 'Props types', 'Component', 'Component helpers and displayName', 'Exports', 'Styled components and local helper types'];
6
+ const ORDER_MESSAGE = ORDER_LABELS.join(' -> ');
7
+ const getSectionLabel = section => ORDER_LABELS[section - 1] ?? 'Unknown';
8
+ const PAGE_TYPE_NAMES = new Set(['NextPage', 'NextPageWithLayout']);
5
9
  const componentFileStructure = createRule$b({
6
10
  defaultOptions: [],
7
11
  meta: {
@@ -9,7 +13,7 @@ const componentFileStructure = createRule$b({
9
13
  description: 'Enforce file structure order for React component files.'
10
14
  },
11
15
  messages: {
12
- invalidOrder: 'This file structure block is out of order.',
16
+ invalidOrder: 'This file structure block is out of order. {{current}} appears before {{previous}}. Expected order: {{order}}.',
13
17
  missingDisplayName: 'Component {{name}} must set displayName.',
14
18
  missingNamedExport: 'Component {{name}} must be exported by name.'
15
19
  },
@@ -37,9 +41,42 @@ const componentFileStructure = createRule$b({
37
41
  }
38
42
  const propsTypeNames = new Set();
39
43
  const propsTypeRefs = new Set();
40
- const propsParam = componentInfo.functionNode.params[0];
41
- if (propsParam && 'typeAnnotation' in propsParam && propsParam.typeAnnotation) {
42
- collectTypeReferences(propsParam.typeAnnotation, propsTypeRefs);
44
+ const propsTypeNode = componentInfo.propsTypeNode ?? null;
45
+ const isPageType = () => {
46
+ const typeNode = componentInfo.componentTypeNode ?? null;
47
+ if (!typeNode) {
48
+ return false;
49
+ }
50
+ const typeRefs = new Set();
51
+ collectTypeReferences(typeNode, typeRefs);
52
+ return Array.from(typeRefs).some(name => PAGE_TYPE_NAMES.has(name));
53
+ };
54
+ const isPageLayoutAssignment = statement => {
55
+ if (statement.type !== 'ExpressionStatement') {
56
+ return false;
57
+ }
58
+ const {
59
+ expression
60
+ } = statement;
61
+ if (expression.type !== 'AssignmentExpression') {
62
+ return false;
63
+ }
64
+ const {
65
+ left
66
+ } = expression;
67
+ if (left.type !== 'MemberExpression' || left.object.type !== 'Identifier') {
68
+ return false;
69
+ }
70
+ if (left.object.name !== componentName || left.property.type !== 'Identifier') {
71
+ return false;
72
+ }
73
+ return left.property.name === 'getLayout' || left.property.name === 'getLayoutKey';
74
+ };
75
+ const hasDefaultExport = programBody.some(statement => isDefaultComponentExport(statement, componentName));
76
+ const hasLayoutAssignment = programBody.some(statement => isPageLayoutAssignment(statement));
77
+ const isPageComponent = hasDefaultExport && (hasLayoutAssignment || isPageType());
78
+ if (propsTypeNode) {
79
+ collectTypeReferences(propsTypeNode, propsTypeRefs);
43
80
  for (const name of propsTypeRefs) {
44
81
  if (typeDeclarations.has(name)) {
45
82
  propsTypeNames.add(name);
@@ -76,13 +113,16 @@ const componentFileStructure = createRule$b({
76
113
  if (isDisplayNameAssignment(statement, componentName)) {
77
114
  return 5;
78
115
  }
79
- if (isComponentExport(statement, componentName)) {
116
+ if (isComponentExport(statement, componentName) || isDefaultComponentExport(statement, componentName)) {
80
117
  return 6;
81
118
  }
82
119
  if (isStyledDeclaration(statement) || isNonPropsTypeDeclaration(statement)) {
83
120
  return 7;
84
121
  }
85
122
  if (isOptionalVarDeclaration(statement)) {
123
+ if (statement.range[0] > componentInfo.statement.range[0]) {
124
+ return 5;
125
+ }
86
126
  return 2;
87
127
  }
88
128
  if (isPropsTypeDeclaration(statement)) {
@@ -108,6 +148,11 @@ const componentFileStructure = createRule$b({
108
148
  }
109
149
  if (section < lastSection) {
110
150
  context.report({
151
+ data: {
152
+ current: getSectionLabel(section),
153
+ order: ORDER_MESSAGE,
154
+ previous: getSectionLabel(lastSection)
155
+ },
111
156
  messageId: 'invalidOrder',
112
157
  node: statement
113
158
  });
@@ -115,7 +160,7 @@ const componentFileStructure = createRule$b({
115
160
  lastSection = section;
116
161
  }
117
162
  }
118
- if (!hasDisplayName) {
163
+ if (!hasDisplayName && !isPageComponent) {
119
164
  context.report({
120
165
  data: {
121
166
  name: componentName
@@ -124,7 +169,7 @@ const componentFileStructure = createRule$b({
124
169
  node: componentInfo.statement
125
170
  });
126
171
  }
127
- if (!hasNamedExport) {
172
+ if (!hasNamedExport && !isPageComponent) {
128
173
  context.report({
129
174
  data: {
130
175
  name: componentName
@@ -1 +1 @@
1
- {"version":3,"file":"component-file-structure.js","sources":["../../../../src/rules/custom/component-file-structure.ts"],"sourcesContent":["import {ESLintUtils} from '@typescript-eslint/utils';\n\nimport {\n collectTypeReferences,\n getComponentInfoFromStatement,\n getTypeDeclarationInfo,\n isComponentExport,\n isDisplayNameAssignment,\n isStyledDeclaration\n} from './utils/component-file-structure-utils';\n\nimport type {ComponentInfo} from './utils/component-file-structure-utils';\nimport type {TSESLint, TSESTree} from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/nfqde/eslint-config-nfq/blob/master/docs/rules/${name}.md`\n);\n\ntype MessageIds = 'invalidOrder' | 'missingDisplayName' | 'missingNamedExport';\n\nexport const componentFileStructure = createRule<[], MessageIds>({\n defaultOptions: [],\n meta: {\n docs: {description: 'Enforce file structure order for React component files.'},\n messages: {\n invalidOrder: 'This file structure block is out of order.',\n missingDisplayName: 'Component {{name}} must set displayName.',\n missingNamedExport: 'Component {{name}} must be exported by name.'\n },\n schema: [],\n type: 'suggestion'\n },\n name: 'component-file-structure',\n /**\n * Creates the rule listener for enforcing component file structure ordering. It analyzes the program body to\n * identify the primary component, its props types, and structural sections. It then reports ordering issues and\n * missing requirements like displayName or named exports.\n *\n * @param context The ESLint rule context used to access source code and report diagnostics.\n * @returns A rule listener that validates component file structure and reports issues.\n *\n * @example\n * ```tsx\n * // eslint-disable-next-line @nfq/component-file-structure\n * const listener = componentFileStructure.create(context);\n * ```\n */\n create(context) {\n const {sourceCode} = context;\n const programBody = sourceCode.ast.body;\n const componentCandidates = programBody\n .filter((statement): statement is TSESTree.Statement => statement.type !== 'TSModuleDeclaration')\n .map(statement => getComponentInfoFromStatement(statement))\n .filter((info): info is ComponentInfo => Boolean(info));\n\n if (componentCandidates.length === 0) {\n return {};\n }\n\n const componentInfo = componentCandidates.sort(\n (left, right) => left.statement.range[0] - right.statement.range[0]\n )[0];\n const componentName = componentInfo.name;\n const typeDeclarations = new Map<string, TSESTree.Node>();\n\n for (const statement of programBody) {\n const info = getTypeDeclarationInfo(statement as TSESTree.Statement);\n\n if (info) {\n typeDeclarations.set(info.name, info.statement);\n }\n }\n\n const propsTypeNames = new Set<string>();\n const propsTypeRefs = new Set<string>();\n const propsParam = componentInfo.functionNode.params[0];\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (propsParam && 'typeAnnotation' in propsParam && propsParam.typeAnnotation) {\n collectTypeReferences(propsParam.typeAnnotation, propsTypeRefs);\n\n for (const name of propsTypeRefs) {\n if (typeDeclarations.has(name)) {\n propsTypeNames.add(name);\n }\n }\n }\n\n /**\n * Determines whether a statement declares a type that is used as the component props. It inspects the statement\n * for a type declaration and compares the declared name against the collected props type names. It returns a\n * boolean so callers can classify statements into the props type section.\n *\n * @param statement The statement to inspect for a props type declaration.\n * @returns True when the statement declares a props type; otherwise false.\n *\n * @example\n * ```tsx\n * const isProps = isPropsTypeDeclaration(statement);\n * ```\n */\n const isPropsTypeDeclaration = (statement: TSESTree.Statement) => {\n const info = getTypeDeclarationInfo(statement);\n\n return Boolean(info && propsTypeNames.has(info.name));\n };\n\n /**\n * Determines whether a statement declares a type that is not used as the component props. It inspects the\n * statement for a type declaration and ensures the declared name is not among the collected props type names.\n * It returns a boolean so callers can classify statements into non-props type sections.\n *\n * @param statement The statement to inspect for a non-props type declaration.\n * @returns True when the statement declares a non-props type; otherwise false.\n *\n * @example\n * ```tsx\n * const isNonProps = isNonPropsTypeDeclaration(statement);\n * ```\n */\n const isNonPropsTypeDeclaration = (statement: TSESTree.Statement) => {\n const info = getTypeDeclarationInfo(statement);\n\n return Boolean(info && !propsTypeNames.has(info.name));\n };\n\n /**\n * Determines whether a statement is an optional variable-like declaration in the component file structure. It\n * filters out the main component statement and styled declarations to avoid misclassification. It considers\n * variable declarations, non-component function declarations, and enum declarations as optional declarations.\n *\n * @param statement The statement to evaluate for optional declaration status.\n * @returns True when the statement should be treated as an optional declaration; otherwise false.\n *\n * @example\n * ```tsx\n * const isOptional = isOptionalVarDeclaration(statement);\n * ```\n */\n const isOptionalVarDeclaration = (statement: TSESTree.Statement) => {\n if (statement.type === 'VariableDeclaration') {\n if (statement === componentInfo.statement || isStyledDeclaration(statement)) {\n return false;\n }\n\n return true;\n }\n\n if (statement.type === 'FunctionDeclaration') {\n return statement !== componentInfo.statement;\n }\n\n return statement.type === 'TSEnumDeclaration';\n };\n\n /**\n * Determines the structural section number for a given statement in a component file. It checks the statement\n * against known component structure elements like imports, the main component, displayName assignment, exports,\n * styled declarations, optional declarations, and props types. It returns a numeric section marker to help\n * enforce ordering rules or null when the statement does not belong to a tracked section.\n *\n * @param statement The statement to classify within the component file structure.\n * @returns The numeric section identifier for the statement, or null when it does not match a section.\n *\n * @example\n * ```tsx\n * const section = sectionForStatement(statement);\n * ```\n */\n const sectionForStatement = (statement: TSESTree.Statement) => {\n if (statement.type === 'ImportDeclaration') {\n return 1;\n }\n\n if (statement === componentInfo.statement) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 4;\n }\n\n if (isDisplayNameAssignment(statement, componentName)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 5;\n }\n\n if (isComponentExport(statement, componentName)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 6;\n }\n\n if (isStyledDeclaration(statement) || isNonPropsTypeDeclaration(statement)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 7;\n }\n\n if (isOptionalVarDeclaration(statement)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 2;\n }\n\n if (isPropsTypeDeclaration(statement)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 3;\n }\n\n return null;\n };\n\n return {\n /**\n * Iterates over the program body statements to validate their order based on the defined component file structure. It\n * tracks the last seen section and reports any statement that appears in an earlier section than the last one. It also checks\n * for the presence of a displayName assignment and a named export for the component, reporting if either is missing.\n * This ensures that the component file adheres to the expected structure and includes necessary metadata for better maintainability and clarity.\n *\n * @example\n * ```tsx\n * Program();\n * ```\n */\n Program() {\n let lastSection = 0;\n let hasDisplayName = false;\n let hasNamedExport = false;\n\n for (const statement of programBody) {\n const section = sectionForStatement(statement as TSESTree.Statement);\n\n // eslint-disable-next-line @nfq/no-magic-numbers\n if (section === 5) {\n hasDisplayName = true;\n }\n\n // eslint-disable-next-line @nfq/no-magic-numbers\n if (section === 6) {\n hasNamedExport = true;\n }\n\n if (!section) {\n continue;\n }\n\n if (section < lastSection) {\n context.report({\n messageId: 'invalidOrder',\n node: statement\n });\n } else {\n lastSection = section;\n }\n }\n\n if (!hasDisplayName) {\n context.report({\n data: {name: componentName},\n messageId: 'missingDisplayName',\n node: componentInfo.statement\n });\n }\n\n if (!hasNamedExport) {\n context.report({\n data: {name: componentName},\n messageId: 'missingNamedExport',\n node: componentInfo.statement\n });\n }\n }\n } as TSESLint.RuleListener;\n }\n});"],"names":["createRule","ESLintUtils","RuleCreator","name","componentFileStructure","defaultOptions","meta","docs","description","messages","invalidOrder","missingDisplayName","missingNamedExport","schema","type","create","context","sourceCode","programBody","ast","body","componentCandidates","filter","statement","map","getComponentInfoFromStatement","info","Boolean","length","componentInfo","sort","left","right","range","componentName","typeDeclarations","Map","getTypeDeclarationInfo","set","propsTypeNames","Set","propsTypeRefs","propsParam","functionNode","params","typeAnnotation","collectTypeReferences","has","add","isPropsTypeDeclaration","isNonPropsTypeDeclaration","isOptionalVarDeclaration","isStyledDeclaration","sectionForStatement","isDisplayNameAssignment","isComponentExport","Program","lastSection","hasDisplayName","hasNamedExport","section","report","messageId","node","data"],"mappings":"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"}
1
+ {"version":3,"file":"component-file-structure.js","sources":["../../../../src/rules/custom/component-file-structure.ts"],"sourcesContent":["import {ESLintUtils} from '@typescript-eslint/utils';\n\nimport {\n collectTypeReferences,\n getComponentInfoFromStatement,\n getTypeDeclarationInfo,\n isComponentExport,\n isDefaultComponentExport,\n isDisplayNameAssignment,\n isStyledDeclaration\n} from './utils/component-file-structure-utils';\n\nimport type {ComponentInfo} from './utils/component-file-structure-utils';\nimport type {TSESLint, TSESTree} from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/nfqde/eslint-config-nfq/blob/master/docs/rules/${name}.md`\n);\n\ntype MessageIds = 'invalidOrder' | 'missingDisplayName' | 'missingNamedExport';\n\nconst ORDER_LABELS = [\n 'Imports',\n 'Optional declarations',\n 'Props types',\n 'Component',\n 'Component helpers and displayName',\n 'Exports',\n 'Styled components and local helper types'\n];\nconst ORDER_MESSAGE = ORDER_LABELS.join(' -> ');\n// eslint-disable-next-line jsdoc/require-jsdoc\nconst getSectionLabel = (section: number) => ORDER_LABELS[section - 1] ?? 'Unknown';\nconst PAGE_TYPE_NAMES = new Set(['NextPage', 'NextPageWithLayout']);\n\nexport const componentFileStructure = createRule<[], MessageIds>({\n defaultOptions: [],\n meta: {\n docs: {description: 'Enforce file structure order for React component files.'},\n messages: {\n // eslint-disable-next-line @stylistic/max-len\n invalidOrder: 'This file structure block is out of order. {{current}} appears before {{previous}}. Expected order: {{order}}.',\n missingDisplayName: 'Component {{name}} must set displayName.',\n missingNamedExport: 'Component {{name}} must be exported by name.'\n },\n schema: [],\n type: 'suggestion'\n },\n name: 'component-file-structure',\n /**\n * Creates the rule listener for enforcing component file structure ordering. It analyzes the program body to\n * identify the primary component, its props types, and structural sections. It then reports ordering issues and\n * missing requirements like displayName or named exports.\n *\n * @param context The ESLint rule context used to access source code and report diagnostics.\n * @returns A rule listener that validates component file structure and reports issues.\n *\n * @example\n * ```tsx\n * // eslint-disable-next-line @nfq/component-file-structure\n * const listener = componentFileStructure.create(context);\n * ```\n */\n create(context) {\n const {sourceCode} = context;\n const programBody = sourceCode.ast.body;\n const componentCandidates = programBody\n .filter((statement): statement is TSESTree.Statement => statement.type !== 'TSModuleDeclaration')\n .map(statement => getComponentInfoFromStatement(statement))\n .filter((info): info is ComponentInfo => Boolean(info));\n\n if (componentCandidates.length === 0) {\n return {};\n }\n\n const componentInfo = componentCandidates.sort(\n (left, right) => left.statement.range[0] - right.statement.range[0]\n )[0];\n const componentName = componentInfo.name;\n const typeDeclarations = new Map<string, TSESTree.Node>();\n\n for (const statement of programBody) {\n const info = getTypeDeclarationInfo(statement as TSESTree.Statement);\n\n if (info) {\n typeDeclarations.set(info.name, info.statement);\n }\n }\n\n const propsTypeNames = new Set<string>();\n const propsTypeRefs = new Set<string>();\n const propsTypeNode = componentInfo.propsTypeNode ?? null;\n /**\n * Determines whether the component uses a page-specific type alias. It inspects the component type node\n * and collects all referenced type names. It then checks if any of those names match known page types to\n * decide if the component is a page component.\n *\n * @returns True when the component type includes a known page type; otherwise false.\n *\n * @example\n * ```tsx\n * const isPage = isPageType();\n * ```\n */\n const isPageType = () => {\n const typeNode = componentInfo.componentTypeNode ?? null;\n\n if (!typeNode) {\n return false;\n }\n\n const typeRefs = new Set<string>();\n\n collectTypeReferences(typeNode, typeRefs);\n\n return Array.from(typeRefs).some(name => PAGE_TYPE_NAMES.has(name));\n };\n\n /**\n * Checks whether a statement assigns a page layout helper to the component. It ensures the statement is\n * an assignment expression targeting a member of the component identifier. It then verifies the member name\n * matches supported layout assignment properties.\n *\n * @param statement The statement to inspect for a layout assignment.\n * @returns True when the statement assigns a layout helper on the component; otherwise false.\n *\n * @example\n * ```tsx\n * const hasLayout = isPageLayoutAssignment(statement);\n * ```\n */\n const isPageLayoutAssignment = (statement: TSESTree.Statement) => {\n if (statement.type !== 'ExpressionStatement') {\n return false;\n }\n\n const {expression} = statement;\n\n if (expression.type !== 'AssignmentExpression') {\n return false;\n }\n\n const {left} = expression;\n\n if (left.type !== 'MemberExpression' || left.object.type !== 'Identifier') {\n return false;\n }\n\n if (left.object.name !== componentName || left.property.type !== 'Identifier') {\n return false;\n }\n\n return left.property.name === 'getLayout' || left.property.name === 'getLayoutKey';\n };\n\n const hasDefaultExport = programBody\n .some(statement => isDefaultComponentExport(statement as TSESTree.Statement, componentName));\n const hasLayoutAssignment = programBody\n .some(statement => isPageLayoutAssignment(statement as TSESTree.Statement));\n const isPageComponent = hasDefaultExport && (hasLayoutAssignment || isPageType());\n\n if (propsTypeNode) {\n collectTypeReferences(propsTypeNode, propsTypeRefs);\n\n for (const name of propsTypeRefs) {\n if (typeDeclarations.has(name)) {\n propsTypeNames.add(name);\n }\n }\n }\n\n /**\n * Determines whether a statement declares a type that is used as the component props. It inspects the statement\n * for a type declaration and compares the declared name against the collected props type names. It returns a\n * boolean so callers can classify statements into the props type section.\n *\n * @param statement The statement to inspect for a props type declaration.\n * @returns True when the statement declares a props type; otherwise false.\n *\n * @example\n * ```tsx\n * const isProps = isPropsTypeDeclaration(statement);\n * ```\n */\n const isPropsTypeDeclaration = (statement: TSESTree.Statement) => {\n const info = getTypeDeclarationInfo(statement);\n\n return Boolean(info && propsTypeNames.has(info.name));\n };\n\n /**\n * Determines whether a statement declares a type that is not used as the component props. It inspects the\n * statement for a type declaration and ensures the declared name is not among the collected props type names.\n * It returns a boolean so callers can classify statements into non-props type sections.\n *\n * @param statement The statement to inspect for a non-props type declaration.\n * @returns True when the statement declares a non-props type; otherwise false.\n *\n * @example\n * ```tsx\n * const isNonProps = isNonPropsTypeDeclaration(statement);\n * ```\n */\n const isNonPropsTypeDeclaration = (statement: TSESTree.Statement) => {\n const info = getTypeDeclarationInfo(statement);\n\n return Boolean(info && !propsTypeNames.has(info.name));\n };\n\n /**\n * Determines whether a statement is an optional variable-like declaration in the component file structure. It\n * filters out the main component statement and styled declarations to avoid misclassification. It considers\n * variable declarations, non-component function declarations, and enum declarations as optional declarations.\n *\n * @param statement The statement to evaluate for optional declaration status.\n * @returns True when the statement should be treated as an optional declaration; otherwise false.\n *\n * @example\n * ```tsx\n * const isOptional = isOptionalVarDeclaration(statement);\n * ```\n */\n const isOptionalVarDeclaration = (statement: TSESTree.Statement) => {\n if (statement.type === 'VariableDeclaration') {\n if (statement === componentInfo.statement || isStyledDeclaration(statement)) {\n return false;\n }\n\n return true;\n }\n\n if (statement.type === 'FunctionDeclaration') {\n return statement !== componentInfo.statement;\n }\n\n return statement.type === 'TSEnumDeclaration';\n };\n\n /**\n * Determines the structural section number for a given statement in a component file. It checks the statement\n * against known component structure elements like imports, the main component, displayName assignment, exports,\n * styled declarations, optional declarations, and props types. It returns a numeric section marker to help\n * enforce ordering rules or null when the statement does not belong to a tracked section.\n *\n * @param statement The statement to classify within the component file structure.\n * @returns The numeric section identifier for the statement, or null when it does not match a section.\n *\n * @example\n * ```tsx\n * const section = sectionForStatement(statement);\n * ```\n */\n const sectionForStatement = (statement: TSESTree.Statement) => {\n if (statement.type === 'ImportDeclaration') {\n return 1;\n }\n\n if (statement === componentInfo.statement) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 4;\n }\n\n if (isDisplayNameAssignment(statement, componentName)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 5;\n }\n\n if (\n isComponentExport(statement, componentName)\n || isDefaultComponentExport(statement, componentName)\n ) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 6;\n }\n\n if (isStyledDeclaration(statement) || isNonPropsTypeDeclaration(statement)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 7;\n }\n\n if (isOptionalVarDeclaration(statement)) {\n if (statement.range[0] > componentInfo.statement.range[0]) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 5;\n }\n\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 2;\n }\n\n if (isPropsTypeDeclaration(statement)) {\n // eslint-disable-next-line @nfq/no-magic-numbers\n return 3;\n }\n\n return null;\n };\n\n return {\n /**\n * Iterates over the program body statements to validate their order based on the defined component file structure. It\n * tracks the last seen section and reports any statement that appears in an earlier section than the last one. It also checks\n * for the presence of a displayName assignment and a named export for the component, reporting if either is missing.\n * This ensures that the component file adheres to the expected structure and includes necessary metadata for better maintainability and clarity.\n *\n * @example\n * ```tsx\n * Program();\n * ```\n */\n Program() {\n let lastSection = 0;\n let hasDisplayName = false;\n let hasNamedExport = false;\n\n for (const statement of programBody) {\n const section = sectionForStatement(statement as TSESTree.Statement);\n\n // eslint-disable-next-line @nfq/no-magic-numbers\n if (section === 5) {\n hasDisplayName = true;\n }\n\n // eslint-disable-next-line @nfq/no-magic-numbers\n if (section === 6) {\n hasNamedExport = true;\n }\n\n if (!section) {\n continue;\n }\n\n if (section < lastSection) {\n context.report({\n data: {\n current: getSectionLabel(section),\n order: ORDER_MESSAGE,\n previous: getSectionLabel(lastSection)\n },\n messageId: 'invalidOrder',\n node: statement\n });\n } else {\n lastSection = section;\n }\n }\n\n if (!hasDisplayName && !isPageComponent) {\n context.report({\n data: {name: componentName},\n messageId: 'missingDisplayName',\n node: componentInfo.statement\n });\n }\n\n if (!hasNamedExport && !isPageComponent) {\n context.report({\n data: {name: componentName},\n messageId: 'missingNamedExport',\n node: componentInfo.statement\n });\n }\n }\n } as TSESLint.RuleListener;\n }\n});"],"names":["createRule","ESLintUtils","RuleCreator","name","ORDER_LABELS","ORDER_MESSAGE","join","getSectionLabel","section","PAGE_TYPE_NAMES","Set","componentFileStructure","defaultOptions","meta","docs","description","messages","invalidOrder","missingDisplayName","missingNamedExport","schema","type","create","context","sourceCode","programBody","ast","body","componentCandidates","filter","statement","map","getComponentInfoFromStatement","info","Boolean","length","componentInfo","sort","left","right","range","componentName","typeDeclarations","Map","getTypeDeclarationInfo","set","propsTypeNames","propsTypeRefs","propsTypeNode","isPageType","typeNode","componentTypeNode","typeRefs","collectTypeReferences","Array","from","some","has","isPageLayoutAssignment","expression","object","property","hasDefaultExport","isDefaultComponentExport","hasLayoutAssignment","isPageComponent","add","isPropsTypeDeclaration","isNonPropsTypeDeclaration","isOptionalVarDeclaration","isStyledDeclaration","sectionForStatement","isDisplayNameAssignment","isComponentExport","Program","lastSection","hasDisplayName","hasNamedExport","report","data","current","order","previous","messageId","node"],"mappings":"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"}
@@ -2,11 +2,84 @@ import { ASTUtils } from '@typescript-eslint/utils';
2
2
  import { isUppercaseName, getFunctionFromExpression } from './component-utils.js';
3
3
  import { unwrapExpression } from './expression-utils.js';
4
4
 
5
+ const containsJsx = node => {
6
+ if (!node) {
7
+ return false;
8
+ }
9
+ const stack = [node];
10
+ while (stack.length) {
11
+ const current = stack.pop();
12
+ if (current.type === 'JSXElement' || current.type === 'JSXFragment') {
13
+ return true;
14
+ }
15
+ for (const key of Object.keys(current)) {
16
+ if (key === 'parent') {
17
+ continue;
18
+ }
19
+ const value = current[key];
20
+ if (!value || typeof value !== 'object') {
21
+ continue;
22
+ }
23
+ if (Array.isArray(value)) {
24
+ for (const item of value) {
25
+ if (item && typeof item === 'object' && 'type' in item) {
26
+ stack.push(item);
27
+ }
28
+ }
29
+ } else if ('type' in value) {
30
+ stack.push(value);
31
+ }
32
+ }
33
+ }
34
+ return false;
35
+ };
36
+ const isComponentSuperclass = node => {
37
+ if (!node) {
38
+ return false;
39
+ }
40
+ if (node.type === 'Identifier') {
41
+ return node.name === 'Component' || node.name === 'PureComponent';
42
+ }
43
+ if (node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'React' && node.property.type === 'Identifier') {
44
+ return node.property.name === 'Component' || node.property.name === 'PureComponent';
45
+ }
46
+ return false;
47
+ };
48
+ const isClassComponent = node => {
49
+ if (!isComponentSuperclass(node.superClass)) {
50
+ return false;
51
+ }
52
+ const renderMethod = node.body.body.find(member => member.type === 'MethodDefinition' && member.key.type === 'Identifier' && member.key.name === 'render');
53
+ if (!renderMethod || renderMethod.type !== 'MethodDefinition') {
54
+ return false;
55
+ }
56
+ return containsJsx(renderMethod.value.body);
57
+ };
58
+ const getSuperclassPropsType = node => {
59
+ const withSuperParams = node;
60
+ const superParams = withSuperParams.superTypeArguments ?? withSuperParams.superTypeParameters;
61
+ return superParams?.params?.[0] ?? null;
62
+ };
5
63
  const getComponentInfoFromStatement = node => {
6
64
  if (node.type === 'FunctionDeclaration' && isUppercaseName(node.id.name)) {
65
+ if (!containsJsx(node.body)) {
66
+ return null;
67
+ }
68
+ return {
69
+ componentTypeNode: node.returnType?.typeAnnotation ?? null,
70
+ name: node.id.name,
71
+ propsTypeNode: node.params[0] && 'typeAnnotation' in node.params[0] ? node.params[0].typeAnnotation : null,
72
+ statement: node
73
+ };
74
+ }
75
+ if (node.type === 'ClassDeclaration' && node.id && isUppercaseName(node.id.name)) {
76
+ if (!isClassComponent(node)) {
77
+ return null;
78
+ }
7
79
  return {
8
- functionNode: node,
80
+ componentTypeNode: null,
9
81
  name: node.id.name,
82
+ propsTypeNode: getSuperclassPropsType(node),
10
83
  statement: node
11
84
  };
12
85
  }
@@ -24,11 +97,23 @@ const getComponentInfoFromStatement = node => {
24
97
  continue;
25
98
  }
26
99
  const init = unwrapExpression(declarator.init);
100
+ if (init.type === 'ClassExpression') {
101
+ if (!isClassComponent(init)) {
102
+ continue;
103
+ }
104
+ return {
105
+ componentTypeNode: null,
106
+ name,
107
+ propsTypeNode: getSuperclassPropsType(init),
108
+ statement: node
109
+ };
110
+ }
27
111
  const functionNode = getFunctionFromExpression(init);
28
- if (functionNode) {
112
+ if (functionNode && containsJsx(functionNode.body)) {
29
113
  return {
30
- functionNode,
114
+ componentTypeNode: declarator.id.typeAnnotation?.typeAnnotation ?? null,
31
115
  name,
116
+ propsTypeNode: functionNode.params[0] && 'typeAnnotation' in functionNode.params[0] ? functionNode.params[0].typeAnnotation : null,
32
117
  statement: node
33
118
  };
34
119
  }
@@ -59,6 +144,21 @@ const isComponentExport = (node, componentName) => {
59
144
  }
60
145
  return node.specifiers.some(specifier => specifier.local.type === 'Identifier' && specifier.local.name === componentName && specifier.exported.type === 'Identifier' && specifier.exported.name === componentName);
61
146
  };
147
+ const isDefaultComponentExport = (node, componentName) => {
148
+ if (node.type !== 'ExportDefaultDeclaration') {
149
+ return false;
150
+ }
151
+ const {
152
+ declaration
153
+ } = node;
154
+ if (declaration.type === 'Identifier') {
155
+ return declaration.name === componentName;
156
+ }
157
+ if (declaration.type === 'ClassDeclaration' || declaration.type === 'FunctionDeclaration') {
158
+ return Boolean(declaration.id && declaration.id.name === componentName);
159
+ }
160
+ return false;
161
+ };
62
162
  const isStyledDeclaration = node => {
63
163
  if (node.type !== 'VariableDeclaration') {
64
164
  return false;
@@ -126,5 +226,5 @@ const collectTypeReferences = (typeNode, names) => {
126
226
  }
127
227
  };
128
228
 
129
- export { collectTypeReferences, getComponentInfoFromStatement, getTypeDeclarationInfo, isComponentExport, isDisplayNameAssignment, isStyledDeclaration };
229
+ export { collectTypeReferences, getComponentInfoFromStatement, getTypeDeclarationInfo, isComponentExport, isDefaultComponentExport, isDisplayNameAssignment, isStyledDeclaration };
130
230
  //# sourceMappingURL=component-file-structure-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"component-file-structure-utils.js","sources":["../../../../../src/rules/custom/utils/component-file-structure-utils.ts"],"sourcesContent":["import {ASTUtils} from '@typescript-eslint/utils';\n\nimport {getFunctionFromExpression, isUppercaseName} from './component-utils';\nimport {unwrapExpression} from './expression-utils';\n\nimport type {TSESTree} from '@typescript-eslint/utils';\n\nexport type ComponentInfo = {\n functionNode: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression;\n name: string;\n statement: TSESTree.Node;\n};\n\nexport type TypeDeclarationInfo = {\n name: string;\n statement: TSESTree.Node;\n};\n\n/**\n * Determines whether a statement declares a component-like function and returns structured details when it does.\n * It checks for uppercase-named function declarations and variable declarations initialized with arrow functions or\n * function expressions. It returns null when the statement does not match the expected component patterns.\n *\n * @param node The statement node to analyze for component declarations.\n * @returns The component information when a match is found, or null when no component is detected.\n *\n * @remarks\n * This helper relies on naming conventions and initializer inspection to infer component declarations.\n *\n * @example\n * ```tsx\n * const info = getComponentInfoFromStatement(statement);\n * ```\n */\nexport const getComponentInfoFromStatement = (node: TSESTree.Statement): ComponentInfo | null => {\n if (node.type === 'FunctionDeclaration' && isUppercaseName(node.id.name)) {\n return {\n functionNode: node,\n name: node.id.name,\n statement: node\n };\n }\n\n if (node.type !== 'VariableDeclaration') {\n return null;\n }\n\n for (const declarator of node.declarations) {\n if (!ASTUtils.isIdentifier(declarator.id)) {\n continue;\n }\n\n const {name} = declarator.id;\n\n if (!isUppercaseName(name) || !declarator.init) {\n continue;\n }\n\n const init = unwrapExpression(declarator.init);\n const functionNode = getFunctionFromExpression(init);\n\n if (functionNode) {\n return {\n functionNode,\n name,\n statement: node\n };\n }\n }\n\n return null;\n};\n\n/**\n * Determines whether a statement assigns a display name to a component identifier. It narrows the statement to an\n * expression statement that performs an assignment and validates the left-hand side member access. It returns a boolean\n * indicating whether the assignment targets the specified component's displayName property.\n *\n * @param node The statement node to inspect.\n * @param componentName The expected component identifier name.\n * @returns True when the statement assigns to the component's displayName property.\n *\n * @remarks\n * This helper is used to recognize explicit displayName assignments.\n *\n * @example\n * ```tsx\n * const ok = isDisplayNameAssignment(statement, 'Header');\n * ```\n */\nexport const isDisplayNameAssignment = (node: TSESTree.Statement, componentName: string) => {\n if (node.type !== 'ExpressionStatement') {\n return false;\n }\n\n const {expression} = node;\n\n if (expression.type !== 'AssignmentExpression') {\n return false;\n }\n\n const {left} = expression;\n\n if (left.type !== 'MemberExpression' || left.property.type !== 'Identifier') {\n return false;\n }\n\n return ASTUtils.isIdentifier(left.object)\n && left.object.name === componentName\n && left.property.name === 'displayName';\n};\n\n/**\n * Determines whether a statement is an export that re-exports a component identifier with the same name.\n * It inspects named export specifiers and verifies that both the local and exported names match the provided component\n * name. It returns false for non-named exports or when no matching specifier is found.\n *\n * @param node The statement node to inspect.\n * @param componentName The expected component identifier name.\n * @returns True when the statement exports the component identifier by name.\n *\n * @remarks\n * This helper is used to detect explicit named exports of component identifiers.\n *\n * @example\n * ```tsx\n * const ok = isComponentExport(statement, 'Header');\n * ```\n */\nexport const isComponentExport = (node: TSESTree.Statement, componentName: string) => {\n if (node.type !== 'ExportNamedDeclaration' || !node.specifiers.length) {\n return false;\n }\n\n return node.specifiers.some(specifier => (\n specifier.local.type === 'Identifier'\n && specifier.local.name === componentName\n && specifier.exported.type === 'Identifier'\n && specifier.exported.name === componentName\n ));\n};\n\n/**\n * Determines whether a statement declares a styled component variable using the styled tag factory. It inspects variable\n * declarations and checks tagged template expressions for identifiers, member expressions, or call expressions that\n * resolve to `styled`. It returns a boolean that indicates whether any declarator matches the styled component pattern.\n *\n * @param node The statement node to inspect for a styled component declaration.\n * @returns True when the statement contains a styled tagged template declaration.\n *\n * @remarks\n * This helper recognizes multiple `styled` invocation forms used in styled-components.\n *\n * @example\n * ```tsx\n * const ok = isStyledDeclaration(statement);\n * ```\n */\nexport const isStyledDeclaration = (node: TSESTree.Statement) => {\n if (node.type !== 'VariableDeclaration') {\n return false;\n }\n\n return node.declarations.some(declarator => {\n if (declarator.init?.type !== 'TaggedTemplateExpression') {\n return false;\n }\n\n const tag = unwrapExpression(declarator.init.tag);\n\n if (ASTUtils.isIdentifier(tag)) {\n return tag.name === 'styled';\n }\n\n if (tag.type === 'MemberExpression') {\n return tag.object.type === 'Identifier' && tag.object.name === 'styled';\n }\n\n if (tag.type === 'CallExpression') {\n return ASTUtils.isIdentifier(tag.callee) && tag.callee.name === 'styled';\n }\n\n return false;\n });\n};\n\n/**\n * Extracts type declaration details from a statement when it represents a TypeScript interface or type alias.\n * It supports both direct declarations and named exports that wrap those declarations. It returns structured metadata\n * so callers can quickly access the declared name and statement node.\n *\n * @param node The statement node to inspect for a type declaration.\n * @returns The type declaration info when found, or null when the statement does not declare a type.\n *\n * @remarks\n * This helper simplifies handling exported and non-exported type declarations in AST traversal.\n *\n * @example\n * ```tsx\n * const info = getTypeDeclarationInfo(statement);\n * ```\n */\nexport const getTypeDeclarationInfo = (node: TSESTree.Statement): TypeDeclarationInfo | null => {\n if (node.type === 'TSInterfaceDeclaration' || node.type === 'TSTypeAliasDeclaration') {\n return {\n name: node.id.name,\n statement: node\n };\n }\n\n if (node.type === 'ExportNamedDeclaration' && node.declaration) {\n const {declaration} = node;\n\n if (declaration.type === 'TSInterfaceDeclaration' || declaration.type === 'TSTypeAliasDeclaration') {\n return {\n name: declaration.id.name,\n statement: node\n };\n }\n }\n\n return null;\n};\n\n/**\n * Collects type reference identifiers from a TypeScript AST node and records them in a provided set. It walks the node\n * recursively, skipping parent links to avoid cycles, and handles both singular child nodes and arrays of nodes. It\n * updates the provided set in place and does not return a value.\n *\n * @param typeNode The AST node to scan for type references.\n * @param names The set that receives discovered type reference names.\n *\n * @remarks\n * This helper is intended for internal traversal of TypeScript type nodes.\n *\n * @example\n * ```tsx\n * const names = new Set<string>();\n * collectTypeReferences(typeNode, names);\n * ```\n */\nexport const collectTypeReferences = (typeNode: TSESTree.Node, names: Set<string>) => {\n if (typeNode.type === 'TSTypeReference') {\n if (typeNode.typeName.type === 'Identifier') {\n names.add(typeNode.typeName.name);\n }\n }\n\n for (const key of Object.keys(typeNode) as (keyof typeof typeNode)[]) {\n if (key === 'parent') {\n continue;\n }\n const value = typeNode[key];\n\n if (typeof value !== 'object') {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object') {\n collectTypeReferences(item as TSESTree.Node, names);\n }\n }\n } else {\n collectTypeReferences(value as unknown as TSESTree.Node, names);\n }\n }\n};"],"names":["getComponentInfoFromStatement","node","type","isUppercaseName","id","name","functionNode","statement","declarator","declarations","ASTUtils","isIdentifier","init","unwrapExpression","getFunctionFromExpression","isDisplayNameAssignment","componentName","expression","left","property","object","isComponentExport","specifiers","length","some","specifier","local","exported","isStyledDeclaration","tag","callee","getTypeDeclarationInfo","declaration","collectTypeReferences","typeNode","names","typeName","add","key","Object","keys","value","Array","isArray","item"],"mappings":"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"}
1
+ {"version":3,"file":"component-file-structure-utils.js","sources":["../../../../../src/rules/custom/utils/component-file-structure-utils.ts"],"sourcesContent":["import {ASTUtils} from '@typescript-eslint/utils';\n\nimport {getFunctionFromExpression, isUppercaseName} from './component-utils';\nimport {unwrapExpression} from './expression-utils';\n\nimport type {TSESTree} from '@typescript-eslint/utils';\n\nexport type ComponentInfo = {\n componentTypeNode?: TSESTree.Node | null;\n name: string;\n propsTypeNode?: TSESTree.Node | null;\n statement: TSESTree.Node;\n};\n\nexport type TypeDeclarationInfo = {\n name: string;\n statement: TSESTree.Node;\n};\n\n/**\n * Determines whether a given AST node tree contains any JSX elements or fragments. It performs a depth-first traversal\n * using an explicit stack to avoid recursion and scans all child nodes except parent links. It returns true as soon as\n * a JSXElement or JSXFragment node is found and otherwise returns false after fully traversing the tree.\n *\n * @param node The AST node to scan for JSX content.\n * @returns True when the tree contains JSX elements or fragments, otherwise false.\n *\n * @remarks\n * This helper is used to detect component-like render bodies that include JSX.\n *\n * @example\n * ```tsx\n * const hasJsx = containsJsx(node);\n * ```\n */\nconst containsJsx = (node: TSESTree.Node | null | undefined): boolean => {\n if (!node) {\n return false;\n }\n\n const stack: TSESTree.Node[] = [node];\n\n while (stack.length) {\n const current = stack.pop()!;\n\n if (current.type === 'JSXElement' || current.type === 'JSXFragment') {\n return true;\n }\n\n for (const key of Object.keys(current) as (keyof TSESTree.Node)[]) {\n if (key === 'parent') {\n continue;\n }\n\n const value = current[key];\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!value || typeof value !== 'object') {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && 'type' in item) {\n stack.push(item as TSESTree.Node);\n }\n }\n } else if ('type' in value) {\n stack.push(value as unknown as TSESTree.Node);\n }\n }\n }\n\n return false;\n};\n\n/**\n * Determines whether the provided AST node represents a React component superclass. It checks for both direct\n * identifiers and React namespace member expressions. It returns true only when the name matches Component or\n * PureComponent and otherwise returns false.\n *\n * @param node The AST node to test for a component superclass reference.\n * @returns True when the node matches Component or PureComponent, otherwise false.\n *\n * @remarks\n * This helper is used to recognize React class component inheritance patterns.\n *\n * @example\n * ```tsx\n * const ok = isComponentSuperclass(node);\n * ```\n */\nconst isComponentSuperclass = (node: TSESTree.Node | null | undefined): boolean => {\n if (!node) {\n return false;\n }\n\n if (node.type === 'Identifier') {\n return node.name === 'Component' || node.name === 'PureComponent';\n }\n\n if (\n node.type === 'MemberExpression'\n && node.object.type === 'Identifier'\n && node.object.name === 'React'\n && node.property.type === 'Identifier'\n ) {\n return node.property.name === 'Component' || node.property.name === 'PureComponent';\n }\n\n return false;\n};\n\n/**\n * Determines whether a class declaration or expression represents a React class component. It validates the superclass\n * against React Component or PureComponent and then checks for a render method that returns JSX. It returns true only\n * when both conditions are satisfied.\n *\n * @param node The class declaration or expression node to inspect.\n * @returns True when the class extends a React component superclass and defines a JSX-producing render method.\n *\n * @remarks\n * This helper relies on a render method presence and JSX detection to identify class components.\n *\n * @example\n * ```tsx\n * const ok = isClassComponent(classNode);\n * ```\n */\nconst isClassComponent = (node: TSESTree.ClassDeclaration | TSESTree.ClassExpression): boolean => {\n if (!isComponentSuperclass(node.superClass)) {\n return false;\n }\n\n const renderMethod = node.body.body.find(\n member => member.type === 'MethodDefinition'\n && member.key.type === 'Identifier'\n && member.key.name === 'render'\n );\n\n // eslint-disable-next-line @typescript-eslint/prefer-optional-chain\n if (!renderMethod || renderMethod.type !== 'MethodDefinition') {\n return false;\n }\n\n return containsJsx(renderMethod.value.body);\n};\n\n/**\n * Retrieves the props type node from the superclass type parameters of a class.\n *\n * @param node The class declaration or expression to inspect.\n * @returns The first type parameter node from the superclass, or `null` if none exists.\n */\nconst getSuperclassPropsType = (\n node: TSESTree.ClassDeclaration | TSESTree.ClassExpression\n): TSESTree.Node | null => {\n const withSuperParams = node as unknown as {\n superTypeArguments?: {params?: TSESTree.Node[]};\n superTypeParameters?: {params?: TSESTree.Node[]};\n };\n\n const superParams = withSuperParams.superTypeArguments ?? withSuperParams.superTypeParameters;\n\n return superParams?.params?.[0] ?? null;\n};\n\n/**\n * Determines whether a statement declares a component-like function and returns structured details when it does.\n * It checks for uppercase-named function declarations and variable declarations initialized with arrow functions or\n * function expressions. It returns null when the statement does not match the expected component patterns.\n *\n * @param node The statement node to analyze for component declarations.\n * @returns The component information when a match is found, or null when no component is detected.\n *\n * @remarks\n * This helper relies on naming conventions and initializer inspection to infer component declarations.\n *\n * @example\n * ```tsx\n * const info = getComponentInfoFromStatement(statement);\n * ```\n */\nexport const getComponentInfoFromStatement = (node: TSESTree.Statement): ComponentInfo | null => {\n if (node.type === 'FunctionDeclaration' && isUppercaseName(node.id.name)) {\n if (!containsJsx(node.body)) {\n return null;\n }\n\n return {\n componentTypeNode: node.returnType?.typeAnnotation ?? null,\n name: node.id.name,\n propsTypeNode: node.params[0] && 'typeAnnotation' in node.params[0]\n ? node.params[0].typeAnnotation\n : null,\n statement: node\n };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (node.type === 'ClassDeclaration' && node.id && isUppercaseName(node.id.name)) {\n if (!isClassComponent(node)) {\n return null;\n }\n\n return {\n componentTypeNode: null,\n name: node.id.name,\n propsTypeNode: getSuperclassPropsType(node),\n statement: node\n };\n }\n\n if (node.type !== 'VariableDeclaration') {\n return null;\n }\n\n for (const declarator of node.declarations) {\n if (!ASTUtils.isIdentifier(declarator.id)) {\n continue;\n }\n\n const {name} = declarator.id;\n\n if (!isUppercaseName(name) || !declarator.init) {\n continue;\n }\n\n const init = unwrapExpression(declarator.init);\n\n if (init.type === 'ClassExpression') {\n if (!isClassComponent(init)) {\n continue;\n }\n\n return {\n componentTypeNode: null,\n name,\n propsTypeNode: getSuperclassPropsType(init),\n statement: node\n };\n }\n\n const functionNode = getFunctionFromExpression(init);\n\n if (functionNode && containsJsx(functionNode.body)) {\n return {\n componentTypeNode: declarator.id.typeAnnotation?.typeAnnotation ?? null,\n name,\n propsTypeNode: functionNode.params[0] && 'typeAnnotation' in functionNode.params[0]\n ? functionNode.params[0].typeAnnotation\n : null,\n statement: node\n };\n }\n }\n\n return null;\n};\n\n/**\n * Determines whether a statement assigns a display name to a component identifier. It narrows the statement to an\n * expression statement that performs an assignment and validates the left-hand side member access. It returns a boolean\n * indicating whether the assignment targets the specified component's displayName property.\n *\n * @param node The statement node to inspect.\n * @param componentName The expected component identifier name.\n * @returns True when the statement assigns to the component's displayName property.\n *\n * @remarks\n * This helper is used to recognize explicit displayName assignments.\n *\n * @example\n * ```tsx\n * const ok = isDisplayNameAssignment(statement, 'Header');\n * ```\n */\nexport const isDisplayNameAssignment = (node: TSESTree.Statement, componentName: string) => {\n if (node.type !== 'ExpressionStatement') {\n return false;\n }\n\n const {expression} = node;\n\n if (expression.type !== 'AssignmentExpression') {\n return false;\n }\n\n const {left} = expression;\n\n if (left.type !== 'MemberExpression' || left.property.type !== 'Identifier') {\n return false;\n }\n\n return ASTUtils.isIdentifier(left.object)\n && left.object.name === componentName\n && left.property.name === 'displayName';\n};\n\n/**\n * Determines whether a statement is an export that re-exports a component identifier with the same name.\n * It inspects named export specifiers and verifies that both the local and exported names match the provided component\n * name. It returns false for non-named exports or when no matching specifier is found.\n *\n * @param node The statement node to inspect.\n * @param componentName The expected component identifier name.\n * @returns True when the statement exports the component identifier by name.\n *\n * @remarks\n * This helper is used to detect explicit named exports of component identifiers.\n *\n * @example\n * ```tsx\n * const ok = isComponentExport(statement, 'Header');\n * ```\n */\nexport const isComponentExport = (node: TSESTree.Statement, componentName: string) => {\n if (node.type !== 'ExportNamedDeclaration' || !node.specifiers.length) {\n return false;\n }\n\n return node.specifiers.some(specifier => (\n specifier.local.type === 'Identifier'\n && specifier.local.name === componentName\n && specifier.exported.type === 'Identifier'\n && specifier.exported.name === componentName\n ));\n};\n\n/**\n * Determines whether a statement is a default export that targets a component identifier.\n * It supports `export default Identifier` and `export default class/function` declarations\n * with matching names.\n *\n * @param node The statement node to inspect.\n * @param componentName The expected component identifier name.\n * @returns True when the statement default-exports the component.\n *\n * @example\n * ```tsx\n * const ok = isDefaultComponentExport(statement, 'App');\n * ```\n */\nexport const isDefaultComponentExport = (node: TSESTree.Statement, componentName: string) => {\n if (node.type !== 'ExportDefaultDeclaration') {\n return false;\n }\n\n const {declaration} = node;\n\n if (declaration.type === 'Identifier') {\n return declaration.name === componentName;\n }\n\n if (declaration.type === 'ClassDeclaration' || declaration.type === 'FunctionDeclaration') {\n // eslint-disable-next-line @typescript-eslint/prefer-optional-chain\n return Boolean(declaration.id && declaration.id.name === componentName);\n }\n\n return false;\n};\n\n/**\n * Determines whether a statement declares a styled component variable using the styled tag factory. It inspects variable\n * declarations and checks tagged template expressions for identifiers, member expressions, or call expressions that\n * resolve to `styled`. It returns a boolean that indicates whether any declarator matches the styled component pattern.\n *\n * @param node The statement node to inspect for a styled component declaration.\n * @returns True when the statement contains a styled tagged template declaration.\n *\n * @remarks\n * This helper recognizes multiple `styled` invocation forms used in styled-components.\n *\n * @example\n * ```tsx\n * const ok = isStyledDeclaration(statement);\n * ```\n */\nexport const isStyledDeclaration = (node: TSESTree.Statement) => {\n if (node.type !== 'VariableDeclaration') {\n return false;\n }\n\n return node.declarations.some(declarator => {\n if (declarator.init?.type !== 'TaggedTemplateExpression') {\n return false;\n }\n\n const tag = unwrapExpression(declarator.init.tag);\n\n if (ASTUtils.isIdentifier(tag)) {\n return tag.name === 'styled';\n }\n\n if (tag.type === 'MemberExpression') {\n return tag.object.type === 'Identifier' && tag.object.name === 'styled';\n }\n\n if (tag.type === 'CallExpression') {\n return ASTUtils.isIdentifier(tag.callee) && tag.callee.name === 'styled';\n }\n\n return false;\n });\n};\n\n/**\n * Extracts type declaration details from a statement when it represents a TypeScript interface or type alias.\n * It supports both direct declarations and named exports that wrap those declarations. It returns structured metadata\n * so callers can quickly access the declared name and statement node.\n *\n * @param node The statement node to inspect for a type declaration.\n * @returns The type declaration info when found, or null when the statement does not declare a type.\n *\n * @remarks\n * This helper simplifies handling exported and non-exported type declarations in AST traversal.\n *\n * @example\n * ```tsx\n * const info = getTypeDeclarationInfo(statement);\n * ```\n */\nexport const getTypeDeclarationInfo = (node: TSESTree.Statement): TypeDeclarationInfo | null => {\n if (node.type === 'TSInterfaceDeclaration' || node.type === 'TSTypeAliasDeclaration') {\n return {\n name: node.id.name,\n statement: node\n };\n }\n\n if (node.type === 'ExportNamedDeclaration' && node.declaration) {\n const {declaration} = node;\n\n if (declaration.type === 'TSInterfaceDeclaration' || declaration.type === 'TSTypeAliasDeclaration') {\n return {\n name: declaration.id.name,\n statement: node\n };\n }\n }\n\n return null;\n};\n\n/**\n * Collects type reference identifiers from a TypeScript AST node and records them in a provided set. It walks the node\n * recursively, skipping parent links to avoid cycles, and handles both singular child nodes and arrays of nodes. It\n * updates the provided set in place and does not return a value.\n *\n * @param typeNode The AST node to scan for type references.\n * @param names The set that receives discovered type reference names.\n *\n * @remarks\n * This helper is intended for internal traversal of TypeScript type nodes.\n *\n * @example\n * ```tsx\n * const names = new Set<string>();\n * collectTypeReferences(typeNode, names);\n * ```\n */\nexport const collectTypeReferences = (typeNode: TSESTree.Node, names: Set<string>) => {\n if (typeNode.type === 'TSTypeReference') {\n if (typeNode.typeName.type === 'Identifier') {\n names.add(typeNode.typeName.name);\n }\n }\n\n for (const key of Object.keys(typeNode) as (keyof typeof typeNode)[]) {\n if (key === 'parent') {\n continue;\n }\n const value = typeNode[key];\n\n if (typeof value !== 'object') {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object') {\n collectTypeReferences(item as TSESTree.Node, names);\n }\n }\n } else {\n collectTypeReferences(value as unknown as TSESTree.Node, names);\n }\n }\n};"],"names":["containsJsx","node","stack","length","current","pop","type","key","Object","keys","value","Array","isArray","item","push","isComponentSuperclass","name","object","property","isClassComponent","superClass","renderMethod","body","find","member","getSuperclassPropsType","withSuperParams","superParams","superTypeArguments","superTypeParameters","params","getComponentInfoFromStatement","isUppercaseName","id","componentTypeNode","returnType","typeAnnotation","propsTypeNode","statement","declarator","declarations","ASTUtils","isIdentifier","init","unwrapExpression","functionNode","getFunctionFromExpression","isDisplayNameAssignment","componentName","expression","left","isComponentExport","specifiers","some","specifier","local","exported","isDefaultComponentExport","declaration","Boolean","isStyledDeclaration","tag","callee","getTypeDeclarationInfo","collectTypeReferences","typeNode","names","typeName","add"],"mappings":"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"}
@@ -1,12 +1,26 @@
1
1
  import { unwrapExpression } from './expression-utils.js';
2
2
 
3
3
  const isUppercaseName = name => /^[A-Z]/u.test(name);
4
+ const COMPONENT_WRAPPERS = new Set(['observer', 'memo', 'forwardRef']);
5
+ const isComponentWrapperCall = expression => {
6
+ const callee = unwrapExpression(expression);
7
+ if (callee.type === 'Identifier') {
8
+ return COMPONENT_WRAPPERS.has(callee.name);
9
+ }
10
+ if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && callee.object.name === 'React' && callee.property.type === 'Identifier') {
11
+ return COMPONENT_WRAPPERS.has(callee.property.name);
12
+ }
13
+ return false;
14
+ };
4
15
  const getFunctionFromExpression = expression => {
5
16
  const node = unwrapExpression(expression);
6
17
  if (node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression') {
7
18
  return node;
8
19
  }
9
20
  if (node.type === 'CallExpression') {
21
+ if (!isComponentWrapperCall(node.callee)) {
22
+ return null;
23
+ }
10
24
  for (const argument of node.arguments) {
11
25
  if (argument.type === 'CallExpression') {
12
26
  const nested = getFunctionFromExpression(argument);