eslint-plugin-ai-rules 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1144 -174
- package/dist/index.cjs +1640 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +80 -3
- package/dist/index.d.ts +80 -3
- package/dist/index.js +1636 -2
- package/dist/index.js.map +1 -1
- package/package.json +25 -11
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/configs/recommended.ts","../src/rules/FilenamePascalCase.ts","../src/rules/NoMultilineImports.ts","../src/rules/SortImports.ts","../src/plugin.ts","../src/index.ts"],"sourcesContent":["import { createNodeResolver, importX } from 'eslint-plugin-import-x'\nimport stylistic from '@stylistic/eslint-plugin'\nimport tseslint from 'typescript-eslint'\nimport type { Linter } from 'eslint'\n\nimport { plugin } from '../plugin'\n\n\nexport const recommended: Linter.Config[] = [\n {\n plugins: {\n '@stylistic': stylistic,\n 'import-x': importX,\n 'ai-rules': plugin,\n '@typescript-eslint': tseslint.plugin,\n },\n settings: {\n 'import-x/resolver-next': [\n createNodeResolver({\n extensions: ['.ts', '.tsx', '.d.ts', '.js', '.jsx'],\n }),\n ],\n },\n rules: {\n 'ai-rules/sort-imports': 'error',\n 'ai-rules/no-multiline-imports': 'error',\n 'ai-rules/filename-pascal-case': 'error',\n 'max-len': 'off',\n 'import-x/no-duplicates': 'error',\n 'import-x/no-default-export': 'off',\n '@stylistic/semi': ['error', 'never'],\n '@typescript-eslint/consistent-type-imports': [\n 'error',\n { prefer: 'type-imports' },\n ],\n '@typescript-eslint/no-unused-vars': [\n 'error',\n { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },\n ],\n '@typescript-eslint/naming-convention': [\n 'error',\n { selector: 'interface', format: ['PascalCase'], prefix: ['I'] },\n { selector: 'typeAlias', format: ['PascalCase'], prefix: ['T'] },\n ],\n },\n },\n]\n\nexport default recommended\n","import type { Rule } from 'eslint'\nimport path from 'node:path'\n\n\ninterface IFilenamePascalCaseOptions {\n ignore?: Array<string | RegExp>\n ignoreMiddleExtensions?: boolean\n}\n\nexport const filenamePascalCase: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n docs: { description: 'Enforce PascalCase for file names' },\n schema: [\n {\n type: 'object',\n properties: {\n ignore: { type: 'array', items: { type: 'string' } },\n ignoreMiddleExtensions: { type: 'boolean' },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n invalid: 'File name \"{{basename}}\" must be in PascalCase. Rename to \"{{expected}}\".',\n },\n },\n create(context) {\n const options = (context.options[0] ?? {}) as IFilenamePascalCaseOptions\n const { ignore = [], ignoreMiddleExtensions = true } = options\n const ignoreMatchers = ignore.flatMap((pattern) => {\n try {\n return [pattern instanceof RegExp ? pattern : new RegExp(pattern)]\n } catch {\n return []\n }\n })\n\n const physicalFilename =\n // eslint 9 flat config\n (context as unknown as { getPhysicalFilename?: () => string }).getPhysicalFilename?.() ??\n (context as unknown as { physicalFilename?: string }).physicalFilename ??\n context.filename ??\n ''\n\n const basename = path.basename(physicalFilename)\n const cwd = process.cwd()\n const relativePath = physicalFilename.startsWith(cwd + path.sep)\n ? physicalFilename.slice(cwd.length + 1)\n : physicalFilename\n\n const isIgnored = ignoreMatchers.some((matcher) =>\n [basename, relativePath].some((target) => {\n matcher.lastIndex = 0\n return matcher.test(target)\n }),\n )\n\n if (isIgnored) return {}\n if (basename.startsWith('.')) return {}\n if (basename === 'index.ts' || basename === 'index.tsx' || basename === 'index.js' || basename === 'index.jsx') return {}\n if (basename.endsWith('.d.ts')) return {}\n if (basename.endsWith('.css')) return {}\n\n const extension = basename.match(/\\.(ts|tsx|js|jsx)$/)?.[0] ?? ''\n const namePart = extension ? basename.slice(0, -extension.length) : basename\n const baseName = namePart.split('.')[0]\n\n const toPascalCase = (value: string): string =>\n value\n .split(/[-_]/)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n\n const segments = ignoreMiddleExtensions ? [baseName] : namePart.split('.')\n const isValid = segments.every(segment => /^[A-Z][a-zA-Z0-9]*$/.test(segment))\n\n if (!isValid) {\n const expectedName = ignoreMiddleExtensions\n ? `${toPascalCase(baseName)}${namePart.slice(baseName.length)}`\n : segments.map(toPascalCase).join('.')\n const expected = `${expectedName}${extension}`\n\n if (expected !== basename) {\n context.report({\n loc: { line: 1, column: 0 },\n messageId: 'invalid',\n data: { basename, expected },\n })\n }\n }\n\n return {}\n },\n}\n","import type { Rule } from 'eslint'\n\n\nexport const noMultilineImports: Rule.RuleModule = {\n meta: {\n type: 'layout',\n fixable: 'code',\n docs: {\n description: 'Disallow multiline imports',\n },\n schema: [],\n messages: {\n multilineImport: 'Imports must be written on a single line.',\n },\n },\n\n create(context) {\n const sourceCode = context.sourceCode\n\n return {\n ImportDeclaration(node) {\n const text = sourceCode.getText(node)\n\n if (!text.includes('\\n')) {\n return\n }\n\n context.report({\n node,\n messageId: 'multilineImport',\n\n fix(fixer) {\n const firstToken = sourceCode.getFirstToken(node)\n const lastToken = sourceCode.getLastToken(node)\n\n if (!firstToken || !lastToken) {\n return null\n }\n\n let importText = sourceCode.getText(node)\n\n importText = importText\n .replace(/\\s*\\{\\s*/g, ' { ')\n .replace(/\\s*\\}\\s*/g, ' } ')\n .replace(/\\s*,\\s*/g, ', ')\n .replace(/\\s+/g, ' ')\n .replace(/ \\{ /g, ' { ')\n .replace(/ \\} /g, ' } ')\n .replace(/\\s+from\\s+/g, ' from ')\n .trim()\n // Corrige espaços colapsados em torno de { e }\n .replace(/\\{ \\s+/g, '{ ')\n .replace(/\\s+ \\}/g, ' }')\n\n return fixer.replaceText(node, importText)\n },\n })\n },\n }\n },\n}\n","import type { Rule } from 'eslint'\n\n\nexport const sortImports: Rule.RuleModule = {\n meta: {\n type: 'layout',\n docs: {\n description: 'Sort imports by group and line length descending, collapsing multiline imports',\n },\n fixable: 'code',\n schema: [],\n messages: {\n sortRequired: 'As importações devem estar ordenadas por grupo e tamanho da linha, ocupando uma única linha.',\n },\n },\n create(context) {\n return {\n Program(node) {\n const sourceCode = context.sourceCode\n const content = sourceCode.text\n\n const newContent = getSortedContent(content)\n\n if (newContent && newContent !== content) {\n context.report({\n node,\n messageId: 'sortRequired',\n fix(fixer) {\n return fixer.replaceText(node, newContent)\n },\n })\n }\n },\n }\n },\n}\n\n// ---------------------------------------------------------------------------\n// Tipos auxiliares\n// ---------------------------------------------------------------------------\ntype TImportItem = {\n line: string\n from: string\n}\n\n// ---------------------------------------------------------------------------\n// Lógica Core - exportada para teste e reutilização\n// ---------------------------------------------------------------------------\nexport function getSortedContent(content: string): string | null {\n const collapseMultiline = (match: string) => {\n return match\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '')\n .replace(/\\s+/g, ' ')\n }\n\n const normalizedContent = content\n .replace(/import\\s+([^'\";]+?)\\s+from\\s+(['\"][^'\"]+['\"])/g, collapseMultiline)\n // Apenas re-exports válidos: export { ... } from / export * from / export * as X from / export type { ... } from\n .replace(/export\\s+(?:type\\s+)?(?:\\{[^}]*\\}|\\*(?:\\s+as\\s+\\w+)?)\\s+from\\s+(['\"][^'\"]+['\"])/g, collapseMultiline)\n\n const lines: string[] = normalizedContent.split('\\n')\n\n const directiveLines: string[] = []\n const reactFirstLine: string[] = []\n const externalLines: TImportItem[] = []\n const internalLines: TImportItem[] = []\n const reExportLines: TImportItem[] = []\n const nonImportLines: string[] = []\n\n let inImportBlock = false\n let canAcceptDirectives = true\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim()\n\n if (\n /^(function|const|let|var|class|interface|enum)\\b/.test(trimmed) ||\n (/^(type|export)\\b/.test(trimmed) && !/ from ['\"]/.test(trimmed) && !/^export\\s*\\{[^}]*\\}\\s*from/.test(trimmed) && !/^export\\s*\\*/.test(trimmed)) ||\n trimmed.startsWith('}')\n ) {\n canAcceptDirectives = false\n }\n\n if (inImportBlock && trimmed === '') continue\n\n if (canAcceptDirectives && /^['\"]use (client|server|strict)['\"];?$/.test(trimmed)) {\n directiveLines.push(lines[i])\n continue\n }\n\n const isReExport =\n /^export\\s+(type\\s+)?\\{[^}]*\\}\\s+from\\s+['\"]/.test(trimmed) ||\n /^export\\s+\\*(\\s+as\\s+\\w+)?\\s+from\\s+['\"]/.test(trimmed)\n\n if (isReExport) {\n const m = lines[i].match(/from\\s+['\"]([^'\"]+)['\"]/)\n if (m) reExportLines.push({ line: lines[i], from: m[1] })\n inImportBlock = true\n canAcceptDirectives = false\n continue\n }\n\n const isImport = /^import\\s/.test(trimmed) || /^import\\{/.test(trimmed)\n\n if (isImport) {\n inImportBlock = true\n canAcceptDirectives = false\n\n const fromMatch = lines[i].match(/from\\s+['\"]([^'\"]+)['\"]/)\n const seMatch = lines[i].match(/^import\\s+['\"]([^'\"]+)['\"]/)\n const from = fromMatch ? fromMatch[1] : seMatch ? seMatch[1] : null\n\n if (!from) {\n nonImportLines.push(lines[i])\n continue\n }\n\n const isTypeOnly = /^import\\s+type\\b/.test(trimmed)\n const isInternal = from.startsWith('.') || from.startsWith('@/')\n const isReactEntry = !isTypeOnly && (from === 'react' || from.startsWith('react/'))\n\n if (isReactEntry) {\n reactFirstLine.push(lines[i])\n } else if (isInternal) {\n internalLines.push({ line: lines[i], from })\n } else {\n externalLines.push({ line: lines[i], from })\n }\n continue\n }\n\n inImportBlock = false\n nonImportLines.push(lines[i])\n }\n\n if (reactFirstLine.length === 0 && externalLines.length === 0 && internalLines.length === 0 && reExportLines.length === 0) {\n return null\n }\n\n const byLengthDesc = (a: TImportItem, b: TImportItem) =>\n b.line.length !== a.line.length ? b.line.length - a.line.length : a.line.localeCompare(b.line)\n\n externalLines.sort(byLengthDesc)\n internalLines.sort(byLengthDesc)\n reExportLines.sort(byLengthDesc)\n\n const blocks: string[] = []\n\n if (directiveLines.length > 0) blocks.push(directiveLines.join('\\n'))\n\n const externalBlock = [...reactFirstLine, ...externalLines.map(i => i.line)]\n if (externalBlock.length > 0) {\n if (blocks.length > 0) blocks.push('')\n blocks.push(externalBlock.join('\\n'))\n }\n\n if (internalLines.length > 0) {\n if (blocks.length > 0) blocks.push('')\n blocks.push(internalLines.map(i => i.line).join('\\n'))\n }\n\n if (reExportLines.length > 0) {\n if (blocks.length > 0) blocks.push('')\n blocks.push(reExportLines.map(i => i.line).join('\\n'))\n }\n\n const rest = nonImportLines.join('\\n').replace(/^\\n+/, '')\n\n let newContent: string\n if (blocks.length > 0 && rest.length > 0) {\n newContent = blocks.join('\\n') + '\\n\\n\\n' + rest\n } else if (blocks.length > 0) {\n newContent = blocks.join('\\n') + '\\n'\n } else {\n newContent = rest\n }\n\n return newContent\n}\n","import { filenamePascalCase } from './rules/FilenamePascalCase'\nimport { noMultilineImports } from './rules/NoMultilineImports'\nimport { sortImports } from './rules/SortImports'\n\n\nexport const plugin = {\n meta: {\n name: 'eslint-plugin-ai-rules',\n version: '0.2.0',\n },\n rules: {\n 'filename-pascal-case': filenamePascalCase,\n 'no-multiline-imports': noMultilineImports,\n 'sort-imports': sortImports,\n },\n} as const\n","import type { ESLint } from 'eslint'\n\nimport { recommended } from './configs/recommended'\nimport { plugin } from './plugin'\n\nexport * from './rules/index'\n\n\nconst aiGuardPlugin: ESLint.Plugin = {\n ...plugin,\n configs: {\n recommended,\n },\n}\n\nexport default aiGuardPlugin\nexport { plugin }\nexport { recommended }"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/configs/recommended.ts","../src/rules/FilenamePascalCase.ts","../src/rules/NoMultilineImports.ts","../src/rules/ProjectStructure.ts","../src/utils/matchNameRule.ts","../src/utils/matchPathPattern.ts","../src/utils/matchFileRule.ts","../src/structures/hasStructureRules.ts","../src/rules/ProjectSetup.ts","../src/rules/SortImports.ts","../src/plugin.ts","../src/configs/projects.ts","../src/structures/buildRelationsConfig.ts","../src/structures/validateRelations.ts","../src/structures/validateStructure.ts","../src/structures/mergeRelations.ts","../src/structures/mergeStructure.ts","../src/structures/presets/helpers.ts","../src/structures/presets/frontend.ts","../src/structures/presets/backend.ts","../src/structures/presets/other.ts","../src/structures/presets/index.ts","../src/index.ts"],"sourcesContent":["import { createNodeResolver, importX } from 'eslint-plugin-import-x'\nimport stylistic from '@stylistic/eslint-plugin'\nimport tseslint from 'typescript-eslint'\nimport type { Linter } from 'eslint'\n\nimport { plugin } from '../plugin'\n\n\nexport const recommended: Linter.Config[] = [\n {\n plugins: {\n '@stylistic': stylistic,\n 'import-x': importX,\n 'ai-rules': plugin,\n '@typescript-eslint': tseslint.plugin,\n },\n settings: {\n 'import-x/resolver-next': [\n createNodeResolver({\n extensions: ['.ts', '.tsx', '.d.ts', '.js', '.jsx'],\n }),\n ],\n },\n rules: {\n 'ai-rules/sort-imports': 'error',\n 'ai-rules/no-multiline-imports': 'error',\n 'ai-rules/filename-pascal-case': 'error',\n 'ai-rules/project-setup': 'warn',\n 'max-len': 'off',\n 'import-x/no-duplicates': 'error',\n 'import-x/no-default-export': 'off',\n '@stylistic/semi': ['error', 'never'],\n '@typescript-eslint/consistent-type-imports': [\n 'error',\n { prefer: 'type-imports' },\n ],\n '@typescript-eslint/no-unused-vars': [\n 'error',\n { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },\n ],\n '@typescript-eslint/naming-convention': [\n 'error',\n { selector: 'interface', format: ['PascalCase'], prefix: ['I'] },\n { selector: 'typeAlias', format: ['PascalCase'], prefix: ['T'] },\n ],\n },\n },\n]\n\nexport default recommended\n","import type { Rule } from 'eslint'\nimport path from 'node:path'\n\n\ninterface IFilenamePascalCaseOptions {\n ignore?: Array<string | RegExp>\n ignoreMiddleExtensions?: boolean\n}\n\nexport const filenamePascalCase: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n docs: { description: 'Enforce PascalCase for file names' },\n schema: [\n {\n type: 'object',\n properties: {\n ignore: { type: 'array', items: { type: 'string' } },\n ignoreMiddleExtensions: { type: 'boolean' },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n invalid: 'File name \"{{basename}}\" must be in PascalCase. Rename to \"{{expected}}\".',\n },\n },\n create(context) {\n const options = (context.options[0] ?? {}) as IFilenamePascalCaseOptions\n const { ignore = [], ignoreMiddleExtensions = true } = options\n const ignoreMatchers = ignore.flatMap((pattern) => {\n try {\n return [pattern instanceof RegExp ? pattern : new RegExp(pattern)]\n } catch {\n return []\n }\n })\n\n const physicalFilename =\n // eslint 9 flat config\n (context as unknown as { getPhysicalFilename?: () => string }).getPhysicalFilename?.() ??\n (context as unknown as { physicalFilename?: string }).physicalFilename ??\n context.filename ??\n ''\n\n const basename = path.basename(physicalFilename)\n const cwd = process.cwd()\n const relativePath = physicalFilename.startsWith(cwd + path.sep)\n ? physicalFilename.slice(cwd.length + 1)\n : physicalFilename\n\n const isIgnored = ignoreMatchers.some((matcher) =>\n [basename, relativePath].some((target) => {\n matcher.lastIndex = 0\n return matcher.test(target)\n }),\n )\n\n if (isIgnored) return {}\n if (basename.startsWith('.')) return {}\n if (basename === 'index.ts' || basename === 'index.tsx' || basename === 'index.js' || basename === 'index.jsx') return {}\n if (basename.endsWith('.d.ts')) return {}\n if (basename.endsWith('.css')) return {}\n\n const extension = basename.match(/\\.(ts|tsx|js|jsx)$/)?.[0] ?? ''\n const namePart = extension ? basename.slice(0, -extension.length) : basename\n const baseName = namePart.split('.')[0]\n\n const toPascalCase = (value: string): string =>\n value\n .split(/[-_]/)\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n\n const segments = ignoreMiddleExtensions ? [baseName] : namePart.split('.')\n const isValid = segments.every(segment => /^[A-Z][a-zA-Z0-9]*$/.test(segment))\n\n if (!isValid) {\n const expectedName = ignoreMiddleExtensions\n ? `${toPascalCase(baseName)}${namePart.slice(baseName.length)}`\n : segments.map(toPascalCase).join('.')\n const expected = `${expectedName}${extension}`\n\n if (expected !== basename) {\n context.report({\n loc: { line: 1, column: 0 },\n messageId: 'invalid',\n data: { basename, expected },\n })\n }\n }\n\n return {}\n },\n}\n","import type { Rule } from 'eslint'\n\n\nexport const noMultilineImports: Rule.RuleModule = {\n meta: {\n type: 'layout',\n fixable: 'code',\n docs: {\n description: 'Disallow multiline imports',\n },\n schema: [],\n messages: {\n multilineImport: 'Imports must be written on a single line.',\n },\n },\n\n create(context) {\n const sourceCode = context.sourceCode\n\n return {\n ImportDeclaration(node) {\n const text = sourceCode.getText(node)\n\n if (!text.includes('\\n')) {\n return\n }\n\n context.report({\n node,\n messageId: 'multilineImport',\n\n fix(fixer) {\n const firstToken = sourceCode.getFirstToken(node)\n const lastToken = sourceCode.getLastToken(node)\n\n if (!firstToken || !lastToken) {\n return null\n }\n\n let importText = sourceCode.getText(node)\n\n importText = importText\n .replace(/\\s*\\{\\s*/g, ' { ')\n .replace(/\\s*\\}\\s*/g, ' } ')\n .replace(/\\s*,\\s*/g, ', ')\n .replace(/\\s+/g, ' ')\n .replace(/ \\{ /g, ' { ')\n .replace(/ \\} /g, ' } ')\n .replace(/\\s+from\\s+/g, ' from ')\n .trim()\n // Corrige espaços colapsados em torno de { e }\n .replace(/\\{ \\s+/g, '{ ')\n .replace(/\\s+ \\}/g, ' }')\n\n return fixer.replaceText(node, importText)\n },\n })\n },\n }\n },\n}\n","import type { Rule } from 'eslint'\nimport path from 'node:path'\n\nimport { describeFileRule, fileRuleMatchesExtension, matchesFileRule, } from '../utils/matchFileRule'\nimport type { IAiRulesSettings, IResolvedProject, IStructureNode, } from '../types/structure'\nimport { describeNameRule, matchesNameRule } from '../utils/matchNameRule'\nimport { matchPathPattern } from '../utils/matchPathPattern'\n\n\nconst DYNAMIC_FOLDER_PATTERN = /^\\[.+\\]$/\n\ntype TFolderNotAllowed = {\n messageId: 'folderNotAllowed'\n data: { folder: string; parent: string; allowed: string }\n}\n\ntype TFolderNameMismatch = {\n messageId: 'folderNameMismatch'\n data: { folder: string; parent: string; expected: string }\n}\n\ntype TFileNotAllowed = {\n messageId: 'fileNotAllowed'\n data: { file: string; parent: string; allowed: string }\n}\n\ntype TFileNameMismatch = {\n messageId: 'fileNameMismatch'\n data: { file: string; parent: string; expected: string }\n}\n\ntype TViolation =\n | TFolderNotAllowed\n | TFolderNameMismatch\n | TFileNotAllowed\n | TFileNameMismatch\n\ntype TFolderMatch = {\n node?: IStructureNode\n mismatch?: string\n}\n\nfunction getFileRules(node: IStructureNode) {\n return [...(node.files ?? []), ...(node.additionalFiles ?? [])]\n}\n\nfunction describeAllowedFolders(node: IStructureNode): string {\n const entries = Object.entries(node.folders ?? {})\n\n if (entries.length === 0) return 'none'\n\n return entries\n .map(([folderName, child]) => {\n if (!DYNAMIC_FOLDER_PATTERN.test(folderName)) return folderName\n if (!child.name) return folderName\n\n return `${folderName} (${describeNameRule(child.name)})`\n })\n .join(', ')\n}\n\nfunction describeAllowedFiles(node: IStructureNode): string {\n const rules = getFileRules(node)\n\n if (rules.length === 0) return 'none'\n\n return rules.map(describeFileRule).join(', ')\n}\n\nfunction matchFolder(node: IStructureNode, segment: string): TFolderMatch {\n let dynamicFolder:\n | { name: string; child: IStructureNode }\n | undefined\n\n for (const [folderName, child] of Object.entries(node.folders ?? {})) {\n if (folderName === segment) return { node: child }\n\n if (!dynamicFolder && DYNAMIC_FOLDER_PATTERN.test(folderName)) {\n dynamicFolder = { name: folderName, child }\n }\n }\n\n if (!dynamicFolder) return {}\n\n if (!dynamicFolder.child.name) return { node: dynamicFolder.child }\n\n if (matchesNameRule(segment, dynamicFolder.child.name)) {\n return { node: dynamicFolder.child }\n }\n\n return { mismatch: describeNameRule(dynamicFolder.child.name) }\n}\n\nfunction findViolation(\n relativePath: string,\n structure: IStructureNode,\n): TViolation | null {\n const segments = relativePath.split('/').filter(Boolean)\n let current = structure\n const consumed: string[] = []\n\n for (let index = 0; index < segments.length; index++) {\n const segment = segments[index]\n const isFile = index === segments.length - 1\n const parent = consumed.length > 0 ? consumed.join('/') : '.'\n\n if (isFile) {\n const rules = getFileRules(current)\n\n if (rules.some((rule) => matchesFileRule(segment, rule))) return null\n\n const matchingExtensionRules = rules.filter((rule) =>\n fileRuleMatchesExtension(segment, rule),\n )\n\n if (matchingExtensionRules.length > 0) {\n return {\n messageId: 'fileNameMismatch',\n data: {\n file: segment,\n parent,\n expected: matchingExtensionRules.map(describeFileRule).join(', '),\n },\n }\n }\n\n return {\n messageId: 'fileNotAllowed',\n data: {\n file: segment,\n parent,\n allowed: describeAllowedFiles(current),\n },\n }\n }\n\n const folderMatch = matchFolder(current, segment)\n\n if (folderMatch.node) {\n if (folderMatch.node.ignore) return null\n\n current = folderMatch.node\n consumed.push(segment)\n continue\n }\n\n if (folderMatch.mismatch) {\n return {\n messageId: 'folderNameMismatch',\n data: {\n folder: segment,\n parent,\n expected: folderMatch.mismatch,\n },\n }\n }\n\n return {\n messageId: 'folderNotAllowed',\n data: {\n folder: segment,\n parent,\n allowed: describeAllowedFolders(current),\n },\n }\n }\n\n return null\n}\n\nfunction findProject(\n projects: IResolvedProject[],\n fileAbsolutePath: string,\n cwd: string,\n): IResolvedProject | undefined {\n let matchedProject: IResolvedProject | undefined\n let matchedRootLength = -1\n\n for (const project of projects) {\n const rootAbsolutePath = path.resolve(cwd, project.rootFolder)\n const relativePath = path.relative(rootAbsolutePath, fileAbsolutePath)\n\n if (\n relativePath.length === 0 ||\n relativePath.startsWith('..') ||\n path.isAbsolute(relativePath)\n ) {\n continue\n }\n\n if (rootAbsolutePath.length > matchedRootLength) {\n matchedProject = project\n matchedRootLength = rootAbsolutePath.length\n }\n }\n\n return matchedProject\n}\n\nfunction getPhysicalFilename(context: Rule.RuleContext): string {\n return (\n (context as unknown as { getPhysicalFilename?: () => string })\n .getPhysicalFilename?.() ??\n (context as unknown as { physicalFilename?: string }).physicalFilename ??\n context.filename ??\n ''\n )\n}\n\nexport const projectStructure: Rule.RuleModule = {\n meta: {\n type: 'problem',\n docs: {\n description: 'Enforce the configured project folder and file structure',\n },\n schema: [],\n messages: {\n folderNotAllowed:\n 'Folder \"{{folder}}\" is not allowed inside \"{{parent}}\". Allowed folders: {{allowed}}.',\n folderNameMismatch:\n 'Folder \"{{folder}}\" inside \"{{parent}}\" must match {{expected}}.',\n fileNotAllowed:\n 'File \"{{file}}\" is not allowed inside \"{{parent}}\". Allowed files: {{allowed}}.',\n fileNameMismatch:\n 'File \"{{file}}\" inside \"{{parent}}\" must match {{expected}}.',\n },\n },\n create(context) {\n const settings = context.settings['ai-rules'] as IAiRulesSettings | undefined\n const projects =\n settings?.projects ??\n (settings?.project ? [settings.project] : [])\n\n if (projects.length === 0) return {}\n\n return {\n Program(node) {\n const physicalFilename = getPhysicalFilename(context)\n\n if (\n !physicalFilename ||\n physicalFilename === '<input>' ||\n physicalFilename === '<text>'\n ) {\n return\n }\n\n const cwd = process.cwd()\n const fileAbsolutePath = path.resolve(cwd, physicalFilename)\n const project = findProject(projects, fileAbsolutePath, cwd)\n\n if (!project || !project.structure) return\n\n const rootAbsolutePath = path.resolve(cwd, project.rootFolder)\n const relativePath = path\n .relative(rootAbsolutePath, fileAbsolutePath)\n .split(path.sep)\n .join('/')\n\n if (\n relativePath.length === 0 ||\n project.structure.ignore ||\n (project.structure.ignoredPaths ?? []).some((pattern) =>\n matchPathPattern(relativePath, pattern),\n )\n ) {\n return\n }\n\n const violation = findViolation(relativePath, project.structure)\n\n if (!violation) return\n\n switch (violation.messageId) {\n case 'folderNotAllowed':\n context.report({\n node,\n messageId: 'folderNotAllowed',\n data: violation.data,\n })\n break\n case 'folderNameMismatch':\n context.report({\n node,\n messageId: 'folderNameMismatch',\n data: violation.data,\n })\n break\n case 'fileNotAllowed':\n context.report({\n node,\n messageId: 'fileNotAllowed',\n data: violation.data,\n })\n break\n case 'fileNameMismatch':\n context.report({\n node,\n messageId: 'fileNameMismatch',\n data: violation.data,\n })\n break\n }\n },\n }\n },\n}\n","import type { INameRule, TNameCase } from '../types/structure'\n\n\nconst CASE_PATTERNS: Record<TNameCase, RegExp> = {\n PascalCase: /^[A-Z][a-zA-Z0-9]*$/,\n camelCase: /^[a-z][a-zA-Z0-9]*$/,\n 'kebab-case': /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/,\n snake_case: /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/,\n}\n\nexport const NAME_CASES = Object.keys(CASE_PATTERNS) as TNameCase[]\n\nexport function isNameCase(value: string): value is TNameCase {\n return value in CASE_PATTERNS\n}\n\nexport function matchesNameCase(value: string, caseName: TNameCase): boolean {\n return CASE_PATTERNS[caseName].test(value)\n}\n\nexport function matchesNameRule(value: string, rule: INameRule): boolean {\n if (rule.case && !matchesNameCase(value, rule.case)) return false\n if (rule.prefix && !value.startsWith(rule.prefix)) return false\n if (rule.suffix && !value.endsWith(rule.suffix)) return false\n if (rule.pattern) {\n try {\n if (!new RegExp(rule.pattern).test(value)) return false\n } catch {\n return false\n }\n }\n return true\n}\n\nexport function describeNameRule(rule: INameRule): string {\n const parts: string[] = []\n\n if (rule.case) parts.push(rule.case)\n if (rule.prefix) parts.push(`prefix \"${rule.prefix}\"`)\n if (rule.suffix) parts.push(`suffix \"${rule.suffix}\"`)\n if (rule.pattern) parts.push(`pattern /${rule.pattern}/`)\n\n return parts.length > 0 ? parts.join(', ') : 'any name'\n}\n","function expandBraces(pattern: string): string[] {\n const match = pattern.match(/\\{([^{}]+)\\}/)\n\n if (!match) return [pattern]\n\n const [fullMatch, body] = match\n const alternatives = body.split(',')\n\n return alternatives.flatMap((alternative) =>\n expandBraces(pattern.replace(fullMatch, () => alternative)),\n )\n}\n\nfunction globToRegExp(pattern: string): RegExp {\n let source = '^'\n\n for (let index = 0; index < pattern.length; index++) {\n const char = pattern[index]\n\n if (char === '*') {\n if (pattern[index + 1] === '*') {\n if (pattern[index + 2] === '/') {\n source += '(?:.*/)?'\n index += 2\n } else {\n source += '.*'\n index += 1\n }\n } else {\n source += '[^/]*'\n }\n continue\n }\n\n if (char === '?') {\n source += '[^/]'\n continue\n }\n\n if ('\\\\^$+?.()|{}[]'.includes(char)) {\n source += `\\\\${char}`\n continue\n }\n\n source += char\n }\n\n source += '$'\n\n return new RegExp(source)\n}\n\nexport function normalizePathPattern(value: string): string {\n return value.replaceAll('\\\\', '/').replace(/^\\.\\//, '')\n}\n\nexport function matchPathPattern(value: string, pattern: string): boolean {\n const normalizedValue = normalizePathPattern(value)\n\n return expandBraces(normalizePathPattern(pattern)).some((expandedPattern) =>\n globToRegExp(expandedPattern).test(normalizedValue),\n )\n}\n","import { describeNameRule, matchesNameRule } from './matchNameRule'\nimport { matchPathPattern } from './matchPathPattern'\nimport type { TFileRule } from '../types/structure'\n\n\nexport function getMatchingExtension(\n filename: string,\n extensions: string[],\n): string | undefined {\n return [...extensions]\n .sort((left, right) => right.length - left.length)\n .find((extension) => filename.endsWith(extension))\n}\n\nexport function matchesFileRule(filename: string, rule: TFileRule): boolean {\n if (typeof rule === 'string') return matchPathPattern(filename, rule)\n\n const extension = getMatchingExtension(filename, rule.extensions)\n\n if (!extension) return false\n\n const baseName = filename.slice(0, -extension.length)\n\n return matchesNameRule(baseName, rule)\n}\n\nexport function fileRuleMatchesExtension(filename: string, rule: TFileRule): boolean {\n if (typeof rule === 'string') return false\n\n return getMatchingExtension(filename, rule.extensions) !== undefined\n}\n\nexport function describeFileRule(rule: TFileRule): string {\n if (typeof rule === 'string') return rule\n\n const extensions = rule.extensions.join(', ')\n\n return `${describeNameRule(rule)}, extension ${extensions}`\n}\n","import type { IProjectStructure } from '../types/structure'\n\n\nexport function hasStructureRules(structure: IProjectStructure): boolean {\n return (\n structure.ignore !== undefined ||\n structure.name !== undefined ||\n structure.files !== undefined ||\n structure.additionalFiles !== undefined ||\n structure.folders !== undefined\n )\n}\n","import type { Rule } from 'eslint'\n\nimport type { IAiRulesSettings, IResolvedProject } from '../types/structure'\nimport { hasStructureRules } from '../structures/hasStructureRules'\n\n\nlet hasWarned = false\n\nfunction isConfiguredProject(project: IResolvedProject): boolean {\n if (project.relations) return true\n\n if (\n project.preset === 'frontend' ||\n project.preset === 'backend' ||\n project.preset === 'other'\n ) {\n return true\n }\n\n return Boolean(project.structure && hasStructureRules(project.structure))\n}\n\nfunction warnOnce(): void {\n if (hasWarned) return\n if (\n process.env.AI_RULES_SILENT === '1' ||\n process.env.AI_RULES_SILENT === 'true'\n ) {\n return\n }\n\n hasWarned = true\n console.warn(\n [\n '[eslint-plugin-ai-rules] Project structure validation is not configured.',\n \"Configure it with aiRules.configs.projects([{ rootFolder: '.', preset: 'frontend' | 'backend' }]).\",\n \"If this project is not a frontend/backend, use preset: 'other' to disable this warning.\",\n ].join('\\n'),\n )\n}\n\nexport const projectSetup: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Warn when the project structure validation is not configured',\n },\n schema: [],\n messages: {},\n },\n create(context) {\n return {\n Program() {\n const settings = context.settings['ai-rules'] as IAiRulesSettings | undefined\n const projects =\n settings?.projects ??\n (settings?.project ? [settings.project] : [])\n\n if (projects.some(isConfiguredProject)) return\n\n warnOnce()\n },\n }\n },\n}\n","import type { Rule } from 'eslint'\n\n\nexport const sortImports: Rule.RuleModule = {\n meta: {\n type: 'layout',\n docs: {\n description: 'Sort imports by group and line length descending, collapsing multiline imports',\n },\n fixable: 'code',\n schema: [],\n messages: {\n sortRequired: 'As importações devem estar ordenadas por grupo e tamanho da linha, ocupando uma única linha.',\n },\n },\n create(context) {\n return {\n Program(node) {\n const sourceCode = context.sourceCode\n const content = sourceCode.text\n\n const newContent = getSortedContent(content)\n\n if (newContent && newContent !== content) {\n context.report({\n node,\n messageId: 'sortRequired',\n fix(fixer) {\n return fixer.replaceText(node, newContent)\n },\n })\n }\n },\n }\n },\n}\n\n// ---------------------------------------------------------------------------\n// Tipos auxiliares\n// ---------------------------------------------------------------------------\ntype TImportItem = {\n line: string\n from: string\n}\n\n// ---------------------------------------------------------------------------\n// Lógica Core - exportada para teste e reutilização\n// ---------------------------------------------------------------------------\nexport function getSortedContent(content: string): string | null {\n const collapseMultiline = (match: string) => {\n return match\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/.*$/gm, '')\n .replace(/\\s+/g, ' ')\n }\n\n const normalizedContent = content\n .replace(/import\\s+([^'\";]+?)\\s+from\\s+(['\"][^'\"]+['\"])/g, collapseMultiline)\n // Apenas re-exports válidos: export { ... } from / export * from / export * as X from / export type { ... } from\n .replace(/export\\s+(?:type\\s+)?(?:\\{[^}]*\\}|\\*(?:\\s+as\\s+\\w+)?)\\s+from\\s+(['\"][^'\"]+['\"])/g, collapseMultiline)\n\n const lines: string[] = normalizedContent.split('\\n')\n\n const directiveLines: string[] = []\n const reactFirstLine: string[] = []\n const externalLines: TImportItem[] = []\n const internalLines: TImportItem[] = []\n const reExportLines: TImportItem[] = []\n const nonImportLines: string[] = []\n\n let inImportBlock = false\n let canAcceptDirectives = true\n\n for (let i = 0; i < lines.length; i++) {\n const trimmed = lines[i].trim()\n\n if (\n /^(function|const|let|var|class|interface|enum)\\b/.test(trimmed) ||\n (/^(type|export)\\b/.test(trimmed) && !/ from ['\"]/.test(trimmed) && !/^export\\s*\\{[^}]*\\}\\s*from/.test(trimmed) && !/^export\\s*\\*/.test(trimmed)) ||\n trimmed.startsWith('}')\n ) {\n canAcceptDirectives = false\n }\n\n if (inImportBlock && trimmed === '') continue\n\n if (canAcceptDirectives && /^['\"]use (client|server|strict)['\"];?$/.test(trimmed)) {\n directiveLines.push(lines[i])\n continue\n }\n\n const isReExport =\n /^export\\s+(type\\s+)?\\{[^}]*\\}\\s+from\\s+['\"]/.test(trimmed) ||\n /^export\\s+\\*(\\s+as\\s+\\w+)?\\s+from\\s+['\"]/.test(trimmed)\n\n if (isReExport) {\n const m = lines[i].match(/from\\s+['\"]([^'\"]+)['\"]/)\n if (m) reExportLines.push({ line: lines[i], from: m[1] })\n inImportBlock = true\n canAcceptDirectives = false\n continue\n }\n\n const isImport = /^import\\s/.test(trimmed) || /^import\\{/.test(trimmed)\n\n if (isImport) {\n inImportBlock = true\n canAcceptDirectives = false\n\n const fromMatch = lines[i].match(/from\\s+['\"]([^'\"]+)['\"]/)\n const seMatch = lines[i].match(/^import\\s+['\"]([^'\"]+)['\"]/)\n const from = fromMatch ? fromMatch[1] : seMatch ? seMatch[1] : null\n\n if (!from) {\n nonImportLines.push(lines[i])\n continue\n }\n\n const isTypeOnly = /^import\\s+type\\b/.test(trimmed)\n const isInternal = from.startsWith('.') || from.startsWith('@/')\n const isReactEntry = !isTypeOnly && (from === 'react' || from.startsWith('react/'))\n\n if (isReactEntry) {\n reactFirstLine.push(lines[i])\n } else if (isInternal) {\n internalLines.push({ line: lines[i], from })\n } else {\n externalLines.push({ line: lines[i], from })\n }\n continue\n }\n\n inImportBlock = false\n nonImportLines.push(lines[i])\n }\n\n if (reactFirstLine.length === 0 && externalLines.length === 0 && internalLines.length === 0 && reExportLines.length === 0) {\n return null\n }\n\n const byLengthDesc = (a: TImportItem, b: TImportItem) =>\n b.line.length !== a.line.length ? b.line.length - a.line.length : a.line.localeCompare(b.line)\n\n externalLines.sort(byLengthDesc)\n internalLines.sort(byLengthDesc)\n reExportLines.sort(byLengthDesc)\n\n const blocks: string[] = []\n\n if (directiveLines.length > 0) blocks.push(directiveLines.join('\\n'))\n\n const externalBlock = [...reactFirstLine, ...externalLines.map(i => i.line)]\n if (externalBlock.length > 0) {\n if (blocks.length > 0) blocks.push('')\n blocks.push(externalBlock.join('\\n'))\n }\n\n if (internalLines.length > 0) {\n if (blocks.length > 0) blocks.push('')\n blocks.push(internalLines.map(i => i.line).join('\\n'))\n }\n\n if (reExportLines.length > 0) {\n if (blocks.length > 0) blocks.push('')\n blocks.push(reExportLines.map(i => i.line).join('\\n'))\n }\n\n const rest = nonImportLines.join('\\n').replace(/^\\n+/, '')\n\n let newContent: string\n if (blocks.length > 0 && rest.length > 0) {\n newContent = blocks.join('\\n') + '\\n\\n\\n' + rest\n } else if (blocks.length > 0) {\n newContent = blocks.join('\\n') + '\\n'\n } else {\n newContent = rest\n }\n\n return newContent\n}\n","import { filenamePascalCase } from './rules/FilenamePascalCase'\nimport { noMultilineImports } from './rules/NoMultilineImports'\nimport { projectStructure } from './rules/ProjectStructure'\nimport { projectSetup } from './rules/ProjectSetup'\nimport { sortImports } from './rules/SortImports'\n\n\nexport const plugin = {\n meta: {\n name: 'eslint-plugin-ai-rules',\n version: '0.3.0',\n },\n rules: {\n 'filename-pascal-case': filenamePascalCase,\n 'no-multiline-imports': noMultilineImports,\n 'project-setup': projectSetup,\n 'project-structure': projectStructure,\n 'sort-imports': sortImports,\n },\n} as const\n","import boundaries from 'eslint-plugin-boundaries'\nimport type { Linter } from 'eslint'\nimport path from 'node:path'\n\nimport type { IProjectDefinition, IProjectPreset, IProjectStructure, TProjectPreset, } from '../types/structure'\nimport { buildRelationsRuleOptions, buildRelationsSettings } from '../structures/buildRelationsConfig'\nimport { hasStructureRules } from '../structures/hasStructureRules'\nimport { validateRelations } from '../structures/validateRelations'\nimport { validateStructure } from '../structures/validateStructure'\nimport { mergeRelations } from '../structures/mergeRelations'\nimport { mergeStructure } from '../structures/mergeStructure'\nimport { getPreset } from '../structures/presets'\nimport { recommended } from './recommended'\n\n\nconst PROJECT_PRESETS: TProjectPreset[] = ['frontend', 'backend', 'other']\n\nfunction normalizeRootFolder(rootFolder: string): string {\n const absolutePath = path.resolve(process.cwd(), rootFolder.trim())\n const relativePath = path.relative(process.cwd(), absolutePath)\n\n if (relativePath.length === 0) return '.'\n\n if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {\n throw new Error(\n `Invalid project: rootFolder \"${rootFolder}\" must be inside the current working directory.`,\n )\n }\n\n return relativePath.split(path.sep).join('/')\n}\n\nfunction isInside(parent: string, child: string): boolean {\n if (parent === child) return false\n if (parent === '.') return true\n\n return child.startsWith(`${parent}/`)\n}\n\nfunction findNestedRoots(\n rootFolder: string,\n definitions: Array<{ rootFolder: string }>,\n): string[] {\n return definitions\n .map((definition) => definition.rootFolder)\n .filter((candidate) => isInside(rootFolder, candidate))\n}\n\nfunction validateDefinition(\n definition: IProjectDefinition,\n index: number,\n): void {\n if (!definition || typeof definition !== 'object') {\n throw new Error(`Invalid project at index ${index}: definition must be an object.`)\n }\n\n if (\n typeof definition.rootFolder !== 'string' ||\n definition.rootFolder.trim().length === 0\n ) {\n throw new Error(\n `Invalid project at index ${index}: rootFolder must be a non-empty string.`,\n )\n }\n\n if (\n definition.preset !== undefined &&\n !PROJECT_PRESETS.includes(definition.preset)\n ) {\n throw new Error(\n `Invalid project at index ${index}: preset must be one of: ${PROJECT_PRESETS.join(', ')}.`,\n )\n }\n\n if (definition.structure !== undefined) {\n try {\n validateStructure(definition.structure)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n throw new Error(`Invalid project at index ${index}: ${message}`, {\n cause: error,\n })\n }\n }\n\n if (definition.relations !== undefined) {\n try {\n validateRelations(definition.relations, { validateReferences: false })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n throw new Error(`Invalid project at index ${index}: ${message}`, {\n cause: error,\n })\n }\n }\n}\n\nfunction resolveStructure(\n definition: IProjectDefinition,\n preset?: IProjectPreset,\n): IProjectStructure {\n return mergeStructure(preset?.structure, definition.structure)\n}\n\nexport function projects(definitions: IProjectDefinition[]): Linter.Config[] {\n if (!Array.isArray(definitions) || definitions.length === 0) {\n throw new Error('projects() requires a non-empty array of project definitions.')\n }\n\n const normalizedDefinitions = definitions.map((definition, index) => {\n validateDefinition(definition, index)\n\n return {\n ...definition,\n rootFolder: normalizeRootFolder(definition.rootFolder),\n }\n })\n\n const seenRoots = new Set<string>()\n\n for (const definition of normalizedDefinitions) {\n if (seenRoots.has(definition.rootFolder)) {\n throw new Error(\n `Invalid projects: rootFolder \"${definition.rootFolder}\" is duplicated.`,\n )\n }\n\n seenRoots.add(definition.rootFolder)\n }\n\n return normalizedDefinitions.map((definition, index) => {\n const preset = definition.preset ? getPreset(definition.preset) : undefined\n const structure = resolveStructure(definition, preset)\n const structureEnabled = hasStructureRules(structure)\n const relations = mergeRelations(preset?.relations, definition.relations)\n\n if (relations) {\n try {\n validateRelations(relations)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n throw new Error(`Invalid project at index ${index}: ${message}`, {\n cause: error,\n })\n }\n }\n const rootAbsolutePath = path.resolve(process.cwd(), definition.rootFolder)\n const baseConfig = recommended[0]\n const rootPrefix = definition.rootFolder === '.'\n ? ''\n : `${definition.rootFolder}/`\n const nestedRoots = findNestedRoots(\n definition.rootFolder,\n normalizedDefinitions,\n )\n const ignoredPaths = Array.from(new Set([\n ...(structure.ignoredPaths ?? []).map(\n (pattern) => `${rootPrefix}${pattern}`,\n ),\n ...nestedRoots.map((nestedRoot) => `${nestedRoot}/**`),\n ]))\n const rules: Linter.RulesRecord = {\n ...baseConfig.rules,\n ...(preset?.rules ?? {}),\n 'ai-rules/project-structure': structureEnabled ? 'error' : 'off',\n 'ai-rules/filename-pascal-case': structureEnabled\n ? 'off'\n : baseConfig.rules?.['ai-rules/filename-pascal-case'] ?? 'error',\n ...(relations\n ? {\n 'boundaries/dependencies': [\n 'error',\n buildRelationsRuleOptions(relations),\n ],\n }\n : {}),\n }\n\n return {\n ...baseConfig,\n plugins: {\n ...baseConfig.plugins,\n ...(relations ? { boundaries } : {}),\n },\n files: [`${rootPrefix}**/*.{js,cjs,mjs,jsx,ts,tsx}`],\n ...(ignoredPaths.length > 0 ? { ignores: ignoredPaths } : {}),\n settings: {\n ...baseConfig.settings,\n ...(relations\n ? buildRelationsSettings(relations, rootAbsolutePath)\n : {}),\n 'ai-rules': {\n project: {\n rootFolder: definition.rootFolder,\n preset: definition.preset,\n structure,\n relations,\n },\n },\n },\n rules,\n }\n })\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\n\nimport type { IRelationsConfig, IRelationsRule, IRelationsScope, } from '../types/structure'\n\n\nfunction layerPatterns(\n paths: string | string[],\n): string[] {\n return Array.isArray(paths) ? paths : [paths]\n}\n\nexport function buildRelationsSettings(\n relations: IRelationsConfig,\n rootAbsolutePath: string,\n): Record<string, unknown> {\n const resolver: Record<string, unknown> = {\n node: {\n extensions: ['.js', '.jsx', '.ts', '.tsx', '.d.ts', '.mjs', '.cjs'],\n },\n }\n\n if (existsSync(path.join(rootAbsolutePath, 'tsconfig.json'))) {\n resolver.typescript = {\n alwaysTryTypes: true,\n project: rootAbsolutePath,\n }\n }\n\n return {\n 'boundaries/root-path': rootAbsolutePath,\n 'boundaries/elements': Object.entries(relations.layers).map(\n ([type, pattern]) => ({\n type,\n pattern: layerPatterns(pattern),\n partialMatch: false,\n ...(relations.scope?.layers.includes(type)\n ? { capture: [relations.scope.capture] }\n : {}),\n }),\n ),\n 'import/resolver': resolver,\n }\n}\n\nfunction fromSelector(from: string): Record<string, unknown> {\n return {\n element: {\n type: from,\n },\n }\n}\n\nfunction targetSelector(type: string): Record<string, unknown> {\n return {\n to: {\n element: {\n type,\n },\n },\n }\n}\n\nfunction scopedTargetSelector(\n type: string,\n scope: IRelationsScope,\n): Record<string, unknown> {\n return {\n to: {\n element: {\n type,\n captured: {\n [scope.capture]: `{{ from.element.captured.${scope.capture} }}`,\n },\n },\n },\n }\n}\n\nfunction buildDisallowPolicy(\n rule: IRelationsRule,\n targetLayer: string,\n): Record<string, unknown> {\n return {\n from: fromSelector(rule.from),\n disallow: targetSelector(targetLayer),\n ...(rule.message ? { message: rule.message } : {}),\n }\n}\n\nfunction buildScopedAllowPolicy(\n rule: IRelationsRule,\n targetLayer: string,\n scope: IRelationsScope,\n): Record<string, unknown> {\n return {\n from: fromSelector(rule.from),\n allow: scopedTargetSelector(targetLayer, scope),\n }\n}\n\nfunction buildTypeAllowPolicy(\n from: string,\n): Record<string, unknown> {\n return {\n from: fromSelector(from),\n allow: {\n dependency: {\n kind: 'type',\n },\n },\n }\n}\n\nexport function buildRelationsRuleOptions(\n relations: IRelationsConfig,\n): Record<string, unknown> {\n const layerNames = Object.keys(relations.layers)\n const scope = relations.scope\n const scopeLayers = new Set(scope?.layers ?? [])\n const policies: Array<Record<string, unknown>> = []\n\n for (const rule of relations.rules) {\n const fromIsScoped = Boolean(\n scope && scopeLayers.has(rule.from),\n )\n\n if (rule.allow) {\n const allowedLayers = new Set(rule.allow)\n\n for (const layerName of layerNames) {\n if (layerName === rule.from) continue\n\n if (!allowedLayers.has(layerName)) {\n policies.push(buildDisallowPolicy(rule, layerName))\n continue\n }\n\n if (fromIsScoped && scope && scopeLayers.has(layerName)) {\n policies.push(buildDisallowPolicy(rule, layerName))\n policies.push(buildScopedAllowPolicy(rule, layerName, scope))\n }\n }\n } else if (rule.deny) {\n for (const layerName of rule.deny) {\n if (layerName === rule.from) continue\n\n policies.push(buildDisallowPolicy(rule, layerName))\n }\n }\n\n const allowSameLayer = rule.allowSameLayer ?? true\n\n if (!allowSameLayer) {\n policies.push(buildDisallowPolicy(rule, rule.from))\n } else if (fromIsScoped && scope) {\n policies.push(buildDisallowPolicy(rule, rule.from))\n policies.push(buildScopedAllowPolicy(rule, rule.from, scope))\n }\n\n const allowTypeImports =\n rule.allowTypeImports ?? relations.allowTypeImports ?? false\n\n if (allowTypeImports) {\n policies.push(buildTypeAllowPolicy(rule.from))\n }\n }\n\n const checkInternals = relations.rules.some(\n (rule) => rule.allowSameLayer === false,\n )\n\n return {\n default: 'allow',\n checkAllOrigins: false,\n checkUnknownLocals: false,\n checkInternals,\n policies,\n }\n}\n","import type { IRelationsConfig } from '../types/structure'\n\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction assertString(value: unknown, path: string): asserts value is string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new Error(`Invalid relations: \"${path}\" must be a non-empty string.`)\n }\n}\n\nfunction validatePaths(value: unknown, path: string): void {\n const paths = Array.isArray(value) ? value : [value]\n\n if (paths.length === 0) {\n throw new Error(`Invalid relations: \"${path}\" must contain at least one path.`)\n }\n\n paths.forEach((entry, index) => {\n assertString(entry, Array.isArray(value) ? `${path}[${index}]` : path)\n })\n}\n\nfunction validateLayerReferences(\n value: unknown,\n path: string,\n layerNames: Set<string>,\n validateReferences: boolean,\n): void {\n if (!Array.isArray(value)) {\n throw new Error(`Invalid relations: \"${path}\" must be an array.`)\n }\n\n value.forEach((layerName, index) => {\n assertString(layerName, `${path}[${index}]`)\n\n if (validateReferences && !layerNames.has(layerName)) {\n throw new Error(\n `Invalid relations: \"${path}[${index}]\" references unknown layer \"${layerName}\".`,\n )\n }\n })\n}\n\nexport function validateRelations(\n value: unknown,\n options: { validateReferences?: boolean } = {},\n): asserts value is IRelationsConfig {\n const validateReferences = options.validateReferences ?? true\n if (!isRecord(value)) {\n throw new Error('Invalid relations: relations must be an object.')\n }\n\n if (!isRecord(value.layers)) {\n throw new Error('Invalid relations: \"relations.layers\" must be an object.')\n }\n\n const layers = value.layers\n const layerNames = new Set(Object.keys(layers))\n\n if (layerNames.size === 0) {\n throw new Error('Invalid relations: \"relations.layers\" cannot be empty.')\n }\n\n for (const [layerName, paths] of Object.entries(layers)) {\n assertString(layerName, 'relations.layers key')\n validatePaths(paths, `relations.layers.${layerName}`)\n }\n\n if (value.allowTypeImports !== undefined && typeof value.allowTypeImports !== 'boolean') {\n throw new Error('Invalid relations: \"relations.allowTypeImports\" must be a boolean.')\n }\n\n if (!Array.isArray(value.rules)) {\n throw new Error('Invalid relations: \"relations.rules\" must be an array.')\n }\n\n const fromLayers = new Set<string>()\n\n value.rules.forEach((rule, index) => {\n const rulePath = `relations.rules[${index}]`\n\n if (!isRecord(rule)) {\n throw new Error(`Invalid relations: \"${rulePath}\" must be an object.`)\n }\n\n assertString(rule.from, `${rulePath}.from`)\n\n if (validateReferences && !layerNames.has(rule.from)) {\n throw new Error(\n `Invalid relations: \"${rulePath}.from\" references unknown layer \"${rule.from}\".`,\n )\n }\n\n if (fromLayers.has(rule.from)) {\n throw new Error(\n `Invalid relations: duplicate rule for layer \"${rule.from}\" at \"${rulePath}\".`,\n )\n }\n\n fromLayers.add(rule.from)\n\n const hasAllow = rule.allow !== undefined\n const hasDeny = rule.deny !== undefined\n\n if (hasAllow === hasDeny) {\n throw new Error(\n `Invalid relations: \"${rulePath}\" must define exactly one of \"allow\" or \"deny\".`,\n )\n }\n\n if (hasAllow) validateLayerReferences(rule.allow, `${rulePath}.allow`, layerNames, validateReferences)\n if (hasDeny) validateLayerReferences(rule.deny, `${rulePath}.deny`, layerNames, validateReferences)\n\n const layerReferences = (hasAllow ? rule.allow : rule.deny) as string[]\n\n if (validateReferences && layerReferences.includes(rule.from)) {\n throw new Error(\n `Invalid relations: \"${rulePath}\" cannot reference its own layer; use \"allowSameLayer\" instead.`,\n )\n }\n\n if (rule.allowSameLayer !== undefined && typeof rule.allowSameLayer !== 'boolean') {\n throw new Error(`Invalid relations: \"${rulePath}.allowSameLayer\" must be a boolean.`)\n }\n\n if (rule.allowTypeImports !== undefined && typeof rule.allowTypeImports !== 'boolean') {\n throw new Error(`Invalid relations: \"${rulePath}.allowTypeImports\" must be a boolean.`)\n }\n\n if (rule.message !== undefined) assertString(rule.message, `${rulePath}.message`)\n })\n\n if (value.scope !== undefined) {\n if (!isRecord(value.scope)) {\n throw new Error('Invalid relations: \"relations.scope\" must be an object.')\n }\n\n assertString(value.scope.capture, 'relations.scope.capture')\n\n if (!Array.isArray(value.scope.layers) || value.scope.layers.length === 0) {\n throw new Error(\n 'Invalid relations: \"relations.scope.layers\" must be a non-empty array.',\n )\n }\n\n const scopeLayers = new Set<string>()\n\n value.scope.layers.forEach((layerName, index) => {\n assertString(layerName, `relations.scope.layers[${index}]`)\n\n if (validateReferences && !layerNames.has(layerName)) {\n throw new Error(\n `Invalid relations: \"relations.scope.layers[${index}]\" references unknown layer \"${layerName}\".`,\n )\n }\n\n if (scopeLayers.has(layerName)) {\n throw new Error(\n `Invalid relations: duplicate scope layer \"${layerName}\".`,\n )\n }\n\n scopeLayers.add(layerName)\n\n if (!validateReferences) return\n\n const layerPaths = Array.isArray(layers[layerName])\n ? layers[layerName] as string[]\n : [layers[layerName] as string]\n\n if (!layerPaths.every((layerPath) => layerPath.includes('*'))) {\n throw new Error(\n `Invalid relations: scope layer \"${layerName}\" must use a pattern with a wildcard.`,\n )\n }\n })\n\n }\n}\n","import type { IProjectStructure } from '../types/structure'\nimport { isNameCase } from '../utils/matchNameRule'\n\n\nconst DYNAMIC_FOLDER_PATTERN = /^\\[.+\\]$/\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction assertString(value: unknown, path: string): asserts value is string {\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`Invalid structure: \"${path}\" must be a non-empty string.`)\n }\n}\n\nfunction validateRegex(value: unknown, path: string): void {\n assertString(value, path)\n\n try {\n new RegExp(value)\n } catch {\n throw new Error(`Invalid structure: \"${path}\" must be a valid regular expression.`)\n }\n}\n\nfunction validateNameRule(value: unknown, path: string): void {\n if (!isRecord(value)) {\n throw new Error(`Invalid structure: \"${path}\" must be an object.`)\n }\n\n if (value.case !== undefined) {\n if (typeof value.case !== 'string' || !isNameCase(value.case)) {\n throw new Error(\n `Invalid structure: \"${path}.case\" must be one of: PascalCase, camelCase, kebab-case, snake_case.`,\n )\n }\n }\n\n if (value.prefix !== undefined) assertString(value.prefix, `${path}.prefix`)\n if (value.suffix !== undefined) assertString(value.suffix, `${path}.suffix`)\n if (value.pattern !== undefined) validateRegex(value.pattern, `${path}.pattern`)\n}\n\nfunction validateFileRule(value: unknown, path: string): void {\n if (typeof value === 'string') {\n assertString(value, path)\n return\n }\n\n if (!isRecord(value)) {\n throw new Error(`Invalid structure: \"${path}\" must be a string or an object.`)\n }\n\n if (!Array.isArray(value.extensions) || value.extensions.length === 0) {\n throw new Error(\n `Invalid structure: \"${path}.extensions\" must be a non-empty array of strings.`,\n )\n }\n\n value.extensions.forEach((extension, index) => {\n if (typeof extension !== 'string' || !extension.startsWith('.')) {\n throw new Error(\n `Invalid structure: \"${path}.extensions[${index}]\" must start with a dot.`,\n )\n }\n })\n\n if (value.case !== undefined) {\n if (typeof value.case !== 'string' || !isNameCase(value.case)) {\n throw new Error(\n `Invalid structure: \"${path}.case\" must be one of: PascalCase, camelCase, kebab-case, snake_case.`,\n )\n }\n }\n\n if (value.prefix !== undefined) assertString(value.prefix, `${path}.prefix`)\n if (value.suffix !== undefined) assertString(value.suffix, `${path}.suffix`)\n if (value.pattern !== undefined) validateRegex(value.pattern, `${path}.pattern`)\n}\n\nfunction validateFileRules(value: unknown, path: string): void {\n if (!Array.isArray(value)) {\n throw new Error(`Invalid structure: \"${path}\" must be an array.`)\n }\n\n value.forEach((rule, index) => validateFileRule(rule, `${path}[${index}]`))\n}\n\nfunction validateNode(\n value: unknown,\n path: string,\n isRoot = false,\n): asserts value is Record<string, unknown> {\n if (!isRecord(value)) {\n throw new Error(`Invalid structure: \"${path}\" must be an object.`)\n }\n\n if (value.name !== undefined) {\n if (isRoot) {\n throw new Error(`Invalid structure: \"${path}.name\" is only allowed for dynamic folders.`)\n }\n\n validateNameRule(value.name, `${path}.name`)\n }\n\n if (value.ignore !== undefined && typeof value.ignore !== 'boolean') {\n throw new Error(`Invalid structure: \"${path}.ignore\" must be a boolean.`)\n }\n\n if (value.files !== undefined) validateFileRules(value.files, `${path}.files`)\n if (value.additionalFiles !== undefined) {\n validateFileRules(value.additionalFiles, `${path}.additionalFiles`)\n }\n\n if (value.folders !== undefined) {\n if (!isRecord(value.folders)) {\n throw new Error(`Invalid structure: \"${path}.folders\" must be an object.`)\n }\n\n let dynamicFolders = 0\n\n for (const [folderName, child] of Object.entries(value.folders)) {\n if (folderName.trim().length === 0) {\n throw new Error(`Invalid structure: \"${path}.folders\" cannot have empty keys.`)\n }\n\n const isDynamicFolder = DYNAMIC_FOLDER_PATTERN.test(folderName)\n\n if (isDynamicFolder) {\n dynamicFolders += 1\n } else if (isRecord(child) && child.name !== undefined) {\n throw new Error(\n `Invalid structure: \"${path}.folders.${folderName}.name\" is only allowed for dynamic folders.`,\n )\n }\n\n validateNode(child, `${path}.folders.${folderName}`)\n }\n\n if (dynamicFolders > 1) {\n throw new Error(\n `Invalid structure: \"${path}.folders\" can have only one dynamic folder per level.`,\n )\n }\n }\n}\n\nexport function validateStructure(value: unknown): asserts value is IProjectStructure {\n validateNode(value, 'structure', true)\n\n if (value.ignoredPaths !== undefined) {\n if (!Array.isArray(value.ignoredPaths)) {\n throw new Error('Invalid structure: \"structure.ignoredPaths\" must be an array.')\n }\n\n value.ignoredPaths.forEach((pattern, index) => {\n assertString(pattern, `structure.ignoredPaths[${index}]`)\n })\n }\n}\n","import type { IRelationsConfig, IRelationsRule, IRelationsScope, } from '../types/structure'\n\n\nfunction cloneLayerPaths(paths: string | string[]): string | string[] {\n return Array.isArray(paths) ? [...paths] : paths\n}\n\nfunction cloneRule(rule: IRelationsRule): IRelationsRule {\n return {\n ...rule,\n ...(rule.allow ? { allow: [...rule.allow] } : {}),\n ...(rule.deny ? { deny: [...rule.deny] } : {}),\n }\n}\n\nfunction cloneScope(scope: IRelationsScope): IRelationsScope {\n return {\n ...scope,\n layers: [...scope.layers],\n }\n}\n\nexport function mergeRelations(\n base?: IRelationsConfig,\n override?: IRelationsConfig,\n): IRelationsConfig | undefined {\n if (!base && !override) return undefined\n\n const layers = {\n ...(base?.layers ?? {}),\n ...(override?.layers ?? {}),\n }\n const normalizedLayers = Object.fromEntries(\n Object.entries(layers).map(([layerName, paths]) => [\n layerName,\n cloneLayerPaths(paths),\n ]),\n )\n\n const rules = (base?.rules ?? []).map(cloneRule)\n\n for (const overrideRule of override?.rules ?? []) {\n const index = rules.findIndex((rule) => rule.from === overrideRule.from)\n\n if (index >= 0) {\n rules[index] = cloneRule(overrideRule)\n } else {\n rules.push(cloneRule(overrideRule))\n }\n }\n\n const scope = override?.scope\n ? cloneScope(override.scope)\n : base?.scope\n ? cloneScope(base.scope)\n : undefined\n\n const allowTypeImports =\n override?.allowTypeImports ?? base?.allowTypeImports\n\n return {\n layers: normalizedLayers,\n rules,\n ...(allowTypeImports !== undefined ? { allowTypeImports } : {}),\n ...(scope ? { scope } : {}),\n }\n}\n","import type { INameRule, IProjectStructure, IStructureNode, TFileRule, } from '../types/structure'\n\n\nfunction cloneFileRule(rule: TFileRule): TFileRule {\n if (typeof rule === 'string') return rule\n\n return {\n ...rule,\n extensions: [...rule.extensions],\n }\n}\n\nfunction mergeNameRule(\n base?: INameRule,\n override?: INameRule,\n): INameRule | undefined {\n if (!base && !override) return undefined\n\n return {\n ...(base ?? {}),\n ...(override ?? {}),\n }\n}\n\nfunction combineFiles(node: IStructureNode): TFileRule[] {\n return [...(node.files ?? []), ...(node.additionalFiles ?? [])]\n}\n\nfunction mergeFolders(\n base?: Record<string, IStructureNode>,\n override?: Record<string, IStructureNode>,\n): Record<string, IStructureNode> | undefined {\n if (!base && !override) return undefined\n\n const result: Record<string, IStructureNode> = {}\n const folderNames = new Set([\n ...Object.keys(base ?? {}),\n ...Object.keys(override ?? {}),\n ])\n\n for (const folderName of folderNames) {\n result[folderName] = mergeNode(\n base?.[folderName] ?? {},\n override?.[folderName] ?? {},\n )\n }\n\n return result\n}\n\nfunction mergeNode(base: IStructureNode, override: IStructureNode): IStructureNode {\n const node: IStructureNode = {}\n const baseHasFileConfig =\n base.files !== undefined || base.additionalFiles !== undefined\n const overrideHasFileConfig =\n override.files !== undefined || override.additionalFiles !== undefined\n\n if (overrideHasFileConfig) {\n const selectedFiles =\n override.files !== undefined ? override.files : combineFiles(base)\n\n node.files = [\n ...selectedFiles,\n ...(override.additionalFiles ?? []),\n ].map(cloneFileRule)\n } else if (baseHasFileConfig) {\n node.files = combineFiles(base).map(cloneFileRule)\n }\n\n const name = mergeNameRule(base.name, override.name)\n if (name) node.name = name\n\n if (override.ignore !== undefined) {\n node.ignore = override.ignore\n } else if (base.ignore !== undefined) {\n node.ignore = base.ignore\n }\n\n const folders = mergeFolders(base.folders, override.folders)\n if (folders) node.folders = folders\n\n return node\n}\n\nexport function mergeStructure(\n base?: IProjectStructure,\n override?: IProjectStructure,\n): IProjectStructure {\n const merged: IProjectStructure = mergeNode(base ?? {}, override ?? {})\n const ignoredPaths = Array.from(new Set([\n ...(base?.ignoredPaths ?? []),\n ...(override?.ignoredPaths ?? []),\n ]))\n\n if (ignoredPaths.length > 0) {\n merged.ignoredPaths = ignoredPaths\n }\n\n return merged\n}\n","import type { TFileRule } from '../../types/structure'\n\n\nexport const pascalTs: TFileRule = {\n case: 'PascalCase',\n extensions: ['.ts'],\n}\n\nexport const pascalTsx: TFileRule = {\n case: 'PascalCase',\n extensions: ['.tsx'],\n}\n\nexport const pascalTsOrTsx: TFileRule = {\n case: 'PascalCase',\n extensions: ['.ts', '.tsx'],\n}\n\nexport const commonIgnoredPaths = [\n 'node_modules/**',\n 'dist/**',\n 'build/**',\n 'coverage/**',\n]\n","import { commonIgnoredPaths, pascalTs, pascalTsOrTsx, pascalTsx } from './helpers'\nimport type { IProjectPreset, IRelationsConfig } from '../../types/structure'\n\n\nconst frontendRelations: IRelationsConfig = {\n layers: {\n pageComponent: ['src/pages/*/components', 'src/pages/*/tabs'],\n pageHook: 'src/pages/*/hooks',\n pageService: 'src/pages/*/services',\n pageContext: 'src/pages/*/contexts',\n pageHelper: 'src/pages/*/helpers',\n page: 'src/pages/*',\n components: 'src/components',\n hooks: 'src/hooks',\n contexts: 'src/contexts',\n generated: 'src/services/generated',\n services: 'src/services',\n utils: 'src/utils',\n helpers: 'src/helpers',\n constants: 'src/constants',\n env: 'src/env',\n },\n scope: {\n capture: 'page',\n layers: [\n 'pageComponent',\n 'pageHook',\n 'pageService',\n 'pageContext',\n 'pageHelper',\n 'page',\n ],\n },\n rules: [\n {\n from: 'components',\n allow: [\n 'hooks',\n 'contexts',\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n ],\n allowSameLayer: true,\n },\n {\n from: 'hooks',\n allow: [\n 'contexts',\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n ],\n allowSameLayer: true,\n },\n {\n from: 'contexts',\n allow: [\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n ],\n allowSameLayer: false,\n },\n {\n from: 'services',\n allow: ['generated', 'utils', 'helpers', 'constants', 'env'],\n allowSameLayer: false,\n },\n {\n from: 'generated',\n allow: [],\n allowSameLayer: true,\n },\n {\n from: 'utils',\n allow: ['helpers', 'constants', 'env'],\n allowSameLayer: false,\n },\n {\n from: 'helpers',\n allow: ['utils', 'constants', 'env'],\n allowSameLayer: false,\n },\n {\n from: 'constants',\n allow: [],\n allowSameLayer: false,\n },\n {\n from: 'env',\n allow: [],\n allowSameLayer: false,\n },\n {\n from: 'page',\n allow: [\n 'components',\n 'hooks',\n 'contexts',\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n 'pageComponent',\n 'pageHook',\n 'pageService',\n 'pageContext',\n 'pageHelper',\n ],\n allowSameLayer: true,\n },\n {\n from: 'pageComponent',\n allow: [\n 'components',\n 'hooks',\n 'contexts',\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n 'page',\n 'pageHook',\n 'pageService',\n 'pageContext',\n 'pageHelper',\n ],\n allowSameLayer: true,\n },\n {\n from: 'pageHook',\n allow: [\n 'hooks',\n 'contexts',\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n 'pageService',\n 'pageContext',\n 'pageHelper',\n ],\n allowSameLayer: true,\n },\n {\n from: 'pageService',\n allow: [\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n 'pageHelper',\n ],\n allowSameLayer: false,\n },\n {\n from: 'pageContext',\n allow: [\n 'contexts',\n 'services',\n 'generated',\n 'utils',\n 'helpers',\n 'constants',\n 'env',\n 'pageService',\n 'pageHelper',\n ],\n allowSameLayer: false,\n },\n {\n from: 'pageHelper',\n allow: ['helpers', 'utils', 'constants', 'env'],\n allowSameLayer: false,\n },\n ],\n}\n\n\nexport const frontendPreset: IProjectPreset = {\n structure: {\n files: [\n 'package.json',\n 'package-lock.json',\n 'yarn.lock',\n 'pnpm-lock.yaml',\n 'bun.lockb',\n '*.config.{js,mjs,cjs,ts}',\n 'tsconfig*.json',\n '*.tsbuildinfo',\n '.env',\n '.env.*',\n '.gitignore',\n '.dockerignore',\n '.editorconfig',\n 'Dockerfile',\n 'entrypoint.sh',\n 'nginx.conf',\n 'index.html',\n 'AGENTS.md',\n 'README.md',\n 'LICENSE',\n ],\n folders: {\n src: {\n files: [\n 'App.tsx',\n 'AppRoutes.tsx',\n 'main.tsx',\n 'index.css',\n 'vite-env.d.ts',\n ],\n folders: {\n components: {\n files: [pascalTsx],\n folders: {\n ui: {\n files: [pascalTsOrTsx],\n },\n },\n },\n constants: {\n files: [pascalTs],\n },\n contexts: {\n files: [\n {\n case: 'PascalCase',\n extensions: ['.tsx'],\n },\n ],\n },\n env: {\n files: ['index.ts'],\n },\n hooks: {\n files: [pascalTs],\n },\n helpers: {\n files: [pascalTs],\n },\n pages: {\n files: [pascalTsx],\n folders: {\n '[feature]': {\n name: { case: 'kebab-case' },\n files: [pascalTsx, 'helpers.ts', 'schema.ts', 'types.ts'],\n folders: {\n components: {\n files: [pascalTsx],\n },\n hooks: {\n files: [pascalTs],\n },\n services: {\n files: [pascalTs],\n },\n contexts: {\n files: [\n {\n case: 'PascalCase',\n extensions: ['.tsx'],\n },\n ],\n },\n helpers: {\n files: [pascalTs],\n },\n tabs: {\n folders: {\n '[tab]': {\n name: { case: 'kebab-case' },\n files: [pascalTsx],\n folders: {\n '[section]': {\n name: { case: 'kebab-case' },\n files: [\n pascalTs,\n pascalTsx,\n 'collisionDetection.ts',\n 'contextualFilters.ts',\n ],\n folders: {\n components: {\n files: [pascalTsx],\n },\n contents: {\n files: [pascalTsx],\n folders: {\n components: {\n files: [pascalTsx],\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n services: {\n folders: {\n generated: { ignore: true },\n utils: {\n files: [pascalTs],\n },\n },\n },\n utils: {\n files: [pascalTs],\n },\n },\n },\n e2e: {\n files: ['.env.e2e', '.env.e2e.example'],\n folders: {\n '.auth': { ignore: true },\n fixtures: {\n files: ['*.png', '*.jpg', '*.jpeg', '*.svg', '*.webp'],\n },\n pages: {\n files: [pascalTs],\n },\n specs: {\n files: ['*.spec.ts'],\n },\n support: {\n files: [pascalTs],\n folders: {\n api: {\n files: [pascalTs],\n },\n },\n },\n },\n },\n scripts: {\n files: [pascalTs],\n },\n public: { ignore: true },\n '.github': { ignore: true },\n '.vscode': { ignore: true },\n },\n ignoredPaths: [\n ...commonIgnoredPaths,\n 'playwright-report/**',\n 'test-results/**',\n 'src/services/generated/**',\n 'scripts/types/**',\n ],\n },\n relations: frontendRelations,\n}\n","import type { IProjectPreset, IRelationsConfig } from '../../types/structure'\nimport { commonIgnoredPaths, pascalTs } from './helpers'\n\n\nconst backendRelations: IRelationsConfig = {\n layers: {\n controller: 'src/http/controllers',\n http: 'src/http/hooks',\n useCase: 'src/use-case',\n repository: 'src/repositories',\n generated: 'src/services/generated',\n serviceModule: 'src/services/*',\n service: 'src/services',\n databaseSchema: 'src/database/schema',\n database: 'src/database',\n helper: 'src/helpers',\n env: 'src/env',\n types: ['src/@types', 'src/http/types'],\n },\n scope: {\n capture: 'service',\n layers: ['serviceModule'],\n },\n rules: [\n {\n from: 'controller',\n allow: ['useCase', 'http', 'generated', 'helper', 'env'],\n allowSameLayer: false,\n },\n {\n from: 'http',\n allow: ['useCase', 'helper', 'generated'],\n allowSameLayer: false,\n },\n {\n from: 'useCase',\n allow: ['repository', 'service', 'serviceModule', 'generated'],\n allowSameLayer: true,\n },\n {\n from: 'repository',\n allow: ['database', 'databaseSchema'],\n allowSameLayer: false,\n },\n {\n from: 'service',\n allow: ['generated', 'env'],\n allowSameLayer: false,\n },\n {\n from: 'generated',\n allow: [],\n allowSameLayer: true,\n },\n {\n from: 'serviceModule',\n allow: ['generated', 'env'],\n allowSameLayer: true,\n },\n {\n from: 'database',\n allow: ['databaseSchema', 'env'],\n allowSameLayer: false,\n },\n {\n from: 'databaseSchema',\n allow: [],\n allowSameLayer: true,\n },\n {\n from: 'helper',\n allow: [],\n allowSameLayer: false,\n },\n {\n from: 'env',\n allow: [],\n allowSameLayer: false,\n },\n {\n from: 'types',\n allow: [],\n allowSameLayer: false,\n },\n ],\n}\n\n\nexport const backendPreset: IProjectPreset = {\n structure: {\n files: [\n 'package.json',\n 'package-lock.json',\n 'yarn.lock',\n 'pnpm-lock.yaml',\n 'bun.lockb',\n '*.config.{js,mjs,cjs,ts}',\n 'tsconfig*.json',\n '*.tsbuildinfo',\n '.env',\n '.env.*',\n '.gitignore',\n '.dockerignore',\n '.editorconfig',\n 'Dockerfile',\n 'AGENTS.md',\n 'README.md',\n 'LICENSE',\n ],\n folders: {\n src: {\n files: ['index.ts', 'Server.ts', 'Schemas.ts'],\n folders: {\n database: {\n files: ['Connection.ts'],\n folders: {\n schema: {\n files: ['index.ts', pascalTs],\n },\n seeds: {\n files: ['index.ts'],\n },\n migrations: { ignore: true },\n },\n },\n repositories: {\n files: ['Setup.ts', pascalTs],\n },\n env: {\n files: ['index.ts'],\n },\n helpers: {\n files: [pascalTs],\n },\n '@types': {\n files: ['*.d.ts'],\n },\n http: {\n files: ['Routes.ts'],\n folders: {\n controllers: {\n files: ['Health.ts'],\n folders: {\n '[feature]': {\n name: { case: 'kebab-case' },\n files: [pascalTs],\n folders: {\n '[resource]': {\n name: { case: 'kebab-case' },\n files: [pascalTs],\n },\n },\n },\n },\n },\n hooks: {\n files: [pascalTs],\n },\n types: {\n files: ['*.d.ts'],\n },\n },\n },\n services: {\n files: [pascalTs],\n folders: {\n generated: { ignore: true },\n '[service]': {\n name: { case: 'kebab-case' },\n files: ['index.ts', pascalTs],\n },\n },\n },\n 'use-case': {\n files: ['Errors.ts'],\n folders: {\n '[feature]': {\n name: { case: 'kebab-case' },\n files: [pascalTs],\n folders: {\n '[resource]': {\n name: { case: 'kebab-case' },\n files: [pascalTs],\n },\n },\n },\n },\n },\n },\n },\n docs: { ignore: true },\n scripts: {\n files: [pascalTs],\n },\n test: {\n files: [\n { case: 'PascalCase', extensions: ['.test.ts'] },\n 'GlobalSetup.ts',\n 'Setup.ts',\n '*.d.ts',\n ],\n folders: {\n Helpers: {\n files: [pascalTs],\n },\n },\n },\n '.github': { ignore: true },\n '.vscode': { ignore: true },\n },\n ignoredPaths: [\n ...commonIgnoredPaths,\n 'uploads/**',\n 'src/services/generated/**',\n ],\n },\n relations: backendRelations,\n}\n","import type { IProjectPreset } from '../../types/structure'\n\n\nexport const otherPreset: IProjectPreset = {\n structure: {},\n}\n","import type { IProjectPreset, TProjectPreset } from '../../types/structure'\nimport { frontendPreset } from './frontend'\nimport { backendPreset } from './backend'\nimport { otherPreset } from './other'\n\n\nexport const presets: Record<TProjectPreset, IProjectPreset> = {\n frontend: frontendPreset,\n backend: backendPreset,\n other: otherPreset,\n}\n\nexport function getPreset(preset: TProjectPreset): IProjectPreset {\n const value = presets[preset]\n\n if (!value) {\n throw new Error(\n `Unknown preset \"${preset}\". Expected one of: ${Object.keys(presets).join(', ')}.`,\n )\n }\n\n return value\n}\n","import type { ESLint, Linter } from 'eslint'\n\nimport type { IProjectDefinition } from './types/structure'\nimport { recommended } from './configs/recommended'\nimport { projects } from './configs/projects'\nimport { plugin } from './plugin'\n\nexport type { IAiRulesSettings, INameRule, IProjectDefinition, IProjectPreset, IProjectStructure, IRelationsConfig, IRelationsRule, IRelationsScope, IResolvedProject, IStructureNode, TFileRule, TNameCase, TProjectPreset, } from './types/structure'\nexport { presets } from './structures/presets'\nexport * from './rules/index'\n\n\ninterface IAiRulesPlugin extends Omit<ESLint.Plugin, 'configs'> {\n configs: {\n recommended: Linter.Config[]\n projects: (definitions: IProjectDefinition[]) => Linter.Config[]\n }\n}\n\nconst aiGuardPlugin: IAiRulesPlugin = {\n ...plugin,\n configs: {\n recommended,\n projects,\n },\n}\n\nexport default aiGuardPlugin\nexport { plugin }\nexport { recommended }\nexport { projects }\n"],"mappings":"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","names":["path","projects","path","projects","path","path","path","DYNAMIC_FOLDER_PATTERN","isRecord","assertString","path","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-ai-rules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "ESLint plugin com regras úteis para projetos com ESLint - AI Rules",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -8,14 +8,20 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
20
|
},
|
|
16
21
|
"files": [
|
|
17
22
|
"dist"
|
|
18
23
|
],
|
|
24
|
+
"sideEffects": false,
|
|
19
25
|
"scripts": {
|
|
20
26
|
"clean": "rm -rf dist",
|
|
21
27
|
"prebuild": "yarn clean",
|
|
@@ -25,9 +31,13 @@
|
|
|
25
31
|
"lint": "eslint .",
|
|
26
32
|
"typecheck": "tsc --noEmit",
|
|
27
33
|
"test": "yarn build && node --test test/*.test.mjs",
|
|
34
|
+
"test:coverage": "yarn build && c8 --include dist/index.js --check-coverage --lines 95 --branches 90 --functions 95 --reporter=text node --test test/*.test.mjs",
|
|
35
|
+
"test:consumer": "node scripts/TestConsumer.mjs",
|
|
36
|
+
"test:package": "npx --yes publint --pack npm && npx --yes @arethetypeswrong/cli --pack .",
|
|
37
|
+
"test:release": "yarn test:consumer && yarn test:package",
|
|
28
38
|
"verify": "yarn typecheck && yarn test && yarn lint && npm pack --dry-run",
|
|
29
39
|
"prepack": "yarn build",
|
|
30
|
-
"prepublishOnly": "git
|
|
40
|
+
"prepublishOnly": "test -z \"$(git status --porcelain)\" || (echo '✖ working tree not clean — commit before publishing' && exit 1) && yarn verify",
|
|
31
41
|
"postpublish": "echo '✔ published. Run: git push --follow-tags'"
|
|
32
42
|
},
|
|
33
43
|
"publishConfig": {
|
|
@@ -50,24 +60,28 @@
|
|
|
50
60
|
"url": "https://github.com/lvsouza/eslint-ai-guard/issues"
|
|
51
61
|
},
|
|
52
62
|
"peerDependencies": {
|
|
53
|
-
"eslint": "^9.0.0",
|
|
54
|
-
"typescript": "
|
|
63
|
+
"eslint": "^9.22.0 || ^10.0.0",
|
|
64
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
65
|
+
"typescript": ">=5.0.0 <6.1.0"
|
|
55
66
|
},
|
|
56
67
|
"dependencies": {
|
|
57
|
-
"@eslint/js": "^9.0.0",
|
|
58
68
|
"@stylistic/eslint-plugin": "^5.0.0",
|
|
69
|
+
"eslint-plugin-boundaries": "^7.4.1",
|
|
59
70
|
"eslint-plugin-import-x": "^4.0.0",
|
|
60
|
-
"globals": "^16.0.0",
|
|
61
71
|
"typescript-eslint": "^8.0.0"
|
|
62
72
|
},
|
|
63
73
|
"devDependencies": {
|
|
74
|
+
"@eslint/js": "^10.0.0",
|
|
64
75
|
"@types/node": "^22.0.0",
|
|
65
|
-
"
|
|
76
|
+
"c8": "^12.0.0",
|
|
77
|
+
"eslint": "^10.0.0",
|
|
78
|
+
"eslint-import-resolver-typescript": "^4.4.5",
|
|
79
|
+
"globals": "^17.0.0",
|
|
66
80
|
"tsup": "^8.0.0",
|
|
67
81
|
"tsx": "^4.0.0",
|
|
68
82
|
"typescript": "^5.6.0"
|
|
69
83
|
},
|
|
70
84
|
"engines": {
|
|
71
|
-
"node": ">=
|
|
85
|
+
"node": ">=20.0.0"
|
|
72
86
|
}
|
|
73
87
|
}
|