eslint-plugin-unslop 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -5
package/dist/index.cjs
CHANGED
|
@@ -37,7 +37,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
37
37
|
// package.json
|
|
38
38
|
var package_default = {
|
|
39
39
|
name: "eslint-plugin-unslop",
|
|
40
|
-
version: "0.1.
|
|
40
|
+
version: "0.1.3",
|
|
41
41
|
description: "ESLint plugin with rules for reducing AI-generated code smells",
|
|
42
42
|
repository: {
|
|
43
43
|
type: "git",
|
|
@@ -64,12 +64,9 @@ var package_default = {
|
|
|
64
64
|
scripts: {
|
|
65
65
|
build: "tsup",
|
|
66
66
|
format: "prettier . --write",
|
|
67
|
-
|
|
68
|
-
knip: "knip",
|
|
69
|
-
lint: "npm run build && eslint .",
|
|
67
|
+
verify: "prettier . --check && tsc --noEmit && tsup && eslint . && knip",
|
|
70
68
|
test: "vitest run",
|
|
71
69
|
"test:watch": "vitest",
|
|
72
|
-
typecheck: "tsc --noEmit",
|
|
73
70
|
prepublishOnly: "npm run build"
|
|
74
71
|
},
|
|
75
72
|
keywords: [
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../package.json","../src/utils/string-literal-listener.ts","../src/rules/no-special-unicode.ts","../src/rules/no-unicode-escape.ts","../src/rules/no-deep-imports.ts","../src/utils/path-helpers.ts","../src/utils/rule-options.ts","../src/utils/source-root.ts","../src/rules/no-false-sharing/analysis.ts","../src/rules/no-false-sharing.ts","../src/rules/read-friendly-order/class-order.ts","../src/rules/read-friendly-order/test-order.ts","../src/rules/read-friendly-order.ts","../src/rules/index.ts"],"sourcesContent":["import type { ESLint, Linter } from 'eslint'\nimport packageJson from '../package.json'\nimport rules from './rules/index.js'\n\n// configs.recommended.plugins.unslop must reference the plugin itself.\n// Build plugin first with an empty configs object, then assign below.\nconst plugin: ESLint.Plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n rules,\n configs: {},\n}\n\nconst recommended: Linter.Config = {\n name: 'unslop/recommended',\n plugins: { unslop: plugin },\n rules: {\n 'unslop/no-special-unicode': 'error',\n 'unslop/no-unicode-escape': 'error',\n 'unslop/no-deep-imports': 'error',\n },\n}\n\nplugin.configs!['recommended'] = recommended\n\nexport default plugin\n","{\n \"name\": \"eslint-plugin-unslop\",\n \"version\": \"0.1.2\",\n \"description\": \"ESLint plugin with rules for reducing AI-generated code smells\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/skhoroshavin/eslint-plugin-unslop\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"format\": \"prettier . --write\",\n \"format:check\": \"prettier . --check\",\n \"knip\": \"knip\",\n \"lint\": \"npm run build && eslint .\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"eslint\",\n \"eslintplugin\",\n \"eslint-plugin\",\n \"ai\",\n \"code-quality\",\n \"unslop\"\n ],\n \"license\": \"MIT\",\n \"peerDependencies\": {\n \"eslint\": \">=9.0.0\",\n \"typescript\": \">=5.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"typescript\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.4\",\n \"@types/estree\": \"^1.0.8\",\n \"@types/node\": \"^22.18.0\",\n \"@typescript-eslint/parser\": \"^8.57.2\",\n \"eslint\": \"^9.39.1\",\n \"globals\": \"^17.4.0\",\n \"knip\": \"^6.1.0\",\n \"prettier\": \"^3.8.1\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.57.2\",\n \"vitest\": \"^3.2.4\"\n }\n}\n","import type { Rule } from 'eslint'\nimport type { Literal, TemplateLiteral } from 'estree'\n\nexport function createStringLiteralListener(\n includeEscapedUnicode: boolean,\n visitLiteral: StringLiteralVisitor,\n): Rule.RuleListener {\n function inspect(node: Literal | TemplateLiteral): void {\n const text = getStringValue(node, includeEscapedUnicode)\n if (text == undefined) {\n return\n }\n\n visitLiteral(node, text)\n }\n\n return {\n Literal: inspect,\n TemplateLiteral: inspect,\n }\n}\n\ntype StringLiteralVisitor = (node: Literal | TemplateLiteral, text: string) => void\n\nfunction getStringValue(\n node: Literal | TemplateLiteral,\n includeEscapedUnicode: boolean,\n): string | undefined {\n if (node.type === 'TemplateLiteral') {\n return node.quasis\n .map((q) =>\n includeEscapedUnicode ? (q.value.raw ?? q.value.cooked ?? '') : (q.value.cooked ?? ''),\n )\n .join('')\n }\n\n if (typeof node.value !== 'string') {\n return undefined\n }\n\n return includeEscapedUnicode ? (node.raw ?? node.value) : node.value\n}\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow special unicode punctuation and whitespace in strings',\n recommended: true,\n },\n schema: [],\n messages: {\n bannedCharacter: 'String contains {{name}} (U+{{code}}). Use the ASCII equivalent.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(false, (node, text) => {\n if (!BANNED_CHARS_RE.test(text)) {\n return\n }\n\n for (const [char, name] of BANNED_CHARS) {\n if (!text.includes(char)) {\n continue\n }\n\n const code = char.codePointAt(0) ?? 0\n\n context.report({\n node,\n messageId: 'bannedCharacter',\n data: {\n name,\n code: code.toString(16).toUpperCase().padStart(4, '0'),\n },\n })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst BANNED_CHARS = new Map([\n ['\\u201C', 'left double quotation mark'],\n ['\\u201D', 'right double quotation mark'],\n ['\\u2018', 'left single quotation mark'],\n ['\\u2019', 'right single quotation mark'],\n ['\\u00A0', 'non-breaking space'],\n ['\\u202F', 'narrow no-break space'],\n ['\\u2007', 'figure space'],\n ['\\u2008', 'punctuation space'],\n ['\\u2009', 'thin space'],\n ['\\u200A', 'hair space'],\n ['\\u200B', 'zero-width space'],\n ['\\u2002', 'en space'],\n ['\\u2003', 'em space'],\n ['\\u205F', 'medium mathematical space'],\n ['\\u3000', 'ideographic space'],\n ['\\uFEFF', 'zero-width no-break space'],\n ['\\u2013', 'en dash'],\n ['\\u2014', 'em dash'],\n ['\\u2026', 'horizontal ellipsis'],\n])\n\nconst BANNED_CHARS_RE = new RegExp([...BANNED_CHARS.keys()].join('|'))\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Prefer literal unicode characters over \\\\uXXXX escape sequences',\n recommended: true,\n },\n schema: [],\n messages: {\n preferLiteral: 'Use the actual character instead of a \\\\uXXXX escape sequence.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(true, (node, text) => {\n if (UNICODE_ESCAPE_RE.test(text)) {\n context.report({ node, messageId: 'preferLiteral' })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst UNICODE_ESCAPE_RE = /\\\\u[0-9a-fA-F]{4}/\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport type { Rule } from 'eslint'\nimport { toPosix } from '../utils/path-helpers.js'\nimport { readSourceRootOption } from '../utils/rule-options.js'\nimport { resolveSourceContext } from '../utils/source-root.js'\n\nconst NO_DEEP_IMPORTS_SCHEMA = [\n {\n type: 'object',\n properties: {\n sourceRoot: { type: 'string' },\n },\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Forbid deep imports inside the same top-level folder',\n recommended: true,\n },\n messages: {\n tooDeep:\n '{{sourceRelativePath}}: {{targetRelativePath}} is too deep (max 1 level below importer).',\n },\n schema: NO_DEEP_IMPORTS_SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot } = sourceContext\n\n return {\n ImportDeclaration(node) {\n const specifier = typeof node.source.value === 'string' ? node.source.value : ''\n\n const violation = findViolation(specifier, filename, sourceRoot, sourceRelativePath)\n\n if (violation) {\n context.report({\n node,\n messageId: 'tooDeep',\n data: violation,\n })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction findViolation(\n specifier: string,\n filename: string,\n sourceRoot: string,\n sourceRelativePath: string,\n): { sourceRelativePath: string; targetRelativePath: string } | undefined {\n const targetSourceRelative = resolveImportSourceRelative(specifier, filename, sourceRoot)\n if (!targetSourceRelative) {\n return undefined\n }\n\n const targetRelativePath = resolveTarget(targetSourceRelative, sourceRoot)\n if (!targetRelativePath) {\n return undefined\n }\n\n const folderScope = folderScopeFromPath(sourceRelativePath)\n if (!isInScope(targetRelativePath, folderScope)) {\n return undefined\n }\n\n const importerDepth = depthWithinScope(sourceRelativePath, folderScope)\n const targetDepth = depthWithinScope(targetRelativePath, folderScope)\n if (targetDepth <= importerDepth + 1) {\n return undefined\n }\n\n return {\n sourceRelativePath,\n targetRelativePath: stripTsExtension(targetRelativePath),\n }\n}\n\nfunction resolveImportSourceRelative(\n specifier: string,\n filename: string,\n sourceRoot: string,\n): string | undefined {\n const normalizedSpecifier = specifier.replace(/\\.js$/, '')\n\n if (normalizedSpecifier.startsWith('@/')) {\n return normalizedSpecifier.slice(2)\n }\n\n if (!normalizedSpecifier.startsWith('.')) {\n return undefined\n }\n\n const absoluteTarget = path.resolve(path.dirname(filename), normalizedSpecifier)\n const targetSourceRelative = path.relative(sourceRoot, absoluteTarget)\n if (targetSourceRelative.startsWith('..')) {\n return undefined\n }\n\n return toPosix(targetSourceRelative)\n}\n\nfunction resolveTarget(targetSourceRelative: string, sourceRoot: string): string | undefined {\n const cacheKey = `${sourceRoot}\\0${targetSourceRelative}`\n if (resolveCache.has(cacheKey)) {\n return resolveCache.get(cacheKey)\n }\n\n const candidates = [\n targetSourceRelative + '.ts',\n targetSourceRelative + '.tsx',\n targetSourceRelative + '/index.ts',\n targetSourceRelative + '/index.tsx',\n ]\n const candidate = candidates.find((entry) => existsSync(path.join(sourceRoot, entry)))\n const targetRelativePath = candidate ? toPosix(candidate) : undefined\n\n resolveCache.set(cacheKey, targetRelativePath)\n return targetRelativePath\n}\n\nfunction folderScopeFromPath(sourceRelativePath: string): string {\n const [firstPart = ''] = sourceRelativePath.split('/')\n return stripTsExtension(firstPart)\n}\n\nfunction isInScope(targetRelativePath: string, scope: string): boolean {\n const targetNoExtension = stripTsExtension(targetRelativePath)\n return targetNoExtension === scope || targetNoExtension.startsWith(`${scope}/`)\n}\n\nfunction depthWithinScope(relativePath: string, scope: string): number {\n const withoutExtension = stripTsExtension(relativePath)\n if (withoutExtension === scope) {\n return 0\n }\n\n // Precondition: isInScope() already confirmed target is within scope,\n // so withoutExtension always starts with scope + '/'\n const suffix = withoutExtension.slice(scope.length + 1)\n return suffix.split('/').length - 1\n}\n\nconst resolveCache = new Map<string, string | undefined>()\n\nfunction stripTsExtension(filePath: string): string {\n return filePath.replace(/\\.tsx?$/, '')\n}\n","import path from 'node:path'\n\nexport function toPosix(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nexport function isInsidePath(filePath: string, parentPath: string): boolean {\n const relativePath = path.relative(parentPath, filePath)\n return relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath))\n}\n","export function readSourceRootOption(options: unknown[]): string | undefined {\n const option = options[0]\n if (!isRecord(option) || !('sourceRoot' in option)) {\n return undefined\n }\n\n return typeof option.sourceRoot === 'string' ? option.sourceRoot : undefined\n}\n\nexport type SharingMode = 'file' | 'dir'\n\nexport interface DirEntry {\n path: string\n mode: SharingMode\n}\n\nexport function readDirsOption(options: unknown[], rootMode: SharingMode = 'file'): DirEntry[] {\n const option = options[0]\n if (!isRecord(option) || !('dirs' in option)) {\n return []\n }\n\n const rootModeResolved = readRootMode(option, rootMode)\n\n const { dirs } = option\n if (!Array.isArray(dirs)) {\n return []\n }\n\n return dirs.flatMap((entry) => {\n const parsed = parseDirEntry(entry, rootModeResolved)\n return parsed ? [parsed] : []\n })\n}\n\nfunction readRootMode(option: object, fallback: SharingMode): SharingMode {\n if (!('mode' in option)) {\n return fallback\n }\n\n return option.mode === 'dir' ? 'dir' : 'file'\n}\n\nfunction parseDirEntry(entry: unknown, defaultMode: SharingMode): DirEntry | undefined {\n if (!isRecord(entry) || !('path' in entry)) {\n return undefined\n }\n\n if (typeof entry.path !== 'string') {\n return undefined\n }\n\n const modeValue = 'mode' in entry ? entry.mode : undefined\n const mode: SharingMode = modeValue === 'dir' ? 'dir' : defaultMode\n\n return { path: entry.path, mode }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { isInsidePath, toPosix } from './path-helpers.js'\n\nexport function resolveSourceContext(\n filename: string,\n sourceRootOverride?: string,\n): SourceContext | undefined {\n if (filename === '<input>') {\n return undefined\n }\n\n const absoluteFilename = path.isAbsolute(filename) ? filename : path.resolve(filename)\n\n if (sourceRootOverride) {\n const projectRoot = findNearestPackageRoot(path.dirname(absoluteFilename)) ?? process.cwd()\n return buildContext(\n absoluteFilename,\n projectRoot,\n path.isAbsolute(sourceRootOverride)\n ? sourceRootOverride\n : path.join(projectRoot, sourceRootOverride),\n )\n }\n\n const packageRoot = findNearestPackageRoot(path.dirname(absoluteFilename))\n if (packageRoot) {\n return buildContext(\n absoluteFilename,\n packageRoot,\n existsSync(path.join(packageRoot, 'src')) ? path.join(packageRoot, 'src') : packageRoot,\n )\n }\n\n return resolveLegacySourceRoot(absoluteFilename)\n}\n\nfunction findNearestPackageRoot(startDirectory: string): string | undefined {\n let directory = startDirectory\n\n while (true) {\n if (existsSync(path.join(directory, 'package.json'))) {\n return directory\n }\n\n const parent = path.dirname(directory)\n if (parent === directory) {\n return undefined\n }\n\n directory = parent\n }\n}\n\nfunction resolveLegacySourceRoot(filename: string): SourceContext | undefined {\n const normalized = toPosix(filename)\n const sourceIndex = normalized.lastIndexOf('/src/')\n if (sourceIndex === -1) {\n return undefined\n }\n\n const projectRoot = normalized.slice(0, sourceIndex)\n const sourceRoot = path.join(projectRoot, 'src')\n return buildContext(filename, projectRoot, sourceRoot)\n}\n\nfunction buildContext(\n filename: string,\n projectRoot: string,\n sourceRoot: string,\n): SourceContext | undefined {\n if (!isInsidePath(filename, sourceRoot)) {\n return undefined\n }\n\n return {\n projectRoot,\n sourceRoot,\n sourceRelativePath: toPosix(path.relative(sourceRoot, filename)),\n }\n}\n\ninterface SourceContext {\n projectRoot: string\n sourceRoot: string\n sourceRelativePath: string\n}\n","import { existsSync, readdirSync } from 'node:fs'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport { isInsidePath, toPosix } from '../../utils/path-helpers.js'\nimport type { DirEntry, SharingMode } from '../../utils/rule-options.js'\n\nexport function runConsumerCheck(\n program: ts.Program,\n projectRoot: string,\n sourceRoot: string,\n directories: DirEntry[],\n): Map<string, string[]> {\n const checker = program.getTypeChecker()\n const sourceFiles = program.getSourceFiles().filter((sf) => isInsidePath(sf.fileName, sourceRoot))\n\n const modules = indexModules(directories, projectRoot, sourceRoot)\n const barrels = indexBarrels(directories, projectRoot, sourceFiles, checker)\n const ctx: AnalysisContext = { modules, barrels, checker }\n countConsumers(sourceFiles, sourceRoot, ctx)\n return collectErrors(modules)\n}\n\nfunction indexModules(\n directories: DirEntry[],\n projectRoot: string,\n sourceRoot: string,\n): Map<string, ModuleEntry> {\n const modules = new Map<string, ModuleEntry>()\n\n for (const dir of directories) {\n const absDir = path.join(projectRoot, dir.path)\n for (const file of listModuleFiles(absDir)) {\n modules.set(file, {\n relativePath: toPosix(path.relative(sourceRoot, file)),\n mode: dir.mode,\n consumers: new Set(),\n })\n }\n }\n\n return modules\n}\n\nfunction listModuleFiles(directory: string): string[] {\n if (!existsSync(directory)) {\n return []\n }\n\n return readdirSync(directory, { withFileTypes: true })\n .filter(\n (e) =>\n e.isFile() &&\n (e.name.endsWith('.ts') || e.name.endsWith('.tsx')) &&\n e.name !== 'index.ts' &&\n !isTestFile(e.name),\n )\n .map((e) => path.join(directory, e.name))\n}\n\nfunction indexBarrels(\n directories: DirEntry[],\n projectRoot: string,\n sourceFiles: ts.SourceFile[],\n checker: ts.TypeChecker,\n): Map<string, Map<string, string>> {\n const barrels = new Map<string, Map<string, string>>()\n const sfByPath = new Map(sourceFiles.map((sf) => [sf.fileName, sf]))\n\n for (const dir of directories) {\n const barrelPath = path.join(projectRoot, dir.path, 'index.ts')\n const barrelSf = sfByPath.get(barrelPath)\n if (barrelSf) {\n barrels.set(barrelPath, buildBarrelMap(barrelSf, checker))\n }\n }\n\n return barrels\n}\n\nfunction buildBarrelMap(barrelFile: ts.SourceFile, checker: ts.TypeChecker): Map<string, string> {\n const map = new Map<string, string>()\n\n for (const stmt of barrelFile.statements) {\n if (!isNamedReExport(stmt)) continue\n\n const targetPath = resolveModulePath(stmt.moduleSpecifier, checker)\n if (!targetPath) continue\n\n for (const el of stmt.exportClause.elements) {\n if (!el.isTypeOnly) {\n map.set(el.name.text, targetPath)\n }\n }\n }\n\n return map\n}\n\nfunction isNamedReExport(stmt: ts.Statement): stmt is ts.ExportDeclaration & {\n exportClause: ts.NamedExports\n moduleSpecifier: ts.Expression\n} {\n return (\n ts.isExportDeclaration(stmt) &&\n !stmt.isTypeOnly &&\n !!stmt.moduleSpecifier &&\n !!stmt.exportClause &&\n ts.isNamedExports(stmt.exportClause)\n )\n}\n\nfunction countConsumers(\n sourceFiles: ts.SourceFile[],\n sourceRoot: string,\n ctx: AnalysisContext,\n): void {\n for (const sf of sourceFiles) {\n if (ctx.modules.has(sf.fileName) || isTestFile(sf.fileName)) continue\n\n const consumerPath = toPosix(path.relative(sourceRoot, sf.fileName))\n\n for (const stmt of sf.statements) {\n if (ts.isImportDeclaration(stmt)) {\n recordImport(stmt, consumerPath, ctx)\n }\n }\n }\n}\n\nfunction isTestFile(filePath: string): boolean {\n return TEST_FILE_RE.test(filePath)\n}\n\nconst TEST_FILE_RE = /\\.(test|integration-test|test-suite)\\.ts$/\n\nfunction recordImport(\n stmt: ts.ImportDeclaration,\n consumerPath: string,\n ctx: AnalysisContext,\n): void {\n const targetPath = resolveModulePath(stmt.moduleSpecifier, ctx.checker)\n if (!targetPath) return\n\n const direct = ctx.modules.get(targetPath)\n if (direct) {\n direct.consumers.add(deriveEntity(consumerPath, direct.mode))\n return\n }\n\n const barrelMap = ctx.barrels.get(targetPath)\n if (barrelMap) {\n resolveBarrelImports(stmt, barrelMap, consumerPath, ctx.modules)\n }\n}\n\nfunction resolveBarrelImports(\n stmt: ts.ImportDeclaration,\n barrelMap: Map<string, string>,\n consumerPath: string,\n modules: Map<string, ModuleEntry>,\n): void {\n const bindings = stmt.importClause?.namedBindings\n if (!bindings) return\n\n const paths = ts.isNamespaceImport(bindings)\n ? [...barrelMap.values()]\n : resolveNamedImports(bindings, barrelMap)\n\n for (const resolved of paths) {\n const entry = modules.get(resolved)\n entry?.consumers.add(deriveEntity(consumerPath, entry.mode))\n }\n}\n\nfunction resolveNamedImports(bindings: ts.NamedImports, barrelMap: Map<string, string>): string[] {\n const result: string[] = []\n for (const el of bindings.elements) {\n const name = el.propertyName?.text ?? el.name.text\n const resolved = barrelMap.get(name)\n if (resolved) {\n result.push(resolved)\n }\n }\n return result\n}\n\nfunction resolveModulePath(specifier: ts.Expression, checker: ts.TypeChecker): string | undefined {\n const symbol = checker.getSymbolAtLocation(specifier)\n return symbol?.declarations?.[0]?.getSourceFile().fileName\n}\n\nfunction collectErrors(modules: Map<string, ModuleEntry>): Map<string, string[]> {\n const errors = new Map<string, string[]>()\n\n for (const [, entry] of modules) {\n if (entry.consumers.size >= 2) continue\n\n const consumers = [...entry.consumers]\n const description =\n consumers.length === 0\n ? 'not imported by any entity'\n : `only used by: ${consumers.join(', ')}`\n\n errors.set(entry.relativePath, [`${description} -> Must be used by 2+ entities`])\n }\n\n return errors\n}\n\nfunction deriveEntity(consumerPath: string, mode: SharingMode): string {\n if (mode === 'file') {\n return consumerPath\n }\n return consumerPath.split('/').slice(0, -1).slice(0, MAX_DIR_DEPTH).join('/')\n}\n\nconst MAX_DIR_DEPTH = 3\n\ninterface AnalysisContext {\n modules: Map<string, ModuleEntry>\n barrels: Map<string, Map<string, string>>\n checker: ts.TypeChecker\n}\n\ninterface ModuleEntry {\n relativePath: string\n mode: SharingMode\n consumers: Set<string>\n}\n","import type { Rule } from 'eslint'\nimport type ts from 'typescript'\nimport { resolveSourceContext } from '../utils/source-root.js'\nimport { readDirsOption, readSourceRootOption } from '../utils/rule-options.js'\nimport { runConsumerCheck } from './no-false-sharing/analysis.js'\n\nconst SCHEMA = [\n {\n type: 'object',\n properties: {\n dirs: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n mode: { type: 'string', enum: ['file', 'dir'] },\n },\n required: ['path'],\n additionalProperties: false,\n },\n },\n mode: { type: 'string', enum: ['file', 'dir'] },\n sourceRoot: { type: 'string' },\n },\n required: ['dirs'],\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Require selected modules to be shared across at least two consumer entities',\n recommended: false,\n },\n schema: SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const dirs = readDirsOption(context.options)\n if (dirs.length === 0) {\n return {}\n }\n\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot, projectRoot } = sourceContext\n\n return {\n Program(node) {\n const program = extractTsProgram(context)\n if (!program) {\n return\n }\n\n const errors = runConsumerCheck(program, projectRoot, sourceRoot, dirs)\n const fileErrors = errors.get(sourceRelativePath)\n if (!fileErrors) {\n return\n }\n\n for (const message of fileErrors) {\n context.report({ node, message })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction extractTsProgram(context: Rule.RuleContext): ts.Program | undefined {\n const services = context.sourceCode.parserServices\n if (!isRecord(services) || !('program' in services)) {\n return undefined\n }\n const program = services.program\n if (!isTsProgram(program)) {\n return undefined\n }\n return program\n}\n\nfunction isTsProgram(value: unknown): value is ts.Program {\n return isRecord(value) && 'getTypeChecker' in value\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import type { ClassBody, Identifier, Node, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportClassOrdering(program: Program, context: Rule.RuleContext): void {\n for (const classNode of collectClassDeclarations(program)) {\n const members = collectClassMembers(classNode)\n reportConstructorOrder(members, classNode, context)\n reportPublicFieldOrder(members, context)\n reportClassDependencyOrder(members, context)\n }\n}\n\nfunction collectClassDeclarations(program: Program): ClassNode[] {\n const classes: ClassNode[] = []\n\n for (const statement of getTopLevelStatements(program)) {\n const classNode = extractClassNode(statement)\n if (classNode) classes.push(classNode)\n }\n\n return classes\n}\n\nfunction extractClassNode(statement: TopLevelNode): ClassNode | undefined {\n if (statement.type === 'ClassDeclaration') return statement\n\n if (\n statement.type === 'ExportNamedDeclaration' &&\n statement.declaration?.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n if (\n statement.type === 'ExportDefaultDeclaration' &&\n statement.declaration.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n return undefined\n}\n\nfunction reportConstructorOrder(\n members: ClassMemberEntry[],\n classNode: ClassNode,\n context: Rule.RuleContext,\n): void {\n const ctor = members.find((m) => m.kind === 'constructor')\n if (!ctor || ctor.index === 0) return\n\n context.report({\n node: ctor.node,\n messageId: 'constructorFirst',\n data: { className: classNode.id?.name ?? 'anonymous class' },\n })\n}\n\nfunction reportPublicFieldOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const ctorIndex = members.find((m) => m.kind === 'constructor')?.index ?? -1\n const startIndex = ctorIndex >= 0 ? ctorIndex + 1 : 0\n let seenOther = false\n\n for (const member of members) {\n if (member.index < startIndex) continue\n\n if (member.kind === 'public-field') {\n if (seenOther) {\n context.report({\n node: member.node,\n messageId: 'publicFieldOrder',\n data: { memberName: member.name },\n })\n }\n continue\n }\n\n seenOther = true\n }\n}\n\nfunction reportClassDependencyOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const others = members.filter((m) => m.kind === 'other')\n\n for (const member of others) {\n const consumer = findFirstClassConsumer(others, member, context)\n if (!consumer) continue\n\n context.report({\n node: member.node,\n messageId: 'moveMemberBelow',\n data: { memberName: member.name, consumerName: consumer.name },\n })\n }\n}\n\nfunction collectClassMembers(classNode: ClassNode): ClassMemberEntry[] {\n const members: ClassMemberEntry[] = []\n\n for (const [index, raw] of classNode.body.body.entries()) {\n const named = toNamedMember(raw)\n if (!named) continue\n members.push({ name: named.name, node: named.node, index, kind: classifyMember(named.node) })\n }\n\n return members\n}\n\nfunction toNamedMember(raw: Node): { name: string; node: Node } | undefined {\n if (!hasMemberKey(raw)) return undefined\n const name = readMemberName(raw.key)\n return name ? { name, node: raw } : undefined\n}\n\nfunction hasMemberKey(value: object): value is { key: Node } {\n return 'key' in value && isNode(value.key)\n}\n\nfunction readMemberName(key: Node): string | undefined {\n if (key.type === 'Identifier') return key.name\n if (key.type === 'Literal' && typeof key.value === 'string') return key.value\n if (key.type === 'PrivateIdentifier') return `#${key.name}`\n return undefined\n}\n\nfunction classifyMember(member: Node): ClassMemberEntry['kind'] {\n if (member.type === 'MethodDefinition' && member.kind === 'constructor') return 'constructor'\n if (isPublicField(member)) return 'public-field'\n return 'other'\n}\n\nfunction isPublicField(member: Node): boolean {\n if (member.type !== 'PropertyDefinition' || member.static) return false\n if (member.key.type === 'PrivateIdentifier') return false\n if (!('accessibility' in member)) return true\n return member.accessibility === undefined || member.accessibility === 'public'\n}\n\nfunction findFirstClassConsumer(\n members: ClassMemberEntry[],\n member: ClassMemberEntry,\n context: Rule.RuleContext,\n): ClassMemberEntry | undefined {\n const pattern = new RegExp(`\\\\bthis(?:\\\\?\\\\.|\\\\.)${escapeRegex(member.name)}\\\\b`)\n\n for (const candidate of members) {\n if (candidate.index <= member.index) continue\n if (pattern.test(context.sourceCode.getText(candidate.node))) return candidate\n }\n\n return undefined\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction isNode(value: unknown): value is Node {\n return !!value && typeof value === 'object' && 'type' in value && typeof value.type === 'string'\n}\n\ninterface ClassNode {\n id?: Identifier | null\n body: ClassBody\n}\n\ninterface ClassMemberEntry {\n name: string\n node: Node\n index: number\n kind: 'constructor' | 'public-field' | 'other'\n}\n","import type { CallExpression, ExpressionStatement, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportTestOrdering(program: Program, context: Rule.RuleContext): void {\n const entries = collectTestPhaseEntries(program)\n if (!entries.some((entry) => entry.kind === 'test')) {\n return\n }\n\n reportSetupOrder(entries, context)\n reportTeardownOrder(entries, context)\n}\n\nfunction collectTestPhaseEntries(program: Program): TestPhaseEntry[] {\n const entries: TestPhaseEntry[] = []\n\n for (const [index, statement] of getTopLevelStatements(program).entries()) {\n const entry = toTestPhaseEntry(statement, index)\n if (entry) {\n entries.push(entry)\n }\n }\n\n return entries\n}\n\nfunction toTestPhaseEntry(statement: TopLevelNode, index: number): TestPhaseEntry | undefined {\n if (statement.type !== 'ExpressionStatement' || statement.expression.type !== 'CallExpression') {\n return undefined\n }\n\n const rootName = getCallRootName(statement.expression)\n if (!rootName) {\n return undefined\n }\n\n const kind = classifyHookName(rootName)\n if (!kind) {\n return undefined\n }\n\n return { index, kind, hookName: rootName, node: statement }\n}\n\nfunction classifyHookName(name: string): TestPhaseEntry['kind'] | undefined {\n if (SETUP_HOOKS.has(name)) return 'setup'\n if (TEARDOWN_HOOKS.has(name)) return 'teardown'\n if (TEST_CALLS.has(name)) return 'test'\n return undefined\n}\n\nconst SETUP_HOOKS = new Set(['beforeAll', 'beforeEach', 'before'])\nconst TEARDOWN_HOOKS = new Set(['afterAll', 'afterEach', 'after'])\nconst TEST_CALLS = new Set(['test', 'it'])\n\nfunction getCallRootName(call: CallExpression): string | undefined {\n const callee = call.callee\n if (callee.type === 'Identifier') return callee.name\n if (callee.type === 'MemberExpression') return readObjectRoot(callee.object)\n if (callee.type === 'CallExpression') return getCallRootName(callee)\n return undefined\n}\n\nfunction readObjectRoot(node: CallExpression['callee']): string | undefined {\n if (node.type === 'Identifier') return node.name\n if (node.type === 'MemberExpression') return readObjectRoot(node.object)\n if (node.type === 'CallExpression') return getCallRootName(node)\n return undefined\n}\n\nfunction reportSetupOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTeardown = findFirstIndex(entries, 'teardown')\n const firstTest = findFirstIndex(entries, 'test')\n\n for (const entry of entries) {\n if (entry.kind !== 'setup') continue\n\n if (firstTeardown >= 0 && entry.index > firstTeardown) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTeardown',\n data: { hookName: entry.hookName },\n })\n continue\n }\n\n if (firstTest >= 0 && entry.index > firstTest) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n }\n}\n\nfunction reportTeardownOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTest = findFirstIndex(entries, 'test')\n if (firstTest < 0) return\n\n for (const entry of entries) {\n if (entry.kind !== 'teardown' || entry.index <= firstTest) continue\n\n context.report({\n node: entry.node,\n messageId: 'teardownBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n}\n\nfunction findFirstIndex(entries: TestPhaseEntry[], kind: TestPhaseEntry['kind']): number {\n const match = entries.find((entry) => entry.kind === kind)\n return match ? match.index : -1\n}\n\ninterface TestPhaseEntry {\n index: number\n kind: 'setup' | 'teardown' | 'test'\n hookName: string\n node: ExpressionStatement\n}\n","import type { ExportNamedDeclaration, Node, Program, VariableDeclaration } from 'estree'\nimport type { Rule, Scope } from 'eslint'\nimport { reportClassOrdering } from './read-friendly-order/class-order.js'\nimport { reportTestOrdering } from './read-friendly-order/test-order.js'\n\nconst READ_FRIENDLY_ORDER_MESSAGES = {\n moveHelperBelow:\n 'Place helper \"{{helperName}}\" below the top-level symbol \"{{symbolName}}\" that depends on it.',\n moveConstantBelow:\n 'Place constant \"{{constantName}}\" below the top-level symbol \"{{symbolName}}\" that uses it.',\n constructorFirst: 'Place constructor first in class \"{{className}}\".',\n publicFieldOrder:\n 'Place public field \"{{memberName}}\" right after constructor and before other class members.',\n moveMemberBelow:\n 'Place class member \"{{memberName}}\" below member \"{{consumerName}}\" that depends on it.',\n setupBeforeTeardown: 'Place setup hook \"{{hookName}}\" before teardown hooks in this test file.',\n setupBeforeTests: 'Place setup hook \"{{hookName}}\" before test cases in this test file.',\n teardownBeforeTests: 'Place teardown hook \"{{hookName}}\" before test cases in this test file.',\n}\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Enforce top-level symbols before helper declarations they depend on',\n recommended: false,\n },\n schema: [],\n messages: READ_FRIENDLY_ORDER_MESSAGES,\n },\n create(context: Rule.RuleContext) {\n return {\n Program(program) {\n reportTopLevelOrdering(program, context)\n reportClassOrdering(program, context)\n reportTestOrdering(program, context)\n },\n }\n },\n} satisfies Rule.RuleModule\n\nexport type TopLevelNode = Program['body'][number]\n\nfunction reportTopLevelOrdering(program: Program, context: Rule.RuleContext): void {\n const body = getTopLevelStatements(program)\n const helpers = collectHelpers(body)\n const refs = collectReferences(context.sourceCode.scopeManager.globalScope)\n const cyclicNames = findCyclicHelperNames(body, helpers, refs)\n\n for (const helper of helpers) {\n if (cyclicNames.has(helper.name)) continue\n if (hasEagerReference(body, helper, refs)) continue\n\n const consumer = findFirstConsumer(body, helper, refs)\n if (!consumer) continue\n\n context.report({\n node: helper.node,\n messageId: helper.kind === 'constant' ? 'moveConstantBelow' : 'moveHelperBelow',\n data: {\n helperName: helper.name,\n constantName: helper.name,\n symbolName: getSymbolName(consumer),\n },\n })\n }\n}\n\nexport function getTopLevelStatements(program: Program): TopLevelNode[] {\n return program.body.filter((s) => s.type !== 'ImportDeclaration')\n}\n\nfunction collectHelpers(body: TopLevelNode[]): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n for (const [index, statement] of body.entries()) {\n helpers.push(...collectHelperEntries(statement, index))\n }\n return helpers\n}\n\nfunction collectHelperEntries(statement: TopLevelNode, index: number): HelperDeclaration[] {\n const typeName = getTypeDeclarationName(statement)\n if (typeName) return [{ name: typeName, node: statement, index, kind: 'helper' }]\n\n if (statement.type === 'FunctionDeclaration' && statement.id) {\n return [{ name: statement.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (statement.type === 'ExportNamedDeclaration') {\n return collectExportedHelpers(statement, index)\n }\n\n if (statement.type === 'VariableDeclaration') {\n return collectVariableHelpers(statement, index)\n }\n\n return []\n}\n\nfunction getTypeDeclarationName(statement: TopLevelNode): string | undefined {\n const t: string = statement.type\n if (t !== 'TSTypeAliasDeclaration' && t !== 'TSInterfaceDeclaration') return undefined\n return hasIdentifierId(statement) ? statement.id.name : undefined\n}\n\nfunction hasIdentifierId(value: object): value is { id: { type: string; name: string } } {\n if (!('id' in value)) return false\n const { id } = value\n return !!id && typeof id === 'object' && 'type' in id && 'name' in id && id.type === 'Identifier'\n}\n\nfunction collectExportedHelpers(\n statement: ExportNamedDeclaration,\n index: number,\n): HelperDeclaration[] {\n const decl = statement.declaration\n if (!decl) return []\n\n if (decl.type === 'FunctionDeclaration' && decl.id) {\n return [{ name: decl.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (decl.type === 'VariableDeclaration') return collectVariableHelpers(decl, index)\n return []\n}\n\nfunction collectVariableHelpers(decl: VariableDeclaration, index: number): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n\n for (const item of decl.declarations) {\n if (item.id.type !== 'Identifier') continue\n const isFn = isFunctionInit(item.init ?? null)\n\n if (!isFn && decl.kind !== 'const') continue\n\n helpers.push({\n name: item.id.name,\n node: item,\n index,\n kind: isFn ? 'helper' : 'constant',\n })\n }\n\n return helpers\n}\n\nfunction isFunctionInit(node: Node | null): boolean {\n return node?.type === 'ArrowFunctionExpression' || node?.type === 'FunctionExpression'\n}\n\nfunction findFirstConsumer(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): TopLevelNode | undefined {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementUsesName(stmt, helper.name, refs)) return stmt\n }\n return undefined\n}\n\nfunction findCyclicHelperNames(\n body: TopLevelNode[],\n helpers: HelperDeclaration[],\n refs: Scope.Reference[],\n): Set<string> {\n const deps = new Map<string, Set<string>>()\n\n for (const helper of helpers) {\n const helperDeps = new Set<string>()\n for (const other of helpers) {\n if (other.name !== helper.name && statementUsesName(body[helper.index], other.name, refs)) {\n helperDeps.add(other.name)\n }\n }\n deps.set(helper.name, helperDeps)\n }\n\n const cyclic = new Set<string>()\n for (const helper of helpers) {\n if (canReachSelf(helper.name, deps)) cyclic.add(helper.name)\n }\n return cyclic\n}\n\nfunction statementUsesName(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name) continue\n const idRange = ref.identifier.range\n if (!idRange) continue\n if (idRange[0] >= range[0] && idRange[1] <= range[1]) return true\n }\n\n return false\n}\n\nfunction canReachSelf(start: string, deps: Map<string, Set<string>>): boolean {\n const visited = new Set<string>()\n const queue = [...(deps.get(start) ?? [])]\n\n while (queue.length > 0) {\n const current = queue.shift()!\n if (current === start) return true\n if (visited.has(current)) continue\n visited.add(current)\n for (const dep of deps.get(current) ?? []) queue.push(dep)\n }\n\n return false\n}\n\nfunction collectReferences(scope: Scope.Scope | null): Scope.Reference[] {\n if (!scope) return []\n const refs = [...scope.references]\n for (const child of scope.childScopes) {\n refs.push(...collectReferences(child))\n }\n return refs\n}\n\nfunction hasEagerReference(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): boolean {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementHasEagerUse(stmt, helper.name, refs)) return true\n }\n return false\n}\n\nfunction statementHasEagerUse(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name || isTypeReference(ref)) continue\n if (isEagerRefInRange(ref, range)) return true\n }\n\n return false\n}\n\nfunction isEagerRefInRange(ref: Scope.Reference, range: [number, number]): boolean {\n const idRange = ref.identifier.range\n if (!idRange) return false\n const inside = idRange[0] >= range[0] && idRange[1] <= range[1]\n return inside && (ref.from.type === 'module' || ref.from.type === 'global')\n}\n\nfunction isTypeReference(ref: Scope.Reference): boolean {\n return 'isTypeReference' in ref && ref.isTypeReference === true\n}\n\nfunction getSymbolName(statement: TopLevelNode): string {\n if (statement.type === 'ExportDefaultDeclaration') return 'default export'\n if (statement.type === 'ExportNamedDeclaration') return getNamedExportName(statement)\n if (statement.type === 'FunctionDeclaration' && statement.id) return statement.id.name\n if (statement.type === 'VariableDeclaration')\n return getVarName(statement) ?? 'top-level statement'\n return 'top-level statement'\n}\n\nfunction getNamedExportName(statement: ExportNamedDeclaration): string {\n const decl = statement.declaration\n if (!decl) return 'named export'\n if (decl.type === 'FunctionDeclaration' && decl.id) return decl.id.name\n if (decl.type === 'VariableDeclaration') return getVarName(decl) ?? 'named export'\n return 'named export'\n}\n\nfunction getVarName(decl: VariableDeclaration): string | undefined {\n const [first] = decl.declarations\n return first?.id.type === 'Identifier' ? first.id.name : undefined\n}\n\ninterface HelperDeclaration {\n name: string\n node: Node\n index: number\n kind: 'helper' | 'constant'\n}\n","import type { Rule } from 'eslint'\nimport noSpecialUnicode from './no-special-unicode.js'\nimport noUnicodeEscape from './no-unicode-escape.js'\nimport noDeepImports from './no-deep-imports.js'\nimport noFalseSharing from './no-false-sharing.js'\nimport readFriendlyOrder from './read-friendly-order.js'\n\nexport default {\n 'no-special-unicode': noSpecialUnicode,\n 'no-unicode-escape': noUnicodeEscape,\n 'no-deep-imports': noDeepImports,\n 'no-false-sharing': noFalseSharing,\n 'read-friendly-order': readFriendlyOrder,\n} satisfies Record<string, Rule.RuleModule>\n"],"mappings":"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","names":["import_node_fs","import_node_path","path","import_node_path","path","path","import_node_fs","import_node_path","path","ts","isRecord"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../package.json","../src/utils/string-literal-listener.ts","../src/rules/no-special-unicode.ts","../src/rules/no-unicode-escape.ts","../src/rules/no-deep-imports.ts","../src/utils/path-helpers.ts","../src/utils/rule-options.ts","../src/utils/source-root.ts","../src/rules/no-false-sharing/analysis.ts","../src/rules/no-false-sharing.ts","../src/rules/read-friendly-order/class-order.ts","../src/rules/read-friendly-order/test-order.ts","../src/rules/read-friendly-order.ts","../src/rules/index.ts"],"sourcesContent":["import type { ESLint, Linter } from 'eslint'\nimport packageJson from '../package.json'\nimport rules from './rules/index.js'\n\n// configs.recommended.plugins.unslop must reference the plugin itself.\n// Build plugin first with an empty configs object, then assign below.\nconst plugin: ESLint.Plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n rules,\n configs: {},\n}\n\nconst recommended: Linter.Config = {\n name: 'unslop/recommended',\n plugins: { unslop: plugin },\n rules: {\n 'unslop/no-special-unicode': 'error',\n 'unslop/no-unicode-escape': 'error',\n 'unslop/no-deep-imports': 'error',\n },\n}\n\nplugin.configs!['recommended'] = recommended\n\nexport default plugin\n","{\n \"name\": \"eslint-plugin-unslop\",\n \"version\": \"0.1.3\",\n \"description\": \"ESLint plugin with rules for reducing AI-generated code smells\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/skhoroshavin/eslint-plugin-unslop\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"format\": \"prettier . --write\",\n \"verify\": \"prettier . --check && tsc --noEmit && tsup && eslint . && knip\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"eslint\",\n \"eslintplugin\",\n \"eslint-plugin\",\n \"ai\",\n \"code-quality\",\n \"unslop\"\n ],\n \"license\": \"MIT\",\n \"peerDependencies\": {\n \"eslint\": \">=9.0.0\",\n \"typescript\": \">=5.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"typescript\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.4\",\n \"@types/estree\": \"^1.0.8\",\n \"@types/node\": \"^22.18.0\",\n \"@typescript-eslint/parser\": \"^8.57.2\",\n \"eslint\": \"^9.39.1\",\n \"globals\": \"^17.4.0\",\n \"knip\": \"^6.1.0\",\n \"prettier\": \"^3.8.1\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.57.2\",\n \"vitest\": \"^3.2.4\"\n }\n}\n","import type { Rule } from 'eslint'\nimport type { Literal, TemplateLiteral } from 'estree'\n\nexport function createStringLiteralListener(\n includeEscapedUnicode: boolean,\n visitLiteral: StringLiteralVisitor,\n): Rule.RuleListener {\n function inspect(node: Literal | TemplateLiteral): void {\n const text = getStringValue(node, includeEscapedUnicode)\n if (text == undefined) {\n return\n }\n\n visitLiteral(node, text)\n }\n\n return {\n Literal: inspect,\n TemplateLiteral: inspect,\n }\n}\n\ntype StringLiteralVisitor = (node: Literal | TemplateLiteral, text: string) => void\n\nfunction getStringValue(\n node: Literal | TemplateLiteral,\n includeEscapedUnicode: boolean,\n): string | undefined {\n if (node.type === 'TemplateLiteral') {\n return node.quasis\n .map((q) =>\n includeEscapedUnicode ? (q.value.raw ?? q.value.cooked ?? '') : (q.value.cooked ?? ''),\n )\n .join('')\n }\n\n if (typeof node.value !== 'string') {\n return undefined\n }\n\n return includeEscapedUnicode ? (node.raw ?? node.value) : node.value\n}\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow special unicode punctuation and whitespace in strings',\n recommended: true,\n },\n schema: [],\n messages: {\n bannedCharacter: 'String contains {{name}} (U+{{code}}). Use the ASCII equivalent.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(false, (node, text) => {\n if (!BANNED_CHARS_RE.test(text)) {\n return\n }\n\n for (const [char, name] of BANNED_CHARS) {\n if (!text.includes(char)) {\n continue\n }\n\n const code = char.codePointAt(0) ?? 0\n\n context.report({\n node,\n messageId: 'bannedCharacter',\n data: {\n name,\n code: code.toString(16).toUpperCase().padStart(4, '0'),\n },\n })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst BANNED_CHARS = new Map([\n ['\\u201C', 'left double quotation mark'],\n ['\\u201D', 'right double quotation mark'],\n ['\\u2018', 'left single quotation mark'],\n ['\\u2019', 'right single quotation mark'],\n ['\\u00A0', 'non-breaking space'],\n ['\\u202F', 'narrow no-break space'],\n ['\\u2007', 'figure space'],\n ['\\u2008', 'punctuation space'],\n ['\\u2009', 'thin space'],\n ['\\u200A', 'hair space'],\n ['\\u200B', 'zero-width space'],\n ['\\u2002', 'en space'],\n ['\\u2003', 'em space'],\n ['\\u205F', 'medium mathematical space'],\n ['\\u3000', 'ideographic space'],\n ['\\uFEFF', 'zero-width no-break space'],\n ['\\u2013', 'en dash'],\n ['\\u2014', 'em dash'],\n ['\\u2026', 'horizontal ellipsis'],\n])\n\nconst BANNED_CHARS_RE = new RegExp([...BANNED_CHARS.keys()].join('|'))\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Prefer literal unicode characters over \\\\uXXXX escape sequences',\n recommended: true,\n },\n schema: [],\n messages: {\n preferLiteral: 'Use the actual character instead of a \\\\uXXXX escape sequence.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(true, (node, text) => {\n if (UNICODE_ESCAPE_RE.test(text)) {\n context.report({ node, messageId: 'preferLiteral' })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst UNICODE_ESCAPE_RE = /\\\\u[0-9a-fA-F]{4}/\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport type { Rule } from 'eslint'\nimport { toPosix } from '../utils/path-helpers.js'\nimport { readSourceRootOption } from '../utils/rule-options.js'\nimport { resolveSourceContext } from '../utils/source-root.js'\n\nconst NO_DEEP_IMPORTS_SCHEMA = [\n {\n type: 'object',\n properties: {\n sourceRoot: { type: 'string' },\n },\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Forbid deep imports inside the same top-level folder',\n recommended: true,\n },\n messages: {\n tooDeep:\n '{{sourceRelativePath}}: {{targetRelativePath}} is too deep (max 1 level below importer).',\n },\n schema: NO_DEEP_IMPORTS_SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot } = sourceContext\n\n return {\n ImportDeclaration(node) {\n const specifier = typeof node.source.value === 'string' ? node.source.value : ''\n\n const violation = findViolation(specifier, filename, sourceRoot, sourceRelativePath)\n\n if (violation) {\n context.report({\n node,\n messageId: 'tooDeep',\n data: violation,\n })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction findViolation(\n specifier: string,\n filename: string,\n sourceRoot: string,\n sourceRelativePath: string,\n): { sourceRelativePath: string; targetRelativePath: string } | undefined {\n const targetSourceRelative = resolveImportSourceRelative(specifier, filename, sourceRoot)\n if (!targetSourceRelative) {\n return undefined\n }\n\n const targetRelativePath = resolveTarget(targetSourceRelative, sourceRoot)\n if (!targetRelativePath) {\n return undefined\n }\n\n const folderScope = folderScopeFromPath(sourceRelativePath)\n if (!isInScope(targetRelativePath, folderScope)) {\n return undefined\n }\n\n const importerDepth = depthWithinScope(sourceRelativePath, folderScope)\n const targetDepth = depthWithinScope(targetRelativePath, folderScope)\n if (targetDepth <= importerDepth + 1) {\n return undefined\n }\n\n return {\n sourceRelativePath,\n targetRelativePath: stripTsExtension(targetRelativePath),\n }\n}\n\nfunction resolveImportSourceRelative(\n specifier: string,\n filename: string,\n sourceRoot: string,\n): string | undefined {\n const normalizedSpecifier = specifier.replace(/\\.js$/, '')\n\n if (normalizedSpecifier.startsWith('@/')) {\n return normalizedSpecifier.slice(2)\n }\n\n if (!normalizedSpecifier.startsWith('.')) {\n return undefined\n }\n\n const absoluteTarget = path.resolve(path.dirname(filename), normalizedSpecifier)\n const targetSourceRelative = path.relative(sourceRoot, absoluteTarget)\n if (targetSourceRelative.startsWith('..')) {\n return undefined\n }\n\n return toPosix(targetSourceRelative)\n}\n\nfunction resolveTarget(targetSourceRelative: string, sourceRoot: string): string | undefined {\n const cacheKey = `${sourceRoot}\\0${targetSourceRelative}`\n if (resolveCache.has(cacheKey)) {\n return resolveCache.get(cacheKey)\n }\n\n const candidates = [\n targetSourceRelative + '.ts',\n targetSourceRelative + '.tsx',\n targetSourceRelative + '/index.ts',\n targetSourceRelative + '/index.tsx',\n ]\n const candidate = candidates.find((entry) => existsSync(path.join(sourceRoot, entry)))\n const targetRelativePath = candidate ? toPosix(candidate) : undefined\n\n resolveCache.set(cacheKey, targetRelativePath)\n return targetRelativePath\n}\n\nfunction folderScopeFromPath(sourceRelativePath: string): string {\n const [firstPart = ''] = sourceRelativePath.split('/')\n return stripTsExtension(firstPart)\n}\n\nfunction isInScope(targetRelativePath: string, scope: string): boolean {\n const targetNoExtension = stripTsExtension(targetRelativePath)\n return targetNoExtension === scope || targetNoExtension.startsWith(`${scope}/`)\n}\n\nfunction depthWithinScope(relativePath: string, scope: string): number {\n const withoutExtension = stripTsExtension(relativePath)\n if (withoutExtension === scope) {\n return 0\n }\n\n // Precondition: isInScope() already confirmed target is within scope,\n // so withoutExtension always starts with scope + '/'\n const suffix = withoutExtension.slice(scope.length + 1)\n return suffix.split('/').length - 1\n}\n\nconst resolveCache = new Map<string, string | undefined>()\n\nfunction stripTsExtension(filePath: string): string {\n return filePath.replace(/\\.tsx?$/, '')\n}\n","import path from 'node:path'\n\nexport function toPosix(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nexport function isInsidePath(filePath: string, parentPath: string): boolean {\n const relativePath = path.relative(parentPath, filePath)\n return relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath))\n}\n","export function readSourceRootOption(options: unknown[]): string | undefined {\n const option = options[0]\n if (!isRecord(option) || !('sourceRoot' in option)) {\n return undefined\n }\n\n return typeof option.sourceRoot === 'string' ? option.sourceRoot : undefined\n}\n\nexport type SharingMode = 'file' | 'dir'\n\nexport interface DirEntry {\n path: string\n mode: SharingMode\n}\n\nexport function readDirsOption(options: unknown[], rootMode: SharingMode = 'file'): DirEntry[] {\n const option = options[0]\n if (!isRecord(option) || !('dirs' in option)) {\n return []\n }\n\n const rootModeResolved = readRootMode(option, rootMode)\n\n const { dirs } = option\n if (!Array.isArray(dirs)) {\n return []\n }\n\n return dirs.flatMap((entry) => {\n const parsed = parseDirEntry(entry, rootModeResolved)\n return parsed ? [parsed] : []\n })\n}\n\nfunction readRootMode(option: object, fallback: SharingMode): SharingMode {\n if (!('mode' in option)) {\n return fallback\n }\n\n return option.mode === 'dir' ? 'dir' : 'file'\n}\n\nfunction parseDirEntry(entry: unknown, defaultMode: SharingMode): DirEntry | undefined {\n if (!isRecord(entry) || !('path' in entry)) {\n return undefined\n }\n\n if (typeof entry.path !== 'string') {\n return undefined\n }\n\n const modeValue = 'mode' in entry ? entry.mode : undefined\n const mode: SharingMode = modeValue === 'dir' ? 'dir' : defaultMode\n\n return { path: entry.path, mode }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { isInsidePath, toPosix } from './path-helpers.js'\n\nexport function resolveSourceContext(\n filename: string,\n sourceRootOverride?: string,\n): SourceContext | undefined {\n if (filename === '<input>') {\n return undefined\n }\n\n const absoluteFilename = path.isAbsolute(filename) ? filename : path.resolve(filename)\n\n if (sourceRootOverride) {\n const projectRoot = findNearestPackageRoot(path.dirname(absoluteFilename)) ?? process.cwd()\n return buildContext(\n absoluteFilename,\n projectRoot,\n path.isAbsolute(sourceRootOverride)\n ? sourceRootOverride\n : path.join(projectRoot, sourceRootOverride),\n )\n }\n\n const packageRoot = findNearestPackageRoot(path.dirname(absoluteFilename))\n if (packageRoot) {\n return buildContext(\n absoluteFilename,\n packageRoot,\n existsSync(path.join(packageRoot, 'src')) ? path.join(packageRoot, 'src') : packageRoot,\n )\n }\n\n return resolveLegacySourceRoot(absoluteFilename)\n}\n\nfunction findNearestPackageRoot(startDirectory: string): string | undefined {\n let directory = startDirectory\n\n while (true) {\n if (existsSync(path.join(directory, 'package.json'))) {\n return directory\n }\n\n const parent = path.dirname(directory)\n if (parent === directory) {\n return undefined\n }\n\n directory = parent\n }\n}\n\nfunction resolveLegacySourceRoot(filename: string): SourceContext | undefined {\n const normalized = toPosix(filename)\n const sourceIndex = normalized.lastIndexOf('/src/')\n if (sourceIndex === -1) {\n return undefined\n }\n\n const projectRoot = normalized.slice(0, sourceIndex)\n const sourceRoot = path.join(projectRoot, 'src')\n return buildContext(filename, projectRoot, sourceRoot)\n}\n\nfunction buildContext(\n filename: string,\n projectRoot: string,\n sourceRoot: string,\n): SourceContext | undefined {\n if (!isInsidePath(filename, sourceRoot)) {\n return undefined\n }\n\n return {\n projectRoot,\n sourceRoot,\n sourceRelativePath: toPosix(path.relative(sourceRoot, filename)),\n }\n}\n\ninterface SourceContext {\n projectRoot: string\n sourceRoot: string\n sourceRelativePath: string\n}\n","import { existsSync, readdirSync } from 'node:fs'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport { isInsidePath, toPosix } from '../../utils/path-helpers.js'\nimport type { DirEntry, SharingMode } from '../../utils/rule-options.js'\n\nexport function runConsumerCheck(\n program: ts.Program,\n projectRoot: string,\n sourceRoot: string,\n directories: DirEntry[],\n): Map<string, string[]> {\n const checker = program.getTypeChecker()\n const sourceFiles = program.getSourceFiles().filter((sf) => isInsidePath(sf.fileName, sourceRoot))\n\n const modules = indexModules(directories, projectRoot, sourceRoot)\n const barrels = indexBarrels(directories, projectRoot, sourceFiles, checker)\n const ctx: AnalysisContext = { modules, barrels, checker }\n countConsumers(sourceFiles, sourceRoot, ctx)\n return collectErrors(modules)\n}\n\nfunction indexModules(\n directories: DirEntry[],\n projectRoot: string,\n sourceRoot: string,\n): Map<string, ModuleEntry> {\n const modules = new Map<string, ModuleEntry>()\n\n for (const dir of directories) {\n const absDir = path.join(projectRoot, dir.path)\n for (const file of listModuleFiles(absDir)) {\n modules.set(file, {\n relativePath: toPosix(path.relative(sourceRoot, file)),\n mode: dir.mode,\n consumers: new Set(),\n })\n }\n }\n\n return modules\n}\n\nfunction listModuleFiles(directory: string): string[] {\n if (!existsSync(directory)) {\n return []\n }\n\n return readdirSync(directory, { withFileTypes: true })\n .filter(\n (e) =>\n e.isFile() &&\n (e.name.endsWith('.ts') || e.name.endsWith('.tsx')) &&\n e.name !== 'index.ts' &&\n !isTestFile(e.name),\n )\n .map((e) => path.join(directory, e.name))\n}\n\nfunction indexBarrels(\n directories: DirEntry[],\n projectRoot: string,\n sourceFiles: ts.SourceFile[],\n checker: ts.TypeChecker,\n): Map<string, Map<string, string>> {\n const barrels = new Map<string, Map<string, string>>()\n const sfByPath = new Map(sourceFiles.map((sf) => [sf.fileName, sf]))\n\n for (const dir of directories) {\n const barrelPath = path.join(projectRoot, dir.path, 'index.ts')\n const barrelSf = sfByPath.get(barrelPath)\n if (barrelSf) {\n barrels.set(barrelPath, buildBarrelMap(barrelSf, checker))\n }\n }\n\n return barrels\n}\n\nfunction buildBarrelMap(barrelFile: ts.SourceFile, checker: ts.TypeChecker): Map<string, string> {\n const map = new Map<string, string>()\n\n for (const stmt of barrelFile.statements) {\n if (!isNamedReExport(stmt)) continue\n\n const targetPath = resolveModulePath(stmt.moduleSpecifier, checker)\n if (!targetPath) continue\n\n for (const el of stmt.exportClause.elements) {\n if (!el.isTypeOnly) {\n map.set(el.name.text, targetPath)\n }\n }\n }\n\n return map\n}\n\nfunction isNamedReExport(stmt: ts.Statement): stmt is ts.ExportDeclaration & {\n exportClause: ts.NamedExports\n moduleSpecifier: ts.Expression\n} {\n return (\n ts.isExportDeclaration(stmt) &&\n !stmt.isTypeOnly &&\n !!stmt.moduleSpecifier &&\n !!stmt.exportClause &&\n ts.isNamedExports(stmt.exportClause)\n )\n}\n\nfunction countConsumers(\n sourceFiles: ts.SourceFile[],\n sourceRoot: string,\n ctx: AnalysisContext,\n): void {\n for (const sf of sourceFiles) {\n if (ctx.modules.has(sf.fileName) || isTestFile(sf.fileName)) continue\n\n const consumerPath = toPosix(path.relative(sourceRoot, sf.fileName))\n\n for (const stmt of sf.statements) {\n if (ts.isImportDeclaration(stmt)) {\n recordImport(stmt, consumerPath, ctx)\n }\n }\n }\n}\n\nfunction isTestFile(filePath: string): boolean {\n return TEST_FILE_RE.test(filePath)\n}\n\nconst TEST_FILE_RE = /\\.(test|integration-test|test-suite)\\.ts$/\n\nfunction recordImport(\n stmt: ts.ImportDeclaration,\n consumerPath: string,\n ctx: AnalysisContext,\n): void {\n const targetPath = resolveModulePath(stmt.moduleSpecifier, ctx.checker)\n if (!targetPath) return\n\n const direct = ctx.modules.get(targetPath)\n if (direct) {\n direct.consumers.add(deriveEntity(consumerPath, direct.mode))\n return\n }\n\n const barrelMap = ctx.barrels.get(targetPath)\n if (barrelMap) {\n resolveBarrelImports(stmt, barrelMap, consumerPath, ctx.modules)\n }\n}\n\nfunction resolveBarrelImports(\n stmt: ts.ImportDeclaration,\n barrelMap: Map<string, string>,\n consumerPath: string,\n modules: Map<string, ModuleEntry>,\n): void {\n const bindings = stmt.importClause?.namedBindings\n if (!bindings) return\n\n const paths = ts.isNamespaceImport(bindings)\n ? [...barrelMap.values()]\n : resolveNamedImports(bindings, barrelMap)\n\n for (const resolved of paths) {\n const entry = modules.get(resolved)\n entry?.consumers.add(deriveEntity(consumerPath, entry.mode))\n }\n}\n\nfunction resolveNamedImports(bindings: ts.NamedImports, barrelMap: Map<string, string>): string[] {\n const result: string[] = []\n for (const el of bindings.elements) {\n const name = el.propertyName?.text ?? el.name.text\n const resolved = barrelMap.get(name)\n if (resolved) {\n result.push(resolved)\n }\n }\n return result\n}\n\nfunction resolveModulePath(specifier: ts.Expression, checker: ts.TypeChecker): string | undefined {\n const symbol = checker.getSymbolAtLocation(specifier)\n return symbol?.declarations?.[0]?.getSourceFile().fileName\n}\n\nfunction collectErrors(modules: Map<string, ModuleEntry>): Map<string, string[]> {\n const errors = new Map<string, string[]>()\n\n for (const [, entry] of modules) {\n if (entry.consumers.size >= 2) continue\n\n const consumers = [...entry.consumers]\n const description =\n consumers.length === 0\n ? 'not imported by any entity'\n : `only used by: ${consumers.join(', ')}`\n\n errors.set(entry.relativePath, [`${description} -> Must be used by 2+ entities`])\n }\n\n return errors\n}\n\nfunction deriveEntity(consumerPath: string, mode: SharingMode): string {\n if (mode === 'file') {\n return consumerPath\n }\n return consumerPath.split('/').slice(0, -1).slice(0, MAX_DIR_DEPTH).join('/')\n}\n\nconst MAX_DIR_DEPTH = 3\n\ninterface AnalysisContext {\n modules: Map<string, ModuleEntry>\n barrels: Map<string, Map<string, string>>\n checker: ts.TypeChecker\n}\n\ninterface ModuleEntry {\n relativePath: string\n mode: SharingMode\n consumers: Set<string>\n}\n","import type { Rule } from 'eslint'\nimport type ts from 'typescript'\nimport { resolveSourceContext } from '../utils/source-root.js'\nimport { readDirsOption, readSourceRootOption } from '../utils/rule-options.js'\nimport { runConsumerCheck } from './no-false-sharing/analysis.js'\n\nconst SCHEMA = [\n {\n type: 'object',\n properties: {\n dirs: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n mode: { type: 'string', enum: ['file', 'dir'] },\n },\n required: ['path'],\n additionalProperties: false,\n },\n },\n mode: { type: 'string', enum: ['file', 'dir'] },\n sourceRoot: { type: 'string' },\n },\n required: ['dirs'],\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Require selected modules to be shared across at least two consumer entities',\n recommended: false,\n },\n schema: SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const dirs = readDirsOption(context.options)\n if (dirs.length === 0) {\n return {}\n }\n\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot, projectRoot } = sourceContext\n\n return {\n Program(node) {\n const program = extractTsProgram(context)\n if (!program) {\n return\n }\n\n const errors = runConsumerCheck(program, projectRoot, sourceRoot, dirs)\n const fileErrors = errors.get(sourceRelativePath)\n if (!fileErrors) {\n return\n }\n\n for (const message of fileErrors) {\n context.report({ node, message })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction extractTsProgram(context: Rule.RuleContext): ts.Program | undefined {\n const services = context.sourceCode.parserServices\n if (!isRecord(services) || !('program' in services)) {\n return undefined\n }\n const program = services.program\n if (!isTsProgram(program)) {\n return undefined\n }\n return program\n}\n\nfunction isTsProgram(value: unknown): value is ts.Program {\n return isRecord(value) && 'getTypeChecker' in value\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import type { ClassBody, Identifier, Node, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportClassOrdering(program: Program, context: Rule.RuleContext): void {\n for (const classNode of collectClassDeclarations(program)) {\n const members = collectClassMembers(classNode)\n reportConstructorOrder(members, classNode, context)\n reportPublicFieldOrder(members, context)\n reportClassDependencyOrder(members, context)\n }\n}\n\nfunction collectClassDeclarations(program: Program): ClassNode[] {\n const classes: ClassNode[] = []\n\n for (const statement of getTopLevelStatements(program)) {\n const classNode = extractClassNode(statement)\n if (classNode) classes.push(classNode)\n }\n\n return classes\n}\n\nfunction extractClassNode(statement: TopLevelNode): ClassNode | undefined {\n if (statement.type === 'ClassDeclaration') return statement\n\n if (\n statement.type === 'ExportNamedDeclaration' &&\n statement.declaration?.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n if (\n statement.type === 'ExportDefaultDeclaration' &&\n statement.declaration.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n return undefined\n}\n\nfunction reportConstructorOrder(\n members: ClassMemberEntry[],\n classNode: ClassNode,\n context: Rule.RuleContext,\n): void {\n const ctor = members.find((m) => m.kind === 'constructor')\n if (!ctor || ctor.index === 0) return\n\n context.report({\n node: ctor.node,\n messageId: 'constructorFirst',\n data: { className: classNode.id?.name ?? 'anonymous class' },\n })\n}\n\nfunction reportPublicFieldOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const ctorIndex = members.find((m) => m.kind === 'constructor')?.index ?? -1\n const startIndex = ctorIndex >= 0 ? ctorIndex + 1 : 0\n let seenOther = false\n\n for (const member of members) {\n if (member.index < startIndex) continue\n\n if (member.kind === 'public-field') {\n if (seenOther) {\n context.report({\n node: member.node,\n messageId: 'publicFieldOrder',\n data: { memberName: member.name },\n })\n }\n continue\n }\n\n seenOther = true\n }\n}\n\nfunction reportClassDependencyOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const others = members.filter((m) => m.kind === 'other')\n\n for (const member of others) {\n const consumer = findFirstClassConsumer(others, member, context)\n if (!consumer) continue\n\n context.report({\n node: member.node,\n messageId: 'moveMemberBelow',\n data: { memberName: member.name, consumerName: consumer.name },\n })\n }\n}\n\nfunction collectClassMembers(classNode: ClassNode): ClassMemberEntry[] {\n const members: ClassMemberEntry[] = []\n\n for (const [index, raw] of classNode.body.body.entries()) {\n const named = toNamedMember(raw)\n if (!named) continue\n members.push({ name: named.name, node: named.node, index, kind: classifyMember(named.node) })\n }\n\n return members\n}\n\nfunction toNamedMember(raw: Node): { name: string; node: Node } | undefined {\n if (!hasMemberKey(raw)) return undefined\n const name = readMemberName(raw.key)\n return name ? { name, node: raw } : undefined\n}\n\nfunction hasMemberKey(value: object): value is { key: Node } {\n return 'key' in value && isNode(value.key)\n}\n\nfunction readMemberName(key: Node): string | undefined {\n if (key.type === 'Identifier') return key.name\n if (key.type === 'Literal' && typeof key.value === 'string') return key.value\n if (key.type === 'PrivateIdentifier') return `#${key.name}`\n return undefined\n}\n\nfunction classifyMember(member: Node): ClassMemberEntry['kind'] {\n if (member.type === 'MethodDefinition' && member.kind === 'constructor') return 'constructor'\n if (isPublicField(member)) return 'public-field'\n return 'other'\n}\n\nfunction isPublicField(member: Node): boolean {\n if (member.type !== 'PropertyDefinition' || member.static) return false\n if (member.key.type === 'PrivateIdentifier') return false\n if (!('accessibility' in member)) return true\n return member.accessibility === undefined || member.accessibility === 'public'\n}\n\nfunction findFirstClassConsumer(\n members: ClassMemberEntry[],\n member: ClassMemberEntry,\n context: Rule.RuleContext,\n): ClassMemberEntry | undefined {\n const pattern = new RegExp(`\\\\bthis(?:\\\\?\\\\.|\\\\.)${escapeRegex(member.name)}\\\\b`)\n\n for (const candidate of members) {\n if (candidate.index <= member.index) continue\n if (pattern.test(context.sourceCode.getText(candidate.node))) return candidate\n }\n\n return undefined\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction isNode(value: unknown): value is Node {\n return !!value && typeof value === 'object' && 'type' in value && typeof value.type === 'string'\n}\n\ninterface ClassNode {\n id?: Identifier | null\n body: ClassBody\n}\n\ninterface ClassMemberEntry {\n name: string\n node: Node\n index: number\n kind: 'constructor' | 'public-field' | 'other'\n}\n","import type { CallExpression, ExpressionStatement, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportTestOrdering(program: Program, context: Rule.RuleContext): void {\n const entries = collectTestPhaseEntries(program)\n if (!entries.some((entry) => entry.kind === 'test')) {\n return\n }\n\n reportSetupOrder(entries, context)\n reportTeardownOrder(entries, context)\n}\n\nfunction collectTestPhaseEntries(program: Program): TestPhaseEntry[] {\n const entries: TestPhaseEntry[] = []\n\n for (const [index, statement] of getTopLevelStatements(program).entries()) {\n const entry = toTestPhaseEntry(statement, index)\n if (entry) {\n entries.push(entry)\n }\n }\n\n return entries\n}\n\nfunction toTestPhaseEntry(statement: TopLevelNode, index: number): TestPhaseEntry | undefined {\n if (statement.type !== 'ExpressionStatement' || statement.expression.type !== 'CallExpression') {\n return undefined\n }\n\n const rootName = getCallRootName(statement.expression)\n if (!rootName) {\n return undefined\n }\n\n const kind = classifyHookName(rootName)\n if (!kind) {\n return undefined\n }\n\n return { index, kind, hookName: rootName, node: statement }\n}\n\nfunction classifyHookName(name: string): TestPhaseEntry['kind'] | undefined {\n if (SETUP_HOOKS.has(name)) return 'setup'\n if (TEARDOWN_HOOKS.has(name)) return 'teardown'\n if (TEST_CALLS.has(name)) return 'test'\n return undefined\n}\n\nconst SETUP_HOOKS = new Set(['beforeAll', 'beforeEach', 'before'])\nconst TEARDOWN_HOOKS = new Set(['afterAll', 'afterEach', 'after'])\nconst TEST_CALLS = new Set(['test', 'it'])\n\nfunction getCallRootName(call: CallExpression): string | undefined {\n const callee = call.callee\n if (callee.type === 'Identifier') return callee.name\n if (callee.type === 'MemberExpression') return readObjectRoot(callee.object)\n if (callee.type === 'CallExpression') return getCallRootName(callee)\n return undefined\n}\n\nfunction readObjectRoot(node: CallExpression['callee']): string | undefined {\n if (node.type === 'Identifier') return node.name\n if (node.type === 'MemberExpression') return readObjectRoot(node.object)\n if (node.type === 'CallExpression') return getCallRootName(node)\n return undefined\n}\n\nfunction reportSetupOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTeardown = findFirstIndex(entries, 'teardown')\n const firstTest = findFirstIndex(entries, 'test')\n\n for (const entry of entries) {\n if (entry.kind !== 'setup') continue\n\n if (firstTeardown >= 0 && entry.index > firstTeardown) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTeardown',\n data: { hookName: entry.hookName },\n })\n continue\n }\n\n if (firstTest >= 0 && entry.index > firstTest) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n }\n}\n\nfunction reportTeardownOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTest = findFirstIndex(entries, 'test')\n if (firstTest < 0) return\n\n for (const entry of entries) {\n if (entry.kind !== 'teardown' || entry.index <= firstTest) continue\n\n context.report({\n node: entry.node,\n messageId: 'teardownBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n}\n\nfunction findFirstIndex(entries: TestPhaseEntry[], kind: TestPhaseEntry['kind']): number {\n const match = entries.find((entry) => entry.kind === kind)\n return match ? match.index : -1\n}\n\ninterface TestPhaseEntry {\n index: number\n kind: 'setup' | 'teardown' | 'test'\n hookName: string\n node: ExpressionStatement\n}\n","import type { ExportNamedDeclaration, Node, Program, VariableDeclaration } from 'estree'\nimport type { Rule, Scope } from 'eslint'\nimport { reportClassOrdering } from './read-friendly-order/class-order.js'\nimport { reportTestOrdering } from './read-friendly-order/test-order.js'\n\nconst READ_FRIENDLY_ORDER_MESSAGES = {\n moveHelperBelow:\n 'Place helper \"{{helperName}}\" below the top-level symbol \"{{symbolName}}\" that depends on it.',\n moveConstantBelow:\n 'Place constant \"{{constantName}}\" below the top-level symbol \"{{symbolName}}\" that uses it.',\n constructorFirst: 'Place constructor first in class \"{{className}}\".',\n publicFieldOrder:\n 'Place public field \"{{memberName}}\" right after constructor and before other class members.',\n moveMemberBelow:\n 'Place class member \"{{memberName}}\" below member \"{{consumerName}}\" that depends on it.',\n setupBeforeTeardown: 'Place setup hook \"{{hookName}}\" before teardown hooks in this test file.',\n setupBeforeTests: 'Place setup hook \"{{hookName}}\" before test cases in this test file.',\n teardownBeforeTests: 'Place teardown hook \"{{hookName}}\" before test cases in this test file.',\n}\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Enforce top-level symbols before helper declarations they depend on',\n recommended: false,\n },\n schema: [],\n messages: READ_FRIENDLY_ORDER_MESSAGES,\n },\n create(context: Rule.RuleContext) {\n return {\n Program(program) {\n reportTopLevelOrdering(program, context)\n reportClassOrdering(program, context)\n reportTestOrdering(program, context)\n },\n }\n },\n} satisfies Rule.RuleModule\n\nexport type TopLevelNode = Program['body'][number]\n\nfunction reportTopLevelOrdering(program: Program, context: Rule.RuleContext): void {\n const body = getTopLevelStatements(program)\n const helpers = collectHelpers(body)\n const refs = collectReferences(context.sourceCode.scopeManager.globalScope)\n const cyclicNames = findCyclicHelperNames(body, helpers, refs)\n\n for (const helper of helpers) {\n if (cyclicNames.has(helper.name)) continue\n if (hasEagerReference(body, helper, refs)) continue\n\n const consumer = findFirstConsumer(body, helper, refs)\n if (!consumer) continue\n\n context.report({\n node: helper.node,\n messageId: helper.kind === 'constant' ? 'moveConstantBelow' : 'moveHelperBelow',\n data: {\n helperName: helper.name,\n constantName: helper.name,\n symbolName: getSymbolName(consumer),\n },\n })\n }\n}\n\nexport function getTopLevelStatements(program: Program): TopLevelNode[] {\n return program.body.filter((s) => s.type !== 'ImportDeclaration')\n}\n\nfunction collectHelpers(body: TopLevelNode[]): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n for (const [index, statement] of body.entries()) {\n helpers.push(...collectHelperEntries(statement, index))\n }\n return helpers\n}\n\nfunction collectHelperEntries(statement: TopLevelNode, index: number): HelperDeclaration[] {\n const typeName = getTypeDeclarationName(statement)\n if (typeName) return [{ name: typeName, node: statement, index, kind: 'helper' }]\n\n if (statement.type === 'FunctionDeclaration' && statement.id) {\n return [{ name: statement.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (statement.type === 'ExportNamedDeclaration') {\n return collectExportedHelpers(statement, index)\n }\n\n if (statement.type === 'VariableDeclaration') {\n return collectVariableHelpers(statement, index)\n }\n\n return []\n}\n\nfunction getTypeDeclarationName(statement: TopLevelNode): string | undefined {\n const t: string = statement.type\n if (t !== 'TSTypeAliasDeclaration' && t !== 'TSInterfaceDeclaration') return undefined\n return hasIdentifierId(statement) ? statement.id.name : undefined\n}\n\nfunction hasIdentifierId(value: object): value is { id: { type: string; name: string } } {\n if (!('id' in value)) return false\n const { id } = value\n return !!id && typeof id === 'object' && 'type' in id && 'name' in id && id.type === 'Identifier'\n}\n\nfunction collectExportedHelpers(\n statement: ExportNamedDeclaration,\n index: number,\n): HelperDeclaration[] {\n const decl = statement.declaration\n if (!decl) return []\n\n if (decl.type === 'FunctionDeclaration' && decl.id) {\n return [{ name: decl.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (decl.type === 'VariableDeclaration') return collectVariableHelpers(decl, index)\n return []\n}\n\nfunction collectVariableHelpers(decl: VariableDeclaration, index: number): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n\n for (const item of decl.declarations) {\n if (item.id.type !== 'Identifier') continue\n const isFn = isFunctionInit(item.init ?? null)\n\n if (!isFn && decl.kind !== 'const') continue\n\n helpers.push({\n name: item.id.name,\n node: item,\n index,\n kind: isFn ? 'helper' : 'constant',\n })\n }\n\n return helpers\n}\n\nfunction isFunctionInit(node: Node | null): boolean {\n return node?.type === 'ArrowFunctionExpression' || node?.type === 'FunctionExpression'\n}\n\nfunction findFirstConsumer(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): TopLevelNode | undefined {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementUsesName(stmt, helper.name, refs)) return stmt\n }\n return undefined\n}\n\nfunction findCyclicHelperNames(\n body: TopLevelNode[],\n helpers: HelperDeclaration[],\n refs: Scope.Reference[],\n): Set<string> {\n const deps = new Map<string, Set<string>>()\n\n for (const helper of helpers) {\n const helperDeps = new Set<string>()\n for (const other of helpers) {\n if (other.name !== helper.name && statementUsesName(body[helper.index], other.name, refs)) {\n helperDeps.add(other.name)\n }\n }\n deps.set(helper.name, helperDeps)\n }\n\n const cyclic = new Set<string>()\n for (const helper of helpers) {\n if (canReachSelf(helper.name, deps)) cyclic.add(helper.name)\n }\n return cyclic\n}\n\nfunction statementUsesName(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name) continue\n const idRange = ref.identifier.range\n if (!idRange) continue\n if (idRange[0] >= range[0] && idRange[1] <= range[1]) return true\n }\n\n return false\n}\n\nfunction canReachSelf(start: string, deps: Map<string, Set<string>>): boolean {\n const visited = new Set<string>()\n const queue = [...(deps.get(start) ?? [])]\n\n while (queue.length > 0) {\n const current = queue.shift()!\n if (current === start) return true\n if (visited.has(current)) continue\n visited.add(current)\n for (const dep of deps.get(current) ?? []) queue.push(dep)\n }\n\n return false\n}\n\nfunction collectReferences(scope: Scope.Scope | null): Scope.Reference[] {\n if (!scope) return []\n const refs = [...scope.references]\n for (const child of scope.childScopes) {\n refs.push(...collectReferences(child))\n }\n return refs\n}\n\nfunction hasEagerReference(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): boolean {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementHasEagerUse(stmt, helper.name, refs)) return true\n }\n return false\n}\n\nfunction statementHasEagerUse(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name || isTypeReference(ref)) continue\n if (isEagerRefInRange(ref, range)) return true\n }\n\n return false\n}\n\nfunction isEagerRefInRange(ref: Scope.Reference, range: [number, number]): boolean {\n const idRange = ref.identifier.range\n if (!idRange) return false\n const inside = idRange[0] >= range[0] && idRange[1] <= range[1]\n return inside && (ref.from.type === 'module' || ref.from.type === 'global')\n}\n\nfunction isTypeReference(ref: Scope.Reference): boolean {\n return 'isTypeReference' in ref && ref.isTypeReference === true\n}\n\nfunction getSymbolName(statement: TopLevelNode): string {\n if (statement.type === 'ExportDefaultDeclaration') return 'default export'\n if (statement.type === 'ExportNamedDeclaration') return getNamedExportName(statement)\n if (statement.type === 'FunctionDeclaration' && statement.id) return statement.id.name\n if (statement.type === 'VariableDeclaration')\n return getVarName(statement) ?? 'top-level statement'\n return 'top-level statement'\n}\n\nfunction getNamedExportName(statement: ExportNamedDeclaration): string {\n const decl = statement.declaration\n if (!decl) return 'named export'\n if (decl.type === 'FunctionDeclaration' && decl.id) return decl.id.name\n if (decl.type === 'VariableDeclaration') return getVarName(decl) ?? 'named export'\n return 'named export'\n}\n\nfunction getVarName(decl: VariableDeclaration): string | undefined {\n const [first] = decl.declarations\n return first?.id.type === 'Identifier' ? first.id.name : undefined\n}\n\ninterface HelperDeclaration {\n name: string\n node: Node\n index: number\n kind: 'helper' | 'constant'\n}\n","import type { Rule } from 'eslint'\nimport noSpecialUnicode from './no-special-unicode.js'\nimport noUnicodeEscape from './no-unicode-escape.js'\nimport noDeepImports from './no-deep-imports.js'\nimport noFalseSharing from './no-false-sharing.js'\nimport readFriendlyOrder from './read-friendly-order.js'\n\nexport default {\n 'no-special-unicode': noSpecialUnicode,\n 'no-unicode-escape': noUnicodeEscape,\n 'no-deep-imports': noDeepImports,\n 'no-false-sharing': noFalseSharing,\n 'read-friendly-order': readFriendlyOrder,\n} satisfies Record<string, Rule.RuleModule>\n"],"mappings":"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","names":["import_node_fs","import_node_path","path","import_node_path","path","path","import_node_fs","import_node_path","path","ts","isRecord"]}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "eslint-plugin-unslop",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.3",
|
|
5
5
|
description: "ESLint plugin with rules for reducing AI-generated code smells",
|
|
6
6
|
repository: {
|
|
7
7
|
type: "git",
|
|
@@ -28,12 +28,9 @@ var package_default = {
|
|
|
28
28
|
scripts: {
|
|
29
29
|
build: "tsup",
|
|
30
30
|
format: "prettier . --write",
|
|
31
|
-
|
|
32
|
-
knip: "knip",
|
|
33
|
-
lint: "npm run build && eslint .",
|
|
31
|
+
verify: "prettier . --check && tsc --noEmit && tsup && eslint . && knip",
|
|
34
32
|
test: "vitest run",
|
|
35
33
|
"test:watch": "vitest",
|
|
36
|
-
typecheck: "tsc --noEmit",
|
|
37
34
|
prepublishOnly: "npm run build"
|
|
38
35
|
},
|
|
39
36
|
keywords: [
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/utils/string-literal-listener.ts","../src/rules/no-special-unicode.ts","../src/rules/no-unicode-escape.ts","../src/rules/no-deep-imports.ts","../src/utils/path-helpers.ts","../src/utils/rule-options.ts","../src/utils/source-root.ts","../src/rules/no-false-sharing/analysis.ts","../src/rules/no-false-sharing.ts","../src/rules/read-friendly-order/class-order.ts","../src/rules/read-friendly-order/test-order.ts","../src/rules/read-friendly-order.ts","../src/rules/index.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"eslint-plugin-unslop\",\n \"version\": \"0.1.2\",\n \"description\": \"ESLint plugin with rules for reducing AI-generated code smells\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/skhoroshavin/eslint-plugin-unslop\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"format\": \"prettier . --write\",\n \"format:check\": \"prettier . --check\",\n \"knip\": \"knip\",\n \"lint\": \"npm run build && eslint .\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"typecheck\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"eslint\",\n \"eslintplugin\",\n \"eslint-plugin\",\n \"ai\",\n \"code-quality\",\n \"unslop\"\n ],\n \"license\": \"MIT\",\n \"peerDependencies\": {\n \"eslint\": \">=9.0.0\",\n \"typescript\": \">=5.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"typescript\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.4\",\n \"@types/estree\": \"^1.0.8\",\n \"@types/node\": \"^22.18.0\",\n \"@typescript-eslint/parser\": \"^8.57.2\",\n \"eslint\": \"^9.39.1\",\n \"globals\": \"^17.4.0\",\n \"knip\": \"^6.1.0\",\n \"prettier\": \"^3.8.1\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.57.2\",\n \"vitest\": \"^3.2.4\"\n }\n}\n","import type { Rule } from 'eslint'\nimport type { Literal, TemplateLiteral } from 'estree'\n\nexport function createStringLiteralListener(\n includeEscapedUnicode: boolean,\n visitLiteral: StringLiteralVisitor,\n): Rule.RuleListener {\n function inspect(node: Literal | TemplateLiteral): void {\n const text = getStringValue(node, includeEscapedUnicode)\n if (text == undefined) {\n return\n }\n\n visitLiteral(node, text)\n }\n\n return {\n Literal: inspect,\n TemplateLiteral: inspect,\n }\n}\n\ntype StringLiteralVisitor = (node: Literal | TemplateLiteral, text: string) => void\n\nfunction getStringValue(\n node: Literal | TemplateLiteral,\n includeEscapedUnicode: boolean,\n): string | undefined {\n if (node.type === 'TemplateLiteral') {\n return node.quasis\n .map((q) =>\n includeEscapedUnicode ? (q.value.raw ?? q.value.cooked ?? '') : (q.value.cooked ?? ''),\n )\n .join('')\n }\n\n if (typeof node.value !== 'string') {\n return undefined\n }\n\n return includeEscapedUnicode ? (node.raw ?? node.value) : node.value\n}\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow special unicode punctuation and whitespace in strings',\n recommended: true,\n },\n schema: [],\n messages: {\n bannedCharacter: 'String contains {{name}} (U+{{code}}). Use the ASCII equivalent.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(false, (node, text) => {\n if (!BANNED_CHARS_RE.test(text)) {\n return\n }\n\n for (const [char, name] of BANNED_CHARS) {\n if (!text.includes(char)) {\n continue\n }\n\n const code = char.codePointAt(0) ?? 0\n\n context.report({\n node,\n messageId: 'bannedCharacter',\n data: {\n name,\n code: code.toString(16).toUpperCase().padStart(4, '0'),\n },\n })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst BANNED_CHARS = new Map([\n ['\\u201C', 'left double quotation mark'],\n ['\\u201D', 'right double quotation mark'],\n ['\\u2018', 'left single quotation mark'],\n ['\\u2019', 'right single quotation mark'],\n ['\\u00A0', 'non-breaking space'],\n ['\\u202F', 'narrow no-break space'],\n ['\\u2007', 'figure space'],\n ['\\u2008', 'punctuation space'],\n ['\\u2009', 'thin space'],\n ['\\u200A', 'hair space'],\n ['\\u200B', 'zero-width space'],\n ['\\u2002', 'en space'],\n ['\\u2003', 'em space'],\n ['\\u205F', 'medium mathematical space'],\n ['\\u3000', 'ideographic space'],\n ['\\uFEFF', 'zero-width no-break space'],\n ['\\u2013', 'en dash'],\n ['\\u2014', 'em dash'],\n ['\\u2026', 'horizontal ellipsis'],\n])\n\nconst BANNED_CHARS_RE = new RegExp([...BANNED_CHARS.keys()].join('|'))\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Prefer literal unicode characters over \\\\uXXXX escape sequences',\n recommended: true,\n },\n schema: [],\n messages: {\n preferLiteral: 'Use the actual character instead of a \\\\uXXXX escape sequence.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(true, (node, text) => {\n if (UNICODE_ESCAPE_RE.test(text)) {\n context.report({ node, messageId: 'preferLiteral' })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst UNICODE_ESCAPE_RE = /\\\\u[0-9a-fA-F]{4}/\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport type { Rule } from 'eslint'\nimport { toPosix } from '../utils/path-helpers.js'\nimport { readSourceRootOption } from '../utils/rule-options.js'\nimport { resolveSourceContext } from '../utils/source-root.js'\n\nconst NO_DEEP_IMPORTS_SCHEMA = [\n {\n type: 'object',\n properties: {\n sourceRoot: { type: 'string' },\n },\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Forbid deep imports inside the same top-level folder',\n recommended: true,\n },\n messages: {\n tooDeep:\n '{{sourceRelativePath}}: {{targetRelativePath}} is too deep (max 1 level below importer).',\n },\n schema: NO_DEEP_IMPORTS_SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot } = sourceContext\n\n return {\n ImportDeclaration(node) {\n const specifier = typeof node.source.value === 'string' ? node.source.value : ''\n\n const violation = findViolation(specifier, filename, sourceRoot, sourceRelativePath)\n\n if (violation) {\n context.report({\n node,\n messageId: 'tooDeep',\n data: violation,\n })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction findViolation(\n specifier: string,\n filename: string,\n sourceRoot: string,\n sourceRelativePath: string,\n): { sourceRelativePath: string; targetRelativePath: string } | undefined {\n const targetSourceRelative = resolveImportSourceRelative(specifier, filename, sourceRoot)\n if (!targetSourceRelative) {\n return undefined\n }\n\n const targetRelativePath = resolveTarget(targetSourceRelative, sourceRoot)\n if (!targetRelativePath) {\n return undefined\n }\n\n const folderScope = folderScopeFromPath(sourceRelativePath)\n if (!isInScope(targetRelativePath, folderScope)) {\n return undefined\n }\n\n const importerDepth = depthWithinScope(sourceRelativePath, folderScope)\n const targetDepth = depthWithinScope(targetRelativePath, folderScope)\n if (targetDepth <= importerDepth + 1) {\n return undefined\n }\n\n return {\n sourceRelativePath,\n targetRelativePath: stripTsExtension(targetRelativePath),\n }\n}\n\nfunction resolveImportSourceRelative(\n specifier: string,\n filename: string,\n sourceRoot: string,\n): string | undefined {\n const normalizedSpecifier = specifier.replace(/\\.js$/, '')\n\n if (normalizedSpecifier.startsWith('@/')) {\n return normalizedSpecifier.slice(2)\n }\n\n if (!normalizedSpecifier.startsWith('.')) {\n return undefined\n }\n\n const absoluteTarget = path.resolve(path.dirname(filename), normalizedSpecifier)\n const targetSourceRelative = path.relative(sourceRoot, absoluteTarget)\n if (targetSourceRelative.startsWith('..')) {\n return undefined\n }\n\n return toPosix(targetSourceRelative)\n}\n\nfunction resolveTarget(targetSourceRelative: string, sourceRoot: string): string | undefined {\n const cacheKey = `${sourceRoot}\\0${targetSourceRelative}`\n if (resolveCache.has(cacheKey)) {\n return resolveCache.get(cacheKey)\n }\n\n const candidates = [\n targetSourceRelative + '.ts',\n targetSourceRelative + '.tsx',\n targetSourceRelative + '/index.ts',\n targetSourceRelative + '/index.tsx',\n ]\n const candidate = candidates.find((entry) => existsSync(path.join(sourceRoot, entry)))\n const targetRelativePath = candidate ? toPosix(candidate) : undefined\n\n resolveCache.set(cacheKey, targetRelativePath)\n return targetRelativePath\n}\n\nfunction folderScopeFromPath(sourceRelativePath: string): string {\n const [firstPart = ''] = sourceRelativePath.split('/')\n return stripTsExtension(firstPart)\n}\n\nfunction isInScope(targetRelativePath: string, scope: string): boolean {\n const targetNoExtension = stripTsExtension(targetRelativePath)\n return targetNoExtension === scope || targetNoExtension.startsWith(`${scope}/`)\n}\n\nfunction depthWithinScope(relativePath: string, scope: string): number {\n const withoutExtension = stripTsExtension(relativePath)\n if (withoutExtension === scope) {\n return 0\n }\n\n // Precondition: isInScope() already confirmed target is within scope,\n // so withoutExtension always starts with scope + '/'\n const suffix = withoutExtension.slice(scope.length + 1)\n return suffix.split('/').length - 1\n}\n\nconst resolveCache = new Map<string, string | undefined>()\n\nfunction stripTsExtension(filePath: string): string {\n return filePath.replace(/\\.tsx?$/, '')\n}\n","import path from 'node:path'\n\nexport function toPosix(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nexport function isInsidePath(filePath: string, parentPath: string): boolean {\n const relativePath = path.relative(parentPath, filePath)\n return relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath))\n}\n","export function readSourceRootOption(options: unknown[]): string | undefined {\n const option = options[0]\n if (!isRecord(option) || !('sourceRoot' in option)) {\n return undefined\n }\n\n return typeof option.sourceRoot === 'string' ? option.sourceRoot : undefined\n}\n\nexport type SharingMode = 'file' | 'dir'\n\nexport interface DirEntry {\n path: string\n mode: SharingMode\n}\n\nexport function readDirsOption(options: unknown[], rootMode: SharingMode = 'file'): DirEntry[] {\n const option = options[0]\n if (!isRecord(option) || !('dirs' in option)) {\n return []\n }\n\n const rootModeResolved = readRootMode(option, rootMode)\n\n const { dirs } = option\n if (!Array.isArray(dirs)) {\n return []\n }\n\n return dirs.flatMap((entry) => {\n const parsed = parseDirEntry(entry, rootModeResolved)\n return parsed ? [parsed] : []\n })\n}\n\nfunction readRootMode(option: object, fallback: SharingMode): SharingMode {\n if (!('mode' in option)) {\n return fallback\n }\n\n return option.mode === 'dir' ? 'dir' : 'file'\n}\n\nfunction parseDirEntry(entry: unknown, defaultMode: SharingMode): DirEntry | undefined {\n if (!isRecord(entry) || !('path' in entry)) {\n return undefined\n }\n\n if (typeof entry.path !== 'string') {\n return undefined\n }\n\n const modeValue = 'mode' in entry ? entry.mode : undefined\n const mode: SharingMode = modeValue === 'dir' ? 'dir' : defaultMode\n\n return { path: entry.path, mode }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { isInsidePath, toPosix } from './path-helpers.js'\n\nexport function resolveSourceContext(\n filename: string,\n sourceRootOverride?: string,\n): SourceContext | undefined {\n if (filename === '<input>') {\n return undefined\n }\n\n const absoluteFilename = path.isAbsolute(filename) ? filename : path.resolve(filename)\n\n if (sourceRootOverride) {\n const projectRoot = findNearestPackageRoot(path.dirname(absoluteFilename)) ?? process.cwd()\n return buildContext(\n absoluteFilename,\n projectRoot,\n path.isAbsolute(sourceRootOverride)\n ? sourceRootOverride\n : path.join(projectRoot, sourceRootOverride),\n )\n }\n\n const packageRoot = findNearestPackageRoot(path.dirname(absoluteFilename))\n if (packageRoot) {\n return buildContext(\n absoluteFilename,\n packageRoot,\n existsSync(path.join(packageRoot, 'src')) ? path.join(packageRoot, 'src') : packageRoot,\n )\n }\n\n return resolveLegacySourceRoot(absoluteFilename)\n}\n\nfunction findNearestPackageRoot(startDirectory: string): string | undefined {\n let directory = startDirectory\n\n while (true) {\n if (existsSync(path.join(directory, 'package.json'))) {\n return directory\n }\n\n const parent = path.dirname(directory)\n if (parent === directory) {\n return undefined\n }\n\n directory = parent\n }\n}\n\nfunction resolveLegacySourceRoot(filename: string): SourceContext | undefined {\n const normalized = toPosix(filename)\n const sourceIndex = normalized.lastIndexOf('/src/')\n if (sourceIndex === -1) {\n return undefined\n }\n\n const projectRoot = normalized.slice(0, sourceIndex)\n const sourceRoot = path.join(projectRoot, 'src')\n return buildContext(filename, projectRoot, sourceRoot)\n}\n\nfunction buildContext(\n filename: string,\n projectRoot: string,\n sourceRoot: string,\n): SourceContext | undefined {\n if (!isInsidePath(filename, sourceRoot)) {\n return undefined\n }\n\n return {\n projectRoot,\n sourceRoot,\n sourceRelativePath: toPosix(path.relative(sourceRoot, filename)),\n }\n}\n\ninterface SourceContext {\n projectRoot: string\n sourceRoot: string\n sourceRelativePath: string\n}\n","import { existsSync, readdirSync } from 'node:fs'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport { isInsidePath, toPosix } from '../../utils/path-helpers.js'\nimport type { DirEntry, SharingMode } from '../../utils/rule-options.js'\n\nexport function runConsumerCheck(\n program: ts.Program,\n projectRoot: string,\n sourceRoot: string,\n directories: DirEntry[],\n): Map<string, string[]> {\n const checker = program.getTypeChecker()\n const sourceFiles = program.getSourceFiles().filter((sf) => isInsidePath(sf.fileName, sourceRoot))\n\n const modules = indexModules(directories, projectRoot, sourceRoot)\n const barrels = indexBarrels(directories, projectRoot, sourceFiles, checker)\n const ctx: AnalysisContext = { modules, barrels, checker }\n countConsumers(sourceFiles, sourceRoot, ctx)\n return collectErrors(modules)\n}\n\nfunction indexModules(\n directories: DirEntry[],\n projectRoot: string,\n sourceRoot: string,\n): Map<string, ModuleEntry> {\n const modules = new Map<string, ModuleEntry>()\n\n for (const dir of directories) {\n const absDir = path.join(projectRoot, dir.path)\n for (const file of listModuleFiles(absDir)) {\n modules.set(file, {\n relativePath: toPosix(path.relative(sourceRoot, file)),\n mode: dir.mode,\n consumers: new Set(),\n })\n }\n }\n\n return modules\n}\n\nfunction listModuleFiles(directory: string): string[] {\n if (!existsSync(directory)) {\n return []\n }\n\n return readdirSync(directory, { withFileTypes: true })\n .filter(\n (e) =>\n e.isFile() &&\n (e.name.endsWith('.ts') || e.name.endsWith('.tsx')) &&\n e.name !== 'index.ts' &&\n !isTestFile(e.name),\n )\n .map((e) => path.join(directory, e.name))\n}\n\nfunction indexBarrels(\n directories: DirEntry[],\n projectRoot: string,\n sourceFiles: ts.SourceFile[],\n checker: ts.TypeChecker,\n): Map<string, Map<string, string>> {\n const barrels = new Map<string, Map<string, string>>()\n const sfByPath = new Map(sourceFiles.map((sf) => [sf.fileName, sf]))\n\n for (const dir of directories) {\n const barrelPath = path.join(projectRoot, dir.path, 'index.ts')\n const barrelSf = sfByPath.get(barrelPath)\n if (barrelSf) {\n barrels.set(barrelPath, buildBarrelMap(barrelSf, checker))\n }\n }\n\n return barrels\n}\n\nfunction buildBarrelMap(barrelFile: ts.SourceFile, checker: ts.TypeChecker): Map<string, string> {\n const map = new Map<string, string>()\n\n for (const stmt of barrelFile.statements) {\n if (!isNamedReExport(stmt)) continue\n\n const targetPath = resolveModulePath(stmt.moduleSpecifier, checker)\n if (!targetPath) continue\n\n for (const el of stmt.exportClause.elements) {\n if (!el.isTypeOnly) {\n map.set(el.name.text, targetPath)\n }\n }\n }\n\n return map\n}\n\nfunction isNamedReExport(stmt: ts.Statement): stmt is ts.ExportDeclaration & {\n exportClause: ts.NamedExports\n moduleSpecifier: ts.Expression\n} {\n return (\n ts.isExportDeclaration(stmt) &&\n !stmt.isTypeOnly &&\n !!stmt.moduleSpecifier &&\n !!stmt.exportClause &&\n ts.isNamedExports(stmt.exportClause)\n )\n}\n\nfunction countConsumers(\n sourceFiles: ts.SourceFile[],\n sourceRoot: string,\n ctx: AnalysisContext,\n): void {\n for (const sf of sourceFiles) {\n if (ctx.modules.has(sf.fileName) || isTestFile(sf.fileName)) continue\n\n const consumerPath = toPosix(path.relative(sourceRoot, sf.fileName))\n\n for (const stmt of sf.statements) {\n if (ts.isImportDeclaration(stmt)) {\n recordImport(stmt, consumerPath, ctx)\n }\n }\n }\n}\n\nfunction isTestFile(filePath: string): boolean {\n return TEST_FILE_RE.test(filePath)\n}\n\nconst TEST_FILE_RE = /\\.(test|integration-test|test-suite)\\.ts$/\n\nfunction recordImport(\n stmt: ts.ImportDeclaration,\n consumerPath: string,\n ctx: AnalysisContext,\n): void {\n const targetPath = resolveModulePath(stmt.moduleSpecifier, ctx.checker)\n if (!targetPath) return\n\n const direct = ctx.modules.get(targetPath)\n if (direct) {\n direct.consumers.add(deriveEntity(consumerPath, direct.mode))\n return\n }\n\n const barrelMap = ctx.barrels.get(targetPath)\n if (barrelMap) {\n resolveBarrelImports(stmt, barrelMap, consumerPath, ctx.modules)\n }\n}\n\nfunction resolveBarrelImports(\n stmt: ts.ImportDeclaration,\n barrelMap: Map<string, string>,\n consumerPath: string,\n modules: Map<string, ModuleEntry>,\n): void {\n const bindings = stmt.importClause?.namedBindings\n if (!bindings) return\n\n const paths = ts.isNamespaceImport(bindings)\n ? [...barrelMap.values()]\n : resolveNamedImports(bindings, barrelMap)\n\n for (const resolved of paths) {\n const entry = modules.get(resolved)\n entry?.consumers.add(deriveEntity(consumerPath, entry.mode))\n }\n}\n\nfunction resolveNamedImports(bindings: ts.NamedImports, barrelMap: Map<string, string>): string[] {\n const result: string[] = []\n for (const el of bindings.elements) {\n const name = el.propertyName?.text ?? el.name.text\n const resolved = barrelMap.get(name)\n if (resolved) {\n result.push(resolved)\n }\n }\n return result\n}\n\nfunction resolveModulePath(specifier: ts.Expression, checker: ts.TypeChecker): string | undefined {\n const symbol = checker.getSymbolAtLocation(specifier)\n return symbol?.declarations?.[0]?.getSourceFile().fileName\n}\n\nfunction collectErrors(modules: Map<string, ModuleEntry>): Map<string, string[]> {\n const errors = new Map<string, string[]>()\n\n for (const [, entry] of modules) {\n if (entry.consumers.size >= 2) continue\n\n const consumers = [...entry.consumers]\n const description =\n consumers.length === 0\n ? 'not imported by any entity'\n : `only used by: ${consumers.join(', ')}`\n\n errors.set(entry.relativePath, [`${description} -> Must be used by 2+ entities`])\n }\n\n return errors\n}\n\nfunction deriveEntity(consumerPath: string, mode: SharingMode): string {\n if (mode === 'file') {\n return consumerPath\n }\n return consumerPath.split('/').slice(0, -1).slice(0, MAX_DIR_DEPTH).join('/')\n}\n\nconst MAX_DIR_DEPTH = 3\n\ninterface AnalysisContext {\n modules: Map<string, ModuleEntry>\n barrels: Map<string, Map<string, string>>\n checker: ts.TypeChecker\n}\n\ninterface ModuleEntry {\n relativePath: string\n mode: SharingMode\n consumers: Set<string>\n}\n","import type { Rule } from 'eslint'\nimport type ts from 'typescript'\nimport { resolveSourceContext } from '../utils/source-root.js'\nimport { readDirsOption, readSourceRootOption } from '../utils/rule-options.js'\nimport { runConsumerCheck } from './no-false-sharing/analysis.js'\n\nconst SCHEMA = [\n {\n type: 'object',\n properties: {\n dirs: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n mode: { type: 'string', enum: ['file', 'dir'] },\n },\n required: ['path'],\n additionalProperties: false,\n },\n },\n mode: { type: 'string', enum: ['file', 'dir'] },\n sourceRoot: { type: 'string' },\n },\n required: ['dirs'],\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Require selected modules to be shared across at least two consumer entities',\n recommended: false,\n },\n schema: SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const dirs = readDirsOption(context.options)\n if (dirs.length === 0) {\n return {}\n }\n\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot, projectRoot } = sourceContext\n\n return {\n Program(node) {\n const program = extractTsProgram(context)\n if (!program) {\n return\n }\n\n const errors = runConsumerCheck(program, projectRoot, sourceRoot, dirs)\n const fileErrors = errors.get(sourceRelativePath)\n if (!fileErrors) {\n return\n }\n\n for (const message of fileErrors) {\n context.report({ node, message })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction extractTsProgram(context: Rule.RuleContext): ts.Program | undefined {\n const services = context.sourceCode.parserServices\n if (!isRecord(services) || !('program' in services)) {\n return undefined\n }\n const program = services.program\n if (!isTsProgram(program)) {\n return undefined\n }\n return program\n}\n\nfunction isTsProgram(value: unknown): value is ts.Program {\n return isRecord(value) && 'getTypeChecker' in value\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import type { ClassBody, Identifier, Node, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportClassOrdering(program: Program, context: Rule.RuleContext): void {\n for (const classNode of collectClassDeclarations(program)) {\n const members = collectClassMembers(classNode)\n reportConstructorOrder(members, classNode, context)\n reportPublicFieldOrder(members, context)\n reportClassDependencyOrder(members, context)\n }\n}\n\nfunction collectClassDeclarations(program: Program): ClassNode[] {\n const classes: ClassNode[] = []\n\n for (const statement of getTopLevelStatements(program)) {\n const classNode = extractClassNode(statement)\n if (classNode) classes.push(classNode)\n }\n\n return classes\n}\n\nfunction extractClassNode(statement: TopLevelNode): ClassNode | undefined {\n if (statement.type === 'ClassDeclaration') return statement\n\n if (\n statement.type === 'ExportNamedDeclaration' &&\n statement.declaration?.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n if (\n statement.type === 'ExportDefaultDeclaration' &&\n statement.declaration.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n return undefined\n}\n\nfunction reportConstructorOrder(\n members: ClassMemberEntry[],\n classNode: ClassNode,\n context: Rule.RuleContext,\n): void {\n const ctor = members.find((m) => m.kind === 'constructor')\n if (!ctor || ctor.index === 0) return\n\n context.report({\n node: ctor.node,\n messageId: 'constructorFirst',\n data: { className: classNode.id?.name ?? 'anonymous class' },\n })\n}\n\nfunction reportPublicFieldOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const ctorIndex = members.find((m) => m.kind === 'constructor')?.index ?? -1\n const startIndex = ctorIndex >= 0 ? ctorIndex + 1 : 0\n let seenOther = false\n\n for (const member of members) {\n if (member.index < startIndex) continue\n\n if (member.kind === 'public-field') {\n if (seenOther) {\n context.report({\n node: member.node,\n messageId: 'publicFieldOrder',\n data: { memberName: member.name },\n })\n }\n continue\n }\n\n seenOther = true\n }\n}\n\nfunction reportClassDependencyOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const others = members.filter((m) => m.kind === 'other')\n\n for (const member of others) {\n const consumer = findFirstClassConsumer(others, member, context)\n if (!consumer) continue\n\n context.report({\n node: member.node,\n messageId: 'moveMemberBelow',\n data: { memberName: member.name, consumerName: consumer.name },\n })\n }\n}\n\nfunction collectClassMembers(classNode: ClassNode): ClassMemberEntry[] {\n const members: ClassMemberEntry[] = []\n\n for (const [index, raw] of classNode.body.body.entries()) {\n const named = toNamedMember(raw)\n if (!named) continue\n members.push({ name: named.name, node: named.node, index, kind: classifyMember(named.node) })\n }\n\n return members\n}\n\nfunction toNamedMember(raw: Node): { name: string; node: Node } | undefined {\n if (!hasMemberKey(raw)) return undefined\n const name = readMemberName(raw.key)\n return name ? { name, node: raw } : undefined\n}\n\nfunction hasMemberKey(value: object): value is { key: Node } {\n return 'key' in value && isNode(value.key)\n}\n\nfunction readMemberName(key: Node): string | undefined {\n if (key.type === 'Identifier') return key.name\n if (key.type === 'Literal' && typeof key.value === 'string') return key.value\n if (key.type === 'PrivateIdentifier') return `#${key.name}`\n return undefined\n}\n\nfunction classifyMember(member: Node): ClassMemberEntry['kind'] {\n if (member.type === 'MethodDefinition' && member.kind === 'constructor') return 'constructor'\n if (isPublicField(member)) return 'public-field'\n return 'other'\n}\n\nfunction isPublicField(member: Node): boolean {\n if (member.type !== 'PropertyDefinition' || member.static) return false\n if (member.key.type === 'PrivateIdentifier') return false\n if (!('accessibility' in member)) return true\n return member.accessibility === undefined || member.accessibility === 'public'\n}\n\nfunction findFirstClassConsumer(\n members: ClassMemberEntry[],\n member: ClassMemberEntry,\n context: Rule.RuleContext,\n): ClassMemberEntry | undefined {\n const pattern = new RegExp(`\\\\bthis(?:\\\\?\\\\.|\\\\.)${escapeRegex(member.name)}\\\\b`)\n\n for (const candidate of members) {\n if (candidate.index <= member.index) continue\n if (pattern.test(context.sourceCode.getText(candidate.node))) return candidate\n }\n\n return undefined\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction isNode(value: unknown): value is Node {\n return !!value && typeof value === 'object' && 'type' in value && typeof value.type === 'string'\n}\n\ninterface ClassNode {\n id?: Identifier | null\n body: ClassBody\n}\n\ninterface ClassMemberEntry {\n name: string\n node: Node\n index: number\n kind: 'constructor' | 'public-field' | 'other'\n}\n","import type { CallExpression, ExpressionStatement, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportTestOrdering(program: Program, context: Rule.RuleContext): void {\n const entries = collectTestPhaseEntries(program)\n if (!entries.some((entry) => entry.kind === 'test')) {\n return\n }\n\n reportSetupOrder(entries, context)\n reportTeardownOrder(entries, context)\n}\n\nfunction collectTestPhaseEntries(program: Program): TestPhaseEntry[] {\n const entries: TestPhaseEntry[] = []\n\n for (const [index, statement] of getTopLevelStatements(program).entries()) {\n const entry = toTestPhaseEntry(statement, index)\n if (entry) {\n entries.push(entry)\n }\n }\n\n return entries\n}\n\nfunction toTestPhaseEntry(statement: TopLevelNode, index: number): TestPhaseEntry | undefined {\n if (statement.type !== 'ExpressionStatement' || statement.expression.type !== 'CallExpression') {\n return undefined\n }\n\n const rootName = getCallRootName(statement.expression)\n if (!rootName) {\n return undefined\n }\n\n const kind = classifyHookName(rootName)\n if (!kind) {\n return undefined\n }\n\n return { index, kind, hookName: rootName, node: statement }\n}\n\nfunction classifyHookName(name: string): TestPhaseEntry['kind'] | undefined {\n if (SETUP_HOOKS.has(name)) return 'setup'\n if (TEARDOWN_HOOKS.has(name)) return 'teardown'\n if (TEST_CALLS.has(name)) return 'test'\n return undefined\n}\n\nconst SETUP_HOOKS = new Set(['beforeAll', 'beforeEach', 'before'])\nconst TEARDOWN_HOOKS = new Set(['afterAll', 'afterEach', 'after'])\nconst TEST_CALLS = new Set(['test', 'it'])\n\nfunction getCallRootName(call: CallExpression): string | undefined {\n const callee = call.callee\n if (callee.type === 'Identifier') return callee.name\n if (callee.type === 'MemberExpression') return readObjectRoot(callee.object)\n if (callee.type === 'CallExpression') return getCallRootName(callee)\n return undefined\n}\n\nfunction readObjectRoot(node: CallExpression['callee']): string | undefined {\n if (node.type === 'Identifier') return node.name\n if (node.type === 'MemberExpression') return readObjectRoot(node.object)\n if (node.type === 'CallExpression') return getCallRootName(node)\n return undefined\n}\n\nfunction reportSetupOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTeardown = findFirstIndex(entries, 'teardown')\n const firstTest = findFirstIndex(entries, 'test')\n\n for (const entry of entries) {\n if (entry.kind !== 'setup') continue\n\n if (firstTeardown >= 0 && entry.index > firstTeardown) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTeardown',\n data: { hookName: entry.hookName },\n })\n continue\n }\n\n if (firstTest >= 0 && entry.index > firstTest) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n }\n}\n\nfunction reportTeardownOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTest = findFirstIndex(entries, 'test')\n if (firstTest < 0) return\n\n for (const entry of entries) {\n if (entry.kind !== 'teardown' || entry.index <= firstTest) continue\n\n context.report({\n node: entry.node,\n messageId: 'teardownBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n}\n\nfunction findFirstIndex(entries: TestPhaseEntry[], kind: TestPhaseEntry['kind']): number {\n const match = entries.find((entry) => entry.kind === kind)\n return match ? match.index : -1\n}\n\ninterface TestPhaseEntry {\n index: number\n kind: 'setup' | 'teardown' | 'test'\n hookName: string\n node: ExpressionStatement\n}\n","import type { ExportNamedDeclaration, Node, Program, VariableDeclaration } from 'estree'\nimport type { Rule, Scope } from 'eslint'\nimport { reportClassOrdering } from './read-friendly-order/class-order.js'\nimport { reportTestOrdering } from './read-friendly-order/test-order.js'\n\nconst READ_FRIENDLY_ORDER_MESSAGES = {\n moveHelperBelow:\n 'Place helper \"{{helperName}}\" below the top-level symbol \"{{symbolName}}\" that depends on it.',\n moveConstantBelow:\n 'Place constant \"{{constantName}}\" below the top-level symbol \"{{symbolName}}\" that uses it.',\n constructorFirst: 'Place constructor first in class \"{{className}}\".',\n publicFieldOrder:\n 'Place public field \"{{memberName}}\" right after constructor and before other class members.',\n moveMemberBelow:\n 'Place class member \"{{memberName}}\" below member \"{{consumerName}}\" that depends on it.',\n setupBeforeTeardown: 'Place setup hook \"{{hookName}}\" before teardown hooks in this test file.',\n setupBeforeTests: 'Place setup hook \"{{hookName}}\" before test cases in this test file.',\n teardownBeforeTests: 'Place teardown hook \"{{hookName}}\" before test cases in this test file.',\n}\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Enforce top-level symbols before helper declarations they depend on',\n recommended: false,\n },\n schema: [],\n messages: READ_FRIENDLY_ORDER_MESSAGES,\n },\n create(context: Rule.RuleContext) {\n return {\n Program(program) {\n reportTopLevelOrdering(program, context)\n reportClassOrdering(program, context)\n reportTestOrdering(program, context)\n },\n }\n },\n} satisfies Rule.RuleModule\n\nexport type TopLevelNode = Program['body'][number]\n\nfunction reportTopLevelOrdering(program: Program, context: Rule.RuleContext): void {\n const body = getTopLevelStatements(program)\n const helpers = collectHelpers(body)\n const refs = collectReferences(context.sourceCode.scopeManager.globalScope)\n const cyclicNames = findCyclicHelperNames(body, helpers, refs)\n\n for (const helper of helpers) {\n if (cyclicNames.has(helper.name)) continue\n if (hasEagerReference(body, helper, refs)) continue\n\n const consumer = findFirstConsumer(body, helper, refs)\n if (!consumer) continue\n\n context.report({\n node: helper.node,\n messageId: helper.kind === 'constant' ? 'moveConstantBelow' : 'moveHelperBelow',\n data: {\n helperName: helper.name,\n constantName: helper.name,\n symbolName: getSymbolName(consumer),\n },\n })\n }\n}\n\nexport function getTopLevelStatements(program: Program): TopLevelNode[] {\n return program.body.filter((s) => s.type !== 'ImportDeclaration')\n}\n\nfunction collectHelpers(body: TopLevelNode[]): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n for (const [index, statement] of body.entries()) {\n helpers.push(...collectHelperEntries(statement, index))\n }\n return helpers\n}\n\nfunction collectHelperEntries(statement: TopLevelNode, index: number): HelperDeclaration[] {\n const typeName = getTypeDeclarationName(statement)\n if (typeName) return [{ name: typeName, node: statement, index, kind: 'helper' }]\n\n if (statement.type === 'FunctionDeclaration' && statement.id) {\n return [{ name: statement.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (statement.type === 'ExportNamedDeclaration') {\n return collectExportedHelpers(statement, index)\n }\n\n if (statement.type === 'VariableDeclaration') {\n return collectVariableHelpers(statement, index)\n }\n\n return []\n}\n\nfunction getTypeDeclarationName(statement: TopLevelNode): string | undefined {\n const t: string = statement.type\n if (t !== 'TSTypeAliasDeclaration' && t !== 'TSInterfaceDeclaration') return undefined\n return hasIdentifierId(statement) ? statement.id.name : undefined\n}\n\nfunction hasIdentifierId(value: object): value is { id: { type: string; name: string } } {\n if (!('id' in value)) return false\n const { id } = value\n return !!id && typeof id === 'object' && 'type' in id && 'name' in id && id.type === 'Identifier'\n}\n\nfunction collectExportedHelpers(\n statement: ExportNamedDeclaration,\n index: number,\n): HelperDeclaration[] {\n const decl = statement.declaration\n if (!decl) return []\n\n if (decl.type === 'FunctionDeclaration' && decl.id) {\n return [{ name: decl.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (decl.type === 'VariableDeclaration') return collectVariableHelpers(decl, index)\n return []\n}\n\nfunction collectVariableHelpers(decl: VariableDeclaration, index: number): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n\n for (const item of decl.declarations) {\n if (item.id.type !== 'Identifier') continue\n const isFn = isFunctionInit(item.init ?? null)\n\n if (!isFn && decl.kind !== 'const') continue\n\n helpers.push({\n name: item.id.name,\n node: item,\n index,\n kind: isFn ? 'helper' : 'constant',\n })\n }\n\n return helpers\n}\n\nfunction isFunctionInit(node: Node | null): boolean {\n return node?.type === 'ArrowFunctionExpression' || node?.type === 'FunctionExpression'\n}\n\nfunction findFirstConsumer(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): TopLevelNode | undefined {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementUsesName(stmt, helper.name, refs)) return stmt\n }\n return undefined\n}\n\nfunction findCyclicHelperNames(\n body: TopLevelNode[],\n helpers: HelperDeclaration[],\n refs: Scope.Reference[],\n): Set<string> {\n const deps = new Map<string, Set<string>>()\n\n for (const helper of helpers) {\n const helperDeps = new Set<string>()\n for (const other of helpers) {\n if (other.name !== helper.name && statementUsesName(body[helper.index], other.name, refs)) {\n helperDeps.add(other.name)\n }\n }\n deps.set(helper.name, helperDeps)\n }\n\n const cyclic = new Set<string>()\n for (const helper of helpers) {\n if (canReachSelf(helper.name, deps)) cyclic.add(helper.name)\n }\n return cyclic\n}\n\nfunction statementUsesName(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name) continue\n const idRange = ref.identifier.range\n if (!idRange) continue\n if (idRange[0] >= range[0] && idRange[1] <= range[1]) return true\n }\n\n return false\n}\n\nfunction canReachSelf(start: string, deps: Map<string, Set<string>>): boolean {\n const visited = new Set<string>()\n const queue = [...(deps.get(start) ?? [])]\n\n while (queue.length > 0) {\n const current = queue.shift()!\n if (current === start) return true\n if (visited.has(current)) continue\n visited.add(current)\n for (const dep of deps.get(current) ?? []) queue.push(dep)\n }\n\n return false\n}\n\nfunction collectReferences(scope: Scope.Scope | null): Scope.Reference[] {\n if (!scope) return []\n const refs = [...scope.references]\n for (const child of scope.childScopes) {\n refs.push(...collectReferences(child))\n }\n return refs\n}\n\nfunction hasEagerReference(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): boolean {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementHasEagerUse(stmt, helper.name, refs)) return true\n }\n return false\n}\n\nfunction statementHasEagerUse(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name || isTypeReference(ref)) continue\n if (isEagerRefInRange(ref, range)) return true\n }\n\n return false\n}\n\nfunction isEagerRefInRange(ref: Scope.Reference, range: [number, number]): boolean {\n const idRange = ref.identifier.range\n if (!idRange) return false\n const inside = idRange[0] >= range[0] && idRange[1] <= range[1]\n return inside && (ref.from.type === 'module' || ref.from.type === 'global')\n}\n\nfunction isTypeReference(ref: Scope.Reference): boolean {\n return 'isTypeReference' in ref && ref.isTypeReference === true\n}\n\nfunction getSymbolName(statement: TopLevelNode): string {\n if (statement.type === 'ExportDefaultDeclaration') return 'default export'\n if (statement.type === 'ExportNamedDeclaration') return getNamedExportName(statement)\n if (statement.type === 'FunctionDeclaration' && statement.id) return statement.id.name\n if (statement.type === 'VariableDeclaration')\n return getVarName(statement) ?? 'top-level statement'\n return 'top-level statement'\n}\n\nfunction getNamedExportName(statement: ExportNamedDeclaration): string {\n const decl = statement.declaration\n if (!decl) return 'named export'\n if (decl.type === 'FunctionDeclaration' && decl.id) return decl.id.name\n if (decl.type === 'VariableDeclaration') return getVarName(decl) ?? 'named export'\n return 'named export'\n}\n\nfunction getVarName(decl: VariableDeclaration): string | undefined {\n const [first] = decl.declarations\n return first?.id.type === 'Identifier' ? first.id.name : undefined\n}\n\ninterface HelperDeclaration {\n name: string\n node: Node\n index: number\n kind: 'helper' | 'constant'\n}\n","import type { Rule } from 'eslint'\nimport noSpecialUnicode from './no-special-unicode.js'\nimport noUnicodeEscape from './no-unicode-escape.js'\nimport noDeepImports from './no-deep-imports.js'\nimport noFalseSharing from './no-false-sharing.js'\nimport readFriendlyOrder from './read-friendly-order.js'\n\nexport default {\n 'no-special-unicode': noSpecialUnicode,\n 'no-unicode-escape': noUnicodeEscape,\n 'no-deep-imports': noDeepImports,\n 'no-false-sharing': noFalseSharing,\n 'read-friendly-order': readFriendlyOrder,\n} satisfies Record<string, Rule.RuleModule>\n","import type { ESLint, Linter } from 'eslint'\nimport packageJson from '../package.json'\nimport rules from './rules/index.js'\n\n// configs.recommended.plugins.unslop must reference the plugin itself.\n// Build plugin first with an empty configs object, then assign below.\nconst plugin: ESLint.Plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n rules,\n configs: {},\n}\n\nconst recommended: Linter.Config = {\n name: 'unslop/recommended',\n plugins: { unslop: plugin },\n rules: {\n 'unslop/no-special-unicode': 'error',\n 'unslop/no-unicode-escape': 'error',\n 'unslop/no-deep-imports': 'error',\n },\n}\n\nplugin.configs!['recommended'] = recommended\n\nexport default plugin\n"],"mappings":"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","names":["existsSync","path","path","path","path","existsSync","existsSync","path","path","existsSync","isRecord"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/utils/string-literal-listener.ts","../src/rules/no-special-unicode.ts","../src/rules/no-unicode-escape.ts","../src/rules/no-deep-imports.ts","../src/utils/path-helpers.ts","../src/utils/rule-options.ts","../src/utils/source-root.ts","../src/rules/no-false-sharing/analysis.ts","../src/rules/no-false-sharing.ts","../src/rules/read-friendly-order/class-order.ts","../src/rules/read-friendly-order/test-order.ts","../src/rules/read-friendly-order.ts","../src/rules/index.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"eslint-plugin-unslop\",\n \"version\": \"0.1.3\",\n \"description\": \"ESLint plugin with rules for reducing AI-generated code smells\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/skhoroshavin/eslint-plugin-unslop\"\n },\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"format\": \"prettier . --write\",\n \"verify\": \"prettier . --check && tsc --noEmit && tsup && eslint . && knip\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"eslint\",\n \"eslintplugin\",\n \"eslint-plugin\",\n \"ai\",\n \"code-quality\",\n \"unslop\"\n ],\n \"license\": \"MIT\",\n \"peerDependencies\": {\n \"eslint\": \">=9.0.0\",\n \"typescript\": \">=5.0.0\"\n },\n \"peerDependenciesMeta\": {\n \"typescript\": {\n \"optional\": true\n }\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.39.4\",\n \"@types/estree\": \"^1.0.8\",\n \"@types/node\": \"^22.18.0\",\n \"@typescript-eslint/parser\": \"^8.57.2\",\n \"eslint\": \"^9.39.1\",\n \"globals\": \"^17.4.0\",\n \"knip\": \"^6.1.0\",\n \"prettier\": \"^3.8.1\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.57.2\",\n \"vitest\": \"^3.2.4\"\n }\n}\n","import type { Rule } from 'eslint'\nimport type { Literal, TemplateLiteral } from 'estree'\n\nexport function createStringLiteralListener(\n includeEscapedUnicode: boolean,\n visitLiteral: StringLiteralVisitor,\n): Rule.RuleListener {\n function inspect(node: Literal | TemplateLiteral): void {\n const text = getStringValue(node, includeEscapedUnicode)\n if (text == undefined) {\n return\n }\n\n visitLiteral(node, text)\n }\n\n return {\n Literal: inspect,\n TemplateLiteral: inspect,\n }\n}\n\ntype StringLiteralVisitor = (node: Literal | TemplateLiteral, text: string) => void\n\nfunction getStringValue(\n node: Literal | TemplateLiteral,\n includeEscapedUnicode: boolean,\n): string | undefined {\n if (node.type === 'TemplateLiteral') {\n return node.quasis\n .map((q) =>\n includeEscapedUnicode ? (q.value.raw ?? q.value.cooked ?? '') : (q.value.cooked ?? ''),\n )\n .join('')\n }\n\n if (typeof node.value !== 'string') {\n return undefined\n }\n\n return includeEscapedUnicode ? (node.raw ?? node.value) : node.value\n}\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallow special unicode punctuation and whitespace in strings',\n recommended: true,\n },\n schema: [],\n messages: {\n bannedCharacter: 'String contains {{name}} (U+{{code}}). Use the ASCII equivalent.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(false, (node, text) => {\n if (!BANNED_CHARS_RE.test(text)) {\n return\n }\n\n for (const [char, name] of BANNED_CHARS) {\n if (!text.includes(char)) {\n continue\n }\n\n const code = char.codePointAt(0) ?? 0\n\n context.report({\n node,\n messageId: 'bannedCharacter',\n data: {\n name,\n code: code.toString(16).toUpperCase().padStart(4, '0'),\n },\n })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst BANNED_CHARS = new Map([\n ['\\u201C', 'left double quotation mark'],\n ['\\u201D', 'right double quotation mark'],\n ['\\u2018', 'left single quotation mark'],\n ['\\u2019', 'right single quotation mark'],\n ['\\u00A0', 'non-breaking space'],\n ['\\u202F', 'narrow no-break space'],\n ['\\u2007', 'figure space'],\n ['\\u2008', 'punctuation space'],\n ['\\u2009', 'thin space'],\n ['\\u200A', 'hair space'],\n ['\\u200B', 'zero-width space'],\n ['\\u2002', 'en space'],\n ['\\u2003', 'em space'],\n ['\\u205F', 'medium mathematical space'],\n ['\\u3000', 'ideographic space'],\n ['\\uFEFF', 'zero-width no-break space'],\n ['\\u2013', 'en dash'],\n ['\\u2014', 'em dash'],\n ['\\u2026', 'horizontal ellipsis'],\n])\n\nconst BANNED_CHARS_RE = new RegExp([...BANNED_CHARS.keys()].join('|'))\n","import type { Rule } from 'eslint'\nimport { createStringLiteralListener } from '../utils/string-literal-listener.js'\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Prefer literal unicode characters over \\\\uXXXX escape sequences',\n recommended: true,\n },\n schema: [],\n messages: {\n preferLiteral: 'Use the actual character instead of a \\\\uXXXX escape sequence.',\n },\n },\n create(context: Rule.RuleContext) {\n return createStringLiteralListener(true, (node, text) => {\n if (UNICODE_ESCAPE_RE.test(text)) {\n context.report({ node, messageId: 'preferLiteral' })\n }\n })\n },\n} satisfies Rule.RuleModule\n\nconst UNICODE_ESCAPE_RE = /\\\\u[0-9a-fA-F]{4}/\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport type { Rule } from 'eslint'\nimport { toPosix } from '../utils/path-helpers.js'\nimport { readSourceRootOption } from '../utils/rule-options.js'\nimport { resolveSourceContext } from '../utils/source-root.js'\n\nconst NO_DEEP_IMPORTS_SCHEMA = [\n {\n type: 'object',\n properties: {\n sourceRoot: { type: 'string' },\n },\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Forbid deep imports inside the same top-level folder',\n recommended: true,\n },\n messages: {\n tooDeep:\n '{{sourceRelativePath}}: {{targetRelativePath}} is too deep (max 1 level below importer).',\n },\n schema: NO_DEEP_IMPORTS_SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot } = sourceContext\n\n return {\n ImportDeclaration(node) {\n const specifier = typeof node.source.value === 'string' ? node.source.value : ''\n\n const violation = findViolation(specifier, filename, sourceRoot, sourceRelativePath)\n\n if (violation) {\n context.report({\n node,\n messageId: 'tooDeep',\n data: violation,\n })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction findViolation(\n specifier: string,\n filename: string,\n sourceRoot: string,\n sourceRelativePath: string,\n): { sourceRelativePath: string; targetRelativePath: string } | undefined {\n const targetSourceRelative = resolveImportSourceRelative(specifier, filename, sourceRoot)\n if (!targetSourceRelative) {\n return undefined\n }\n\n const targetRelativePath = resolveTarget(targetSourceRelative, sourceRoot)\n if (!targetRelativePath) {\n return undefined\n }\n\n const folderScope = folderScopeFromPath(sourceRelativePath)\n if (!isInScope(targetRelativePath, folderScope)) {\n return undefined\n }\n\n const importerDepth = depthWithinScope(sourceRelativePath, folderScope)\n const targetDepth = depthWithinScope(targetRelativePath, folderScope)\n if (targetDepth <= importerDepth + 1) {\n return undefined\n }\n\n return {\n sourceRelativePath,\n targetRelativePath: stripTsExtension(targetRelativePath),\n }\n}\n\nfunction resolveImportSourceRelative(\n specifier: string,\n filename: string,\n sourceRoot: string,\n): string | undefined {\n const normalizedSpecifier = specifier.replace(/\\.js$/, '')\n\n if (normalizedSpecifier.startsWith('@/')) {\n return normalizedSpecifier.slice(2)\n }\n\n if (!normalizedSpecifier.startsWith('.')) {\n return undefined\n }\n\n const absoluteTarget = path.resolve(path.dirname(filename), normalizedSpecifier)\n const targetSourceRelative = path.relative(sourceRoot, absoluteTarget)\n if (targetSourceRelative.startsWith('..')) {\n return undefined\n }\n\n return toPosix(targetSourceRelative)\n}\n\nfunction resolveTarget(targetSourceRelative: string, sourceRoot: string): string | undefined {\n const cacheKey = `${sourceRoot}\\0${targetSourceRelative}`\n if (resolveCache.has(cacheKey)) {\n return resolveCache.get(cacheKey)\n }\n\n const candidates = [\n targetSourceRelative + '.ts',\n targetSourceRelative + '.tsx',\n targetSourceRelative + '/index.ts',\n targetSourceRelative + '/index.tsx',\n ]\n const candidate = candidates.find((entry) => existsSync(path.join(sourceRoot, entry)))\n const targetRelativePath = candidate ? toPosix(candidate) : undefined\n\n resolveCache.set(cacheKey, targetRelativePath)\n return targetRelativePath\n}\n\nfunction folderScopeFromPath(sourceRelativePath: string): string {\n const [firstPart = ''] = sourceRelativePath.split('/')\n return stripTsExtension(firstPart)\n}\n\nfunction isInScope(targetRelativePath: string, scope: string): boolean {\n const targetNoExtension = stripTsExtension(targetRelativePath)\n return targetNoExtension === scope || targetNoExtension.startsWith(`${scope}/`)\n}\n\nfunction depthWithinScope(relativePath: string, scope: string): number {\n const withoutExtension = stripTsExtension(relativePath)\n if (withoutExtension === scope) {\n return 0\n }\n\n // Precondition: isInScope() already confirmed target is within scope,\n // so withoutExtension always starts with scope + '/'\n const suffix = withoutExtension.slice(scope.length + 1)\n return suffix.split('/').length - 1\n}\n\nconst resolveCache = new Map<string, string | undefined>()\n\nfunction stripTsExtension(filePath: string): string {\n return filePath.replace(/\\.tsx?$/, '')\n}\n","import path from 'node:path'\n\nexport function toPosix(filePath: string): string {\n return filePath.split(path.sep).join('/')\n}\n\nexport function isInsidePath(filePath: string, parentPath: string): boolean {\n const relativePath = path.relative(parentPath, filePath)\n return relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath))\n}\n","export function readSourceRootOption(options: unknown[]): string | undefined {\n const option = options[0]\n if (!isRecord(option) || !('sourceRoot' in option)) {\n return undefined\n }\n\n return typeof option.sourceRoot === 'string' ? option.sourceRoot : undefined\n}\n\nexport type SharingMode = 'file' | 'dir'\n\nexport interface DirEntry {\n path: string\n mode: SharingMode\n}\n\nexport function readDirsOption(options: unknown[], rootMode: SharingMode = 'file'): DirEntry[] {\n const option = options[0]\n if (!isRecord(option) || !('dirs' in option)) {\n return []\n }\n\n const rootModeResolved = readRootMode(option, rootMode)\n\n const { dirs } = option\n if (!Array.isArray(dirs)) {\n return []\n }\n\n return dirs.flatMap((entry) => {\n const parsed = parseDirEntry(entry, rootModeResolved)\n return parsed ? [parsed] : []\n })\n}\n\nfunction readRootMode(option: object, fallback: SharingMode): SharingMode {\n if (!('mode' in option)) {\n return fallback\n }\n\n return option.mode === 'dir' ? 'dir' : 'file'\n}\n\nfunction parseDirEntry(entry: unknown, defaultMode: SharingMode): DirEntry | undefined {\n if (!isRecord(entry) || !('path' in entry)) {\n return undefined\n }\n\n if (typeof entry.path !== 'string') {\n return undefined\n }\n\n const modeValue = 'mode' in entry ? entry.mode : undefined\n const mode: SharingMode = modeValue === 'dir' ? 'dir' : defaultMode\n\n return { path: entry.path, mode }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import { existsSync } from 'node:fs'\nimport path from 'node:path'\nimport { isInsidePath, toPosix } from './path-helpers.js'\n\nexport function resolveSourceContext(\n filename: string,\n sourceRootOverride?: string,\n): SourceContext | undefined {\n if (filename === '<input>') {\n return undefined\n }\n\n const absoluteFilename = path.isAbsolute(filename) ? filename : path.resolve(filename)\n\n if (sourceRootOverride) {\n const projectRoot = findNearestPackageRoot(path.dirname(absoluteFilename)) ?? process.cwd()\n return buildContext(\n absoluteFilename,\n projectRoot,\n path.isAbsolute(sourceRootOverride)\n ? sourceRootOverride\n : path.join(projectRoot, sourceRootOverride),\n )\n }\n\n const packageRoot = findNearestPackageRoot(path.dirname(absoluteFilename))\n if (packageRoot) {\n return buildContext(\n absoluteFilename,\n packageRoot,\n existsSync(path.join(packageRoot, 'src')) ? path.join(packageRoot, 'src') : packageRoot,\n )\n }\n\n return resolveLegacySourceRoot(absoluteFilename)\n}\n\nfunction findNearestPackageRoot(startDirectory: string): string | undefined {\n let directory = startDirectory\n\n while (true) {\n if (existsSync(path.join(directory, 'package.json'))) {\n return directory\n }\n\n const parent = path.dirname(directory)\n if (parent === directory) {\n return undefined\n }\n\n directory = parent\n }\n}\n\nfunction resolveLegacySourceRoot(filename: string): SourceContext | undefined {\n const normalized = toPosix(filename)\n const sourceIndex = normalized.lastIndexOf('/src/')\n if (sourceIndex === -1) {\n return undefined\n }\n\n const projectRoot = normalized.slice(0, sourceIndex)\n const sourceRoot = path.join(projectRoot, 'src')\n return buildContext(filename, projectRoot, sourceRoot)\n}\n\nfunction buildContext(\n filename: string,\n projectRoot: string,\n sourceRoot: string,\n): SourceContext | undefined {\n if (!isInsidePath(filename, sourceRoot)) {\n return undefined\n }\n\n return {\n projectRoot,\n sourceRoot,\n sourceRelativePath: toPosix(path.relative(sourceRoot, filename)),\n }\n}\n\ninterface SourceContext {\n projectRoot: string\n sourceRoot: string\n sourceRelativePath: string\n}\n","import { existsSync, readdirSync } from 'node:fs'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport { isInsidePath, toPosix } from '../../utils/path-helpers.js'\nimport type { DirEntry, SharingMode } from '../../utils/rule-options.js'\n\nexport function runConsumerCheck(\n program: ts.Program,\n projectRoot: string,\n sourceRoot: string,\n directories: DirEntry[],\n): Map<string, string[]> {\n const checker = program.getTypeChecker()\n const sourceFiles = program.getSourceFiles().filter((sf) => isInsidePath(sf.fileName, sourceRoot))\n\n const modules = indexModules(directories, projectRoot, sourceRoot)\n const barrels = indexBarrels(directories, projectRoot, sourceFiles, checker)\n const ctx: AnalysisContext = { modules, barrels, checker }\n countConsumers(sourceFiles, sourceRoot, ctx)\n return collectErrors(modules)\n}\n\nfunction indexModules(\n directories: DirEntry[],\n projectRoot: string,\n sourceRoot: string,\n): Map<string, ModuleEntry> {\n const modules = new Map<string, ModuleEntry>()\n\n for (const dir of directories) {\n const absDir = path.join(projectRoot, dir.path)\n for (const file of listModuleFiles(absDir)) {\n modules.set(file, {\n relativePath: toPosix(path.relative(sourceRoot, file)),\n mode: dir.mode,\n consumers: new Set(),\n })\n }\n }\n\n return modules\n}\n\nfunction listModuleFiles(directory: string): string[] {\n if (!existsSync(directory)) {\n return []\n }\n\n return readdirSync(directory, { withFileTypes: true })\n .filter(\n (e) =>\n e.isFile() &&\n (e.name.endsWith('.ts') || e.name.endsWith('.tsx')) &&\n e.name !== 'index.ts' &&\n !isTestFile(e.name),\n )\n .map((e) => path.join(directory, e.name))\n}\n\nfunction indexBarrels(\n directories: DirEntry[],\n projectRoot: string,\n sourceFiles: ts.SourceFile[],\n checker: ts.TypeChecker,\n): Map<string, Map<string, string>> {\n const barrels = new Map<string, Map<string, string>>()\n const sfByPath = new Map(sourceFiles.map((sf) => [sf.fileName, sf]))\n\n for (const dir of directories) {\n const barrelPath = path.join(projectRoot, dir.path, 'index.ts')\n const barrelSf = sfByPath.get(barrelPath)\n if (barrelSf) {\n barrels.set(barrelPath, buildBarrelMap(barrelSf, checker))\n }\n }\n\n return barrels\n}\n\nfunction buildBarrelMap(barrelFile: ts.SourceFile, checker: ts.TypeChecker): Map<string, string> {\n const map = new Map<string, string>()\n\n for (const stmt of barrelFile.statements) {\n if (!isNamedReExport(stmt)) continue\n\n const targetPath = resolveModulePath(stmt.moduleSpecifier, checker)\n if (!targetPath) continue\n\n for (const el of stmt.exportClause.elements) {\n if (!el.isTypeOnly) {\n map.set(el.name.text, targetPath)\n }\n }\n }\n\n return map\n}\n\nfunction isNamedReExport(stmt: ts.Statement): stmt is ts.ExportDeclaration & {\n exportClause: ts.NamedExports\n moduleSpecifier: ts.Expression\n} {\n return (\n ts.isExportDeclaration(stmt) &&\n !stmt.isTypeOnly &&\n !!stmt.moduleSpecifier &&\n !!stmt.exportClause &&\n ts.isNamedExports(stmt.exportClause)\n )\n}\n\nfunction countConsumers(\n sourceFiles: ts.SourceFile[],\n sourceRoot: string,\n ctx: AnalysisContext,\n): void {\n for (const sf of sourceFiles) {\n if (ctx.modules.has(sf.fileName) || isTestFile(sf.fileName)) continue\n\n const consumerPath = toPosix(path.relative(sourceRoot, sf.fileName))\n\n for (const stmt of sf.statements) {\n if (ts.isImportDeclaration(stmt)) {\n recordImport(stmt, consumerPath, ctx)\n }\n }\n }\n}\n\nfunction isTestFile(filePath: string): boolean {\n return TEST_FILE_RE.test(filePath)\n}\n\nconst TEST_FILE_RE = /\\.(test|integration-test|test-suite)\\.ts$/\n\nfunction recordImport(\n stmt: ts.ImportDeclaration,\n consumerPath: string,\n ctx: AnalysisContext,\n): void {\n const targetPath = resolveModulePath(stmt.moduleSpecifier, ctx.checker)\n if (!targetPath) return\n\n const direct = ctx.modules.get(targetPath)\n if (direct) {\n direct.consumers.add(deriveEntity(consumerPath, direct.mode))\n return\n }\n\n const barrelMap = ctx.barrels.get(targetPath)\n if (barrelMap) {\n resolveBarrelImports(stmt, barrelMap, consumerPath, ctx.modules)\n }\n}\n\nfunction resolveBarrelImports(\n stmt: ts.ImportDeclaration,\n barrelMap: Map<string, string>,\n consumerPath: string,\n modules: Map<string, ModuleEntry>,\n): void {\n const bindings = stmt.importClause?.namedBindings\n if (!bindings) return\n\n const paths = ts.isNamespaceImport(bindings)\n ? [...barrelMap.values()]\n : resolveNamedImports(bindings, barrelMap)\n\n for (const resolved of paths) {\n const entry = modules.get(resolved)\n entry?.consumers.add(deriveEntity(consumerPath, entry.mode))\n }\n}\n\nfunction resolveNamedImports(bindings: ts.NamedImports, barrelMap: Map<string, string>): string[] {\n const result: string[] = []\n for (const el of bindings.elements) {\n const name = el.propertyName?.text ?? el.name.text\n const resolved = barrelMap.get(name)\n if (resolved) {\n result.push(resolved)\n }\n }\n return result\n}\n\nfunction resolveModulePath(specifier: ts.Expression, checker: ts.TypeChecker): string | undefined {\n const symbol = checker.getSymbolAtLocation(specifier)\n return symbol?.declarations?.[0]?.getSourceFile().fileName\n}\n\nfunction collectErrors(modules: Map<string, ModuleEntry>): Map<string, string[]> {\n const errors = new Map<string, string[]>()\n\n for (const [, entry] of modules) {\n if (entry.consumers.size >= 2) continue\n\n const consumers = [...entry.consumers]\n const description =\n consumers.length === 0\n ? 'not imported by any entity'\n : `only used by: ${consumers.join(', ')}`\n\n errors.set(entry.relativePath, [`${description} -> Must be used by 2+ entities`])\n }\n\n return errors\n}\n\nfunction deriveEntity(consumerPath: string, mode: SharingMode): string {\n if (mode === 'file') {\n return consumerPath\n }\n return consumerPath.split('/').slice(0, -1).slice(0, MAX_DIR_DEPTH).join('/')\n}\n\nconst MAX_DIR_DEPTH = 3\n\ninterface AnalysisContext {\n modules: Map<string, ModuleEntry>\n barrels: Map<string, Map<string, string>>\n checker: ts.TypeChecker\n}\n\ninterface ModuleEntry {\n relativePath: string\n mode: SharingMode\n consumers: Set<string>\n}\n","import type { Rule } from 'eslint'\nimport type ts from 'typescript'\nimport { resolveSourceContext } from '../utils/source-root.js'\nimport { readDirsOption, readSourceRootOption } from '../utils/rule-options.js'\nimport { runConsumerCheck } from './no-false-sharing/analysis.js'\n\nconst SCHEMA = [\n {\n type: 'object',\n properties: {\n dirs: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n mode: { type: 'string', enum: ['file', 'dir'] },\n },\n required: ['path'],\n additionalProperties: false,\n },\n },\n mode: { type: 'string', enum: ['file', 'dir'] },\n sourceRoot: { type: 'string' },\n },\n required: ['dirs'],\n additionalProperties: false,\n },\n]\n\nexport default {\n meta: {\n type: 'problem',\n docs: {\n description: 'Require selected modules to be shared across at least two consumer entities',\n recommended: false,\n },\n schema: SCHEMA,\n },\n create(context: Rule.RuleContext) {\n const dirs = readDirsOption(context.options)\n if (dirs.length === 0) {\n return {}\n }\n\n const filename = context.filename\n const sourceRootOption = readSourceRootOption(context.options)\n const sourceContext = resolveSourceContext(filename, sourceRootOption)\n if (!sourceContext) {\n return {}\n }\n\n const { sourceRelativePath, sourceRoot, projectRoot } = sourceContext\n\n return {\n Program(node) {\n const program = extractTsProgram(context)\n if (!program) {\n return\n }\n\n const errors = runConsumerCheck(program, projectRoot, sourceRoot, dirs)\n const fileErrors = errors.get(sourceRelativePath)\n if (!fileErrors) {\n return\n }\n\n for (const message of fileErrors) {\n context.report({ node, message })\n }\n },\n }\n },\n} satisfies Rule.RuleModule\n\nfunction extractTsProgram(context: Rule.RuleContext): ts.Program | undefined {\n const services = context.sourceCode.parserServices\n if (!isRecord(services) || !('program' in services)) {\n return undefined\n }\n const program = services.program\n if (!isTsProgram(program)) {\n return undefined\n }\n return program\n}\n\nfunction isTsProgram(value: unknown): value is ts.Program {\n return isRecord(value) && 'getTypeChecker' in value\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != undefined && typeof value === 'object'\n}\n","import type { ClassBody, Identifier, Node, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportClassOrdering(program: Program, context: Rule.RuleContext): void {\n for (const classNode of collectClassDeclarations(program)) {\n const members = collectClassMembers(classNode)\n reportConstructorOrder(members, classNode, context)\n reportPublicFieldOrder(members, context)\n reportClassDependencyOrder(members, context)\n }\n}\n\nfunction collectClassDeclarations(program: Program): ClassNode[] {\n const classes: ClassNode[] = []\n\n for (const statement of getTopLevelStatements(program)) {\n const classNode = extractClassNode(statement)\n if (classNode) classes.push(classNode)\n }\n\n return classes\n}\n\nfunction extractClassNode(statement: TopLevelNode): ClassNode | undefined {\n if (statement.type === 'ClassDeclaration') return statement\n\n if (\n statement.type === 'ExportNamedDeclaration' &&\n statement.declaration?.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n if (\n statement.type === 'ExportDefaultDeclaration' &&\n statement.declaration.type === 'ClassDeclaration'\n ) {\n return statement.declaration\n }\n\n return undefined\n}\n\nfunction reportConstructorOrder(\n members: ClassMemberEntry[],\n classNode: ClassNode,\n context: Rule.RuleContext,\n): void {\n const ctor = members.find((m) => m.kind === 'constructor')\n if (!ctor || ctor.index === 0) return\n\n context.report({\n node: ctor.node,\n messageId: 'constructorFirst',\n data: { className: classNode.id?.name ?? 'anonymous class' },\n })\n}\n\nfunction reportPublicFieldOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const ctorIndex = members.find((m) => m.kind === 'constructor')?.index ?? -1\n const startIndex = ctorIndex >= 0 ? ctorIndex + 1 : 0\n let seenOther = false\n\n for (const member of members) {\n if (member.index < startIndex) continue\n\n if (member.kind === 'public-field') {\n if (seenOther) {\n context.report({\n node: member.node,\n messageId: 'publicFieldOrder',\n data: { memberName: member.name },\n })\n }\n continue\n }\n\n seenOther = true\n }\n}\n\nfunction reportClassDependencyOrder(members: ClassMemberEntry[], context: Rule.RuleContext): void {\n const others = members.filter((m) => m.kind === 'other')\n\n for (const member of others) {\n const consumer = findFirstClassConsumer(others, member, context)\n if (!consumer) continue\n\n context.report({\n node: member.node,\n messageId: 'moveMemberBelow',\n data: { memberName: member.name, consumerName: consumer.name },\n })\n }\n}\n\nfunction collectClassMembers(classNode: ClassNode): ClassMemberEntry[] {\n const members: ClassMemberEntry[] = []\n\n for (const [index, raw] of classNode.body.body.entries()) {\n const named = toNamedMember(raw)\n if (!named) continue\n members.push({ name: named.name, node: named.node, index, kind: classifyMember(named.node) })\n }\n\n return members\n}\n\nfunction toNamedMember(raw: Node): { name: string; node: Node } | undefined {\n if (!hasMemberKey(raw)) return undefined\n const name = readMemberName(raw.key)\n return name ? { name, node: raw } : undefined\n}\n\nfunction hasMemberKey(value: object): value is { key: Node } {\n return 'key' in value && isNode(value.key)\n}\n\nfunction readMemberName(key: Node): string | undefined {\n if (key.type === 'Identifier') return key.name\n if (key.type === 'Literal' && typeof key.value === 'string') return key.value\n if (key.type === 'PrivateIdentifier') return `#${key.name}`\n return undefined\n}\n\nfunction classifyMember(member: Node): ClassMemberEntry['kind'] {\n if (member.type === 'MethodDefinition' && member.kind === 'constructor') return 'constructor'\n if (isPublicField(member)) return 'public-field'\n return 'other'\n}\n\nfunction isPublicField(member: Node): boolean {\n if (member.type !== 'PropertyDefinition' || member.static) return false\n if (member.key.type === 'PrivateIdentifier') return false\n if (!('accessibility' in member)) return true\n return member.accessibility === undefined || member.accessibility === 'public'\n}\n\nfunction findFirstClassConsumer(\n members: ClassMemberEntry[],\n member: ClassMemberEntry,\n context: Rule.RuleContext,\n): ClassMemberEntry | undefined {\n const pattern = new RegExp(`\\\\bthis(?:\\\\?\\\\.|\\\\.)${escapeRegex(member.name)}\\\\b`)\n\n for (const candidate of members) {\n if (candidate.index <= member.index) continue\n if (pattern.test(context.sourceCode.getText(candidate.node))) return candidate\n }\n\n return undefined\n}\n\nfunction escapeRegex(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction isNode(value: unknown): value is Node {\n return !!value && typeof value === 'object' && 'type' in value && typeof value.type === 'string'\n}\n\ninterface ClassNode {\n id?: Identifier | null\n body: ClassBody\n}\n\ninterface ClassMemberEntry {\n name: string\n node: Node\n index: number\n kind: 'constructor' | 'public-field' | 'other'\n}\n","import type { CallExpression, ExpressionStatement, Program } from 'estree'\nimport type { Rule } from 'eslint'\nimport { getTopLevelStatements, type TopLevelNode } from '../read-friendly-order.js'\n\nexport function reportTestOrdering(program: Program, context: Rule.RuleContext): void {\n const entries = collectTestPhaseEntries(program)\n if (!entries.some((entry) => entry.kind === 'test')) {\n return\n }\n\n reportSetupOrder(entries, context)\n reportTeardownOrder(entries, context)\n}\n\nfunction collectTestPhaseEntries(program: Program): TestPhaseEntry[] {\n const entries: TestPhaseEntry[] = []\n\n for (const [index, statement] of getTopLevelStatements(program).entries()) {\n const entry = toTestPhaseEntry(statement, index)\n if (entry) {\n entries.push(entry)\n }\n }\n\n return entries\n}\n\nfunction toTestPhaseEntry(statement: TopLevelNode, index: number): TestPhaseEntry | undefined {\n if (statement.type !== 'ExpressionStatement' || statement.expression.type !== 'CallExpression') {\n return undefined\n }\n\n const rootName = getCallRootName(statement.expression)\n if (!rootName) {\n return undefined\n }\n\n const kind = classifyHookName(rootName)\n if (!kind) {\n return undefined\n }\n\n return { index, kind, hookName: rootName, node: statement }\n}\n\nfunction classifyHookName(name: string): TestPhaseEntry['kind'] | undefined {\n if (SETUP_HOOKS.has(name)) return 'setup'\n if (TEARDOWN_HOOKS.has(name)) return 'teardown'\n if (TEST_CALLS.has(name)) return 'test'\n return undefined\n}\n\nconst SETUP_HOOKS = new Set(['beforeAll', 'beforeEach', 'before'])\nconst TEARDOWN_HOOKS = new Set(['afterAll', 'afterEach', 'after'])\nconst TEST_CALLS = new Set(['test', 'it'])\n\nfunction getCallRootName(call: CallExpression): string | undefined {\n const callee = call.callee\n if (callee.type === 'Identifier') return callee.name\n if (callee.type === 'MemberExpression') return readObjectRoot(callee.object)\n if (callee.type === 'CallExpression') return getCallRootName(callee)\n return undefined\n}\n\nfunction readObjectRoot(node: CallExpression['callee']): string | undefined {\n if (node.type === 'Identifier') return node.name\n if (node.type === 'MemberExpression') return readObjectRoot(node.object)\n if (node.type === 'CallExpression') return getCallRootName(node)\n return undefined\n}\n\nfunction reportSetupOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTeardown = findFirstIndex(entries, 'teardown')\n const firstTest = findFirstIndex(entries, 'test')\n\n for (const entry of entries) {\n if (entry.kind !== 'setup') continue\n\n if (firstTeardown >= 0 && entry.index > firstTeardown) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTeardown',\n data: { hookName: entry.hookName },\n })\n continue\n }\n\n if (firstTest >= 0 && entry.index > firstTest) {\n context.report({\n node: entry.node,\n messageId: 'setupBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n }\n}\n\nfunction reportTeardownOrder(entries: TestPhaseEntry[], context: Rule.RuleContext): void {\n const firstTest = findFirstIndex(entries, 'test')\n if (firstTest < 0) return\n\n for (const entry of entries) {\n if (entry.kind !== 'teardown' || entry.index <= firstTest) continue\n\n context.report({\n node: entry.node,\n messageId: 'teardownBeforeTests',\n data: { hookName: entry.hookName },\n })\n }\n}\n\nfunction findFirstIndex(entries: TestPhaseEntry[], kind: TestPhaseEntry['kind']): number {\n const match = entries.find((entry) => entry.kind === kind)\n return match ? match.index : -1\n}\n\ninterface TestPhaseEntry {\n index: number\n kind: 'setup' | 'teardown' | 'test'\n hookName: string\n node: ExpressionStatement\n}\n","import type { ExportNamedDeclaration, Node, Program, VariableDeclaration } from 'estree'\nimport type { Rule, Scope } from 'eslint'\nimport { reportClassOrdering } from './read-friendly-order/class-order.js'\nimport { reportTestOrdering } from './read-friendly-order/test-order.js'\n\nconst READ_FRIENDLY_ORDER_MESSAGES = {\n moveHelperBelow:\n 'Place helper \"{{helperName}}\" below the top-level symbol \"{{symbolName}}\" that depends on it.',\n moveConstantBelow:\n 'Place constant \"{{constantName}}\" below the top-level symbol \"{{symbolName}}\" that uses it.',\n constructorFirst: 'Place constructor first in class \"{{className}}\".',\n publicFieldOrder:\n 'Place public field \"{{memberName}}\" right after constructor and before other class members.',\n moveMemberBelow:\n 'Place class member \"{{memberName}}\" below member \"{{consumerName}}\" that depends on it.',\n setupBeforeTeardown: 'Place setup hook \"{{hookName}}\" before teardown hooks in this test file.',\n setupBeforeTests: 'Place setup hook \"{{hookName}}\" before test cases in this test file.',\n teardownBeforeTests: 'Place teardown hook \"{{hookName}}\" before test cases in this test file.',\n}\n\nexport default {\n meta: {\n type: 'suggestion',\n docs: {\n description: 'Enforce top-level symbols before helper declarations they depend on',\n recommended: false,\n },\n schema: [],\n messages: READ_FRIENDLY_ORDER_MESSAGES,\n },\n create(context: Rule.RuleContext) {\n return {\n Program(program) {\n reportTopLevelOrdering(program, context)\n reportClassOrdering(program, context)\n reportTestOrdering(program, context)\n },\n }\n },\n} satisfies Rule.RuleModule\n\nexport type TopLevelNode = Program['body'][number]\n\nfunction reportTopLevelOrdering(program: Program, context: Rule.RuleContext): void {\n const body = getTopLevelStatements(program)\n const helpers = collectHelpers(body)\n const refs = collectReferences(context.sourceCode.scopeManager.globalScope)\n const cyclicNames = findCyclicHelperNames(body, helpers, refs)\n\n for (const helper of helpers) {\n if (cyclicNames.has(helper.name)) continue\n if (hasEagerReference(body, helper, refs)) continue\n\n const consumer = findFirstConsumer(body, helper, refs)\n if (!consumer) continue\n\n context.report({\n node: helper.node,\n messageId: helper.kind === 'constant' ? 'moveConstantBelow' : 'moveHelperBelow',\n data: {\n helperName: helper.name,\n constantName: helper.name,\n symbolName: getSymbolName(consumer),\n },\n })\n }\n}\n\nexport function getTopLevelStatements(program: Program): TopLevelNode[] {\n return program.body.filter((s) => s.type !== 'ImportDeclaration')\n}\n\nfunction collectHelpers(body: TopLevelNode[]): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n for (const [index, statement] of body.entries()) {\n helpers.push(...collectHelperEntries(statement, index))\n }\n return helpers\n}\n\nfunction collectHelperEntries(statement: TopLevelNode, index: number): HelperDeclaration[] {\n const typeName = getTypeDeclarationName(statement)\n if (typeName) return [{ name: typeName, node: statement, index, kind: 'helper' }]\n\n if (statement.type === 'FunctionDeclaration' && statement.id) {\n return [{ name: statement.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (statement.type === 'ExportNamedDeclaration') {\n return collectExportedHelpers(statement, index)\n }\n\n if (statement.type === 'VariableDeclaration') {\n return collectVariableHelpers(statement, index)\n }\n\n return []\n}\n\nfunction getTypeDeclarationName(statement: TopLevelNode): string | undefined {\n const t: string = statement.type\n if (t !== 'TSTypeAliasDeclaration' && t !== 'TSInterfaceDeclaration') return undefined\n return hasIdentifierId(statement) ? statement.id.name : undefined\n}\n\nfunction hasIdentifierId(value: object): value is { id: { type: string; name: string } } {\n if (!('id' in value)) return false\n const { id } = value\n return !!id && typeof id === 'object' && 'type' in id && 'name' in id && id.type === 'Identifier'\n}\n\nfunction collectExportedHelpers(\n statement: ExportNamedDeclaration,\n index: number,\n): HelperDeclaration[] {\n const decl = statement.declaration\n if (!decl) return []\n\n if (decl.type === 'FunctionDeclaration' && decl.id) {\n return [{ name: decl.id.name, node: statement, index, kind: 'helper' }]\n }\n\n if (decl.type === 'VariableDeclaration') return collectVariableHelpers(decl, index)\n return []\n}\n\nfunction collectVariableHelpers(decl: VariableDeclaration, index: number): HelperDeclaration[] {\n const helpers: HelperDeclaration[] = []\n\n for (const item of decl.declarations) {\n if (item.id.type !== 'Identifier') continue\n const isFn = isFunctionInit(item.init ?? null)\n\n if (!isFn && decl.kind !== 'const') continue\n\n helpers.push({\n name: item.id.name,\n node: item,\n index,\n kind: isFn ? 'helper' : 'constant',\n })\n }\n\n return helpers\n}\n\nfunction isFunctionInit(node: Node | null): boolean {\n return node?.type === 'ArrowFunctionExpression' || node?.type === 'FunctionExpression'\n}\n\nfunction findFirstConsumer(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): TopLevelNode | undefined {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementUsesName(stmt, helper.name, refs)) return stmt\n }\n return undefined\n}\n\nfunction findCyclicHelperNames(\n body: TopLevelNode[],\n helpers: HelperDeclaration[],\n refs: Scope.Reference[],\n): Set<string> {\n const deps = new Map<string, Set<string>>()\n\n for (const helper of helpers) {\n const helperDeps = new Set<string>()\n for (const other of helpers) {\n if (other.name !== helper.name && statementUsesName(body[helper.index], other.name, refs)) {\n helperDeps.add(other.name)\n }\n }\n deps.set(helper.name, helperDeps)\n }\n\n const cyclic = new Set<string>()\n for (const helper of helpers) {\n if (canReachSelf(helper.name, deps)) cyclic.add(helper.name)\n }\n return cyclic\n}\n\nfunction statementUsesName(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name) continue\n const idRange = ref.identifier.range\n if (!idRange) continue\n if (idRange[0] >= range[0] && idRange[1] <= range[1]) return true\n }\n\n return false\n}\n\nfunction canReachSelf(start: string, deps: Map<string, Set<string>>): boolean {\n const visited = new Set<string>()\n const queue = [...(deps.get(start) ?? [])]\n\n while (queue.length > 0) {\n const current = queue.shift()!\n if (current === start) return true\n if (visited.has(current)) continue\n visited.add(current)\n for (const dep of deps.get(current) ?? []) queue.push(dep)\n }\n\n return false\n}\n\nfunction collectReferences(scope: Scope.Scope | null): Scope.Reference[] {\n if (!scope) return []\n const refs = [...scope.references]\n for (const child of scope.childScopes) {\n refs.push(...collectReferences(child))\n }\n return refs\n}\n\nfunction hasEagerReference(\n body: TopLevelNode[],\n helper: HelperDeclaration,\n refs: Scope.Reference[],\n): boolean {\n for (let i = helper.index + 1; i < body.length; i += 1) {\n const stmt = body[i]\n if (stmt.type === 'ExportNamedDeclaration' && !stmt.declaration) continue\n if (statementHasEagerUse(stmt, helper.name, refs)) return true\n }\n return false\n}\n\nfunction statementHasEagerUse(\n statement: TopLevelNode,\n name: string,\n refs: Scope.Reference[],\n): boolean {\n const range = statement.range\n if (!range) return false\n\n for (const ref of refs) {\n if (ref.identifier.name !== name || isTypeReference(ref)) continue\n if (isEagerRefInRange(ref, range)) return true\n }\n\n return false\n}\n\nfunction isEagerRefInRange(ref: Scope.Reference, range: [number, number]): boolean {\n const idRange = ref.identifier.range\n if (!idRange) return false\n const inside = idRange[0] >= range[0] && idRange[1] <= range[1]\n return inside && (ref.from.type === 'module' || ref.from.type === 'global')\n}\n\nfunction isTypeReference(ref: Scope.Reference): boolean {\n return 'isTypeReference' in ref && ref.isTypeReference === true\n}\n\nfunction getSymbolName(statement: TopLevelNode): string {\n if (statement.type === 'ExportDefaultDeclaration') return 'default export'\n if (statement.type === 'ExportNamedDeclaration') return getNamedExportName(statement)\n if (statement.type === 'FunctionDeclaration' && statement.id) return statement.id.name\n if (statement.type === 'VariableDeclaration')\n return getVarName(statement) ?? 'top-level statement'\n return 'top-level statement'\n}\n\nfunction getNamedExportName(statement: ExportNamedDeclaration): string {\n const decl = statement.declaration\n if (!decl) return 'named export'\n if (decl.type === 'FunctionDeclaration' && decl.id) return decl.id.name\n if (decl.type === 'VariableDeclaration') return getVarName(decl) ?? 'named export'\n return 'named export'\n}\n\nfunction getVarName(decl: VariableDeclaration): string | undefined {\n const [first] = decl.declarations\n return first?.id.type === 'Identifier' ? first.id.name : undefined\n}\n\ninterface HelperDeclaration {\n name: string\n node: Node\n index: number\n kind: 'helper' | 'constant'\n}\n","import type { Rule } from 'eslint'\nimport noSpecialUnicode from './no-special-unicode.js'\nimport noUnicodeEscape from './no-unicode-escape.js'\nimport noDeepImports from './no-deep-imports.js'\nimport noFalseSharing from './no-false-sharing.js'\nimport readFriendlyOrder from './read-friendly-order.js'\n\nexport default {\n 'no-special-unicode': noSpecialUnicode,\n 'no-unicode-escape': noUnicodeEscape,\n 'no-deep-imports': noDeepImports,\n 'no-false-sharing': noFalseSharing,\n 'read-friendly-order': readFriendlyOrder,\n} satisfies Record<string, Rule.RuleModule>\n","import type { ESLint, Linter } from 'eslint'\nimport packageJson from '../package.json'\nimport rules from './rules/index.js'\n\n// configs.recommended.plugins.unslop must reference the plugin itself.\n// Build plugin first with an empty configs object, then assign below.\nconst plugin: ESLint.Plugin = {\n meta: {\n name: packageJson.name,\n version: packageJson.version,\n },\n rules,\n configs: {},\n}\n\nconst recommended: Linter.Config = {\n name: 'unslop/recommended',\n plugins: { unslop: plugin },\n rules: {\n 'unslop/no-special-unicode': 'error',\n 'unslop/no-unicode-escape': 'error',\n 'unslop/no-deep-imports': 'error',\n },\n}\n\nplugin.configs!['recommended'] = recommended\n\nexport default plugin\n"],"mappings":"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","names":["existsSync","path","path","path","path","existsSync","existsSync","path","path","existsSync","isRecord"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-unslop",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "ESLint plugin with rules for reducing AI-generated code smells",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,12 +27,9 @@
|
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsup",
|
|
29
29
|
"format": "prettier . --write",
|
|
30
|
-
"
|
|
31
|
-
"knip": "knip",
|
|
32
|
-
"lint": "npm run build && eslint .",
|
|
30
|
+
"verify": "prettier . --check && tsc --noEmit && tsup && eslint . && knip",
|
|
33
31
|
"test": "vitest run",
|
|
34
32
|
"test:watch": "vitest",
|
|
35
|
-
"typecheck": "tsc --noEmit",
|
|
36
33
|
"prepublishOnly": "npm run build"
|
|
37
34
|
},
|
|
38
35
|
"keywords": [
|