@tenphi/eslint-plugin-tasty 1.7.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/dist/configs.js +1 -0
- package/dist/configs.js.map +1 -1
- package/dist/constants.js +66 -25
- package/dist/constants.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/state-key-parser.js +24 -1
- package/dist/parsers/state-key-parser.js.map +1 -1
- package/dist/pseudo-elements.js +85 -0
- package/dist/pseudo-elements.js.map +1 -0
- package/dist/rules/no-ignored-pseudo-element-state.js +155 -0
- package/dist/rules/no-ignored-pseudo-element-state.js.map +1 -0
- package/dist/rules/no-state-in-selector.js +30 -23
- package/dist/rules/no-state-in-selector.js.map +1 -1
- package/dist/type-aware-jsx.js +9 -4
- package/dist/type-aware-jsx.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-state-in-selector.js","names":[],"sources":["../../src/rules/no-state-in-selector.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport selectorParser from 'postcss-selector-parser';\nimport { createRule } from '../create-rule.js';\nimport { TastyContext, styleObjectListeners } from '../context.js';\nimport { getKeyName, getStringValue, unwrapExpression } from '../utils.js';\n\nconst STRUCTURAL_PSEUDOS = new Set([':is', ':where']);\
|
|
1
|
+
{"version":3,"file":"no-state-in-selector.js","names":[],"sources":["../../src/rules/no-state-in-selector.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport selectorParser from 'postcss-selector-parser';\nimport { createRule } from '../create-rule.js';\nimport { TastyContext, styleObjectListeners } from '../context.js';\nimport {\n isPseudoElement,\n pseudoElementMismatch,\n pseudoName,\n splitAtPseudoElement,\n} from '../pseudo-elements.js';\nimport { getKeyName, getStringValue, unwrapExpression } from '../utils.js';\n\nconst STRUCTURAL_PSEUDOS = new Set([':is', ':where']);\n\nfunction isCondition(node: selectorParser.Node): boolean {\n if (node.type === 'attribute') {\n // An exact data-element identity is structural, like Tasty's uppercase\n // element names. Other attributes express conditions on that element.\n return !(\n node.attribute === 'data-element' &&\n !node.namespace &&\n node.operator === '=' &&\n node.value\n );\n }\n if (node.type !== 'pseudo') return false;\n return !isPseudoElement(node) && !STRUCTURAL_PSEUDOS.has(pseudoName(node));\n}\n\nfunction findCondition(nodes: selectorParser.Node[]): string | null {\n for (const node of nodes) {\n if (isCondition(node)) return node.toString().trim();\n // Continue into structural wrappers: :where(img:hover) still contains\n // a condition, although the wrapper itself is structural.\n if (selectorParser.isContainer(node)) {\n const condition = findCondition(node.nodes);\n if (condition !== null) return condition;\n }\n }\n return null;\n}\n\n/** Whether @own() can express `node` on a pseudo-element. */\nfunction isPseudoElementState(node: selectorParser.Node): boolean {\n return node.type === 'pseudo' && !pseudoElementMismatch(node.toString());\n}\n\nfunction firstItemCondition(item: selectorParser.Selector): string | null {\n const split = splitAtPseudoElement(item);\n if (split === null) return findCondition(item.nodes);\n\n // The item ends in a pseudo-element, which Tasty treats as the subject:\n // @own() states go after the pseudo-element, and the states it cannot have\n // are dropped. Conditions on the originating element before it, and inside\n // it (::slotted(img:hover), ::after:hover::marker), must stay in `$`.\n return (\n findCondition(item.nodes.slice(0, split.compound)) ??\n findCondition(item.nodes.slice(split.last + 1).filter(isPseudoElementState))\n );\n}\n\nfunction firstStateCondition(selector: string): string | null {\n let root: selectorParser.Root;\n try {\n root = selectorParser().astSync(selector);\n } catch {\n // This recommendation is not a CSS syntax validator. Incomplete selectors\n // must not crash lint or produce a misleading state-map recommendation.\n return null;\n }\n\n // Each item of a selector list is judged on its own.\n for (const item of root.nodes) {\n const condition = firstItemCondition(item);\n if (condition !== null) return condition;\n }\n return null;\n}\n\nexport default createRule<[], 'stateInSelector'>({\n name: 'no-state-in-selector',\n meta: {\n type: 'suggestion',\n docs: {\n description:\n 'Keep sub-element selectors structural and express conditions in property state maps',\n },\n messages: {\n stateInSelector:\n \"Move state condition '{{condition}}' out of the sub-element '$' selector and into property state maps. Use @own(...) for the sub-element's own state. If the condition must stay in this selector, explicitly disable tasty/no-state-in-selector on this line with a reason.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n const ctx = new TastyContext(context);\n const visited = new WeakSet<TSESTree.ObjectExpression>();\n\n function handleStyleObject(node: TSESTree.ObjectExpression) {\n if (visited.has(node) || !ctx.isStyleObject(node)) return;\n visited.add(node);\n const isSubElement = ctx.isInsideSubElement(node);\n\n for (const prop of node.properties) {\n if (prop.type !== 'Property') continue;\n const key = prop.computed\n ? getStringValue(unwrapExpression(prop.key))\n : getKeyName(prop.key);\n // Some listeners match only the shared/JSX root. Follow its owned\n // sub-elements explicitly, without entering state maps or metadata.\n if (!prop.computed && key && ctx.isSubElementKey(key)) {\n const child = unwrapExpression(prop.value);\n if (child.type === 'ObjectExpression') handleStyleObject(child);\n }\n if (!isSubElement || key !== '$') continue;\n\n const selector = getStringValue(unwrapExpression(prop.value));\n if (selector === null) continue;\n const condition = firstStateCondition(selector);\n if (condition === null) continue;\n\n context.report({\n node: prop.value,\n messageId: 'stateInSelector',\n data: { condition },\n });\n }\n }\n\n return {\n ImportDeclaration(node) {\n ctx.trackImport(node);\n },\n ...styleObjectListeners(handleStyleObject),\n };\n },\n});\n"],"mappings":";;;;;;;AAYA,MAAM,qBAAqB,IAAI,IAAI,CAAC,OAAO,SAAS,CAAC;AAErD,SAAS,YAAY,MAAoC;AACvD,KAAI,KAAK,SAAS,YAGhB,QAAO,EACL,KAAK,cAAc,kBACnB,CAAC,KAAK,aACN,KAAK,aAAa,OAClB,KAAK;AAGT,KAAI,KAAK,SAAS,SAAU,QAAO;AACnC,QAAO,CAAC,gBAAgB,KAAK,IAAI,CAAC,mBAAmB,IAAI,WAAW,KAAK,CAAC;;AAG5E,SAAS,cAAc,OAA6C;AAClE,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,YAAY,KAAK,CAAE,QAAO,KAAK,UAAU,CAAC,MAAM;AAGpD,MAAI,eAAe,YAAY,KAAK,EAAE;GACpC,MAAM,YAAY,cAAc,KAAK,MAAM;AAC3C,OAAI,cAAc,KAAM,QAAO;;;AAGnC,QAAO;;;AAIT,SAAS,qBAAqB,MAAoC;AAChE,QAAO,KAAK,SAAS,YAAY,CAAC,sBAAsB,KAAK,UAAU,CAAC;;AAG1E,SAAS,mBAAmB,MAA8C;CACxE,MAAM,QAAQ,qBAAqB,KAAK;AACxC,KAAI,UAAU,KAAM,QAAO,cAAc,KAAK,MAAM;AAMpD,QACE,cAAc,KAAK,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAClD,cAAc,KAAK,MAAM,MAAM,MAAM,OAAO,EAAE,CAAC,OAAO,qBAAqB,CAAC;;AAIhF,SAAS,oBAAoB,UAAiC;CAC5D,IAAI;AACJ,KAAI;AACF,SAAO,gBAAgB,CAAC,QAAQ,SAAS;SACnC;AAGN,SAAO;;AAIT,MAAK,MAAM,QAAQ,KAAK,OAAO;EAC7B,MAAM,YAAY,mBAAmB,KAAK;AAC1C,MAAI,cAAc,KAAM,QAAO;;AAEjC,QAAO;;AAGT,mCAAe,WAAkC;CAC/C,MAAM;CACN,MAAM;EACJ,MAAM;EACN,MAAM,EACJ,aACE,uFACH;EACD,UAAU,EACR,iBACE,gRACH;EACD,QAAQ,EAAE;EACX;CACD,gBAAgB,EAAE;CAClB,OAAO,SAAS;EACd,MAAM,MAAM,IAAI,aAAa,QAAQ;EACrC,MAAM,0BAAU,IAAI,SAAoC;EAExD,SAAS,kBAAkB,MAAiC;AAC1D,OAAI,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,cAAc,KAAK,CAAE;AACnD,WAAQ,IAAI,KAAK;GACjB,MAAM,eAAe,IAAI,mBAAmB,KAAK;AAEjD,QAAK,MAAM,QAAQ,KAAK,YAAY;AAClC,QAAI,KAAK,SAAS,WAAY;IAC9B,MAAM,MAAM,KAAK,WACb,eAAe,iBAAiB,KAAK,IAAI,CAAC,GAC1C,WAAW,KAAK,IAAI;AAGxB,QAAI,CAAC,KAAK,YAAY,OAAO,IAAI,gBAAgB,IAAI,EAAE;KACrD,MAAM,QAAQ,iBAAiB,KAAK,MAAM;AAC1C,SAAI,MAAM,SAAS,mBAAoB,mBAAkB,MAAM;;AAEjE,QAAI,CAAC,gBAAgB,QAAQ,IAAK;IAElC,MAAM,WAAW,eAAe,iBAAiB,KAAK,MAAM,CAAC;AAC7D,QAAI,aAAa,KAAM;IACvB,MAAM,YAAY,oBAAoB,SAAS;AAC/C,QAAI,cAAc,KAAM;AAExB,YAAQ,OAAO;KACb,MAAM,KAAK;KACX,WAAW;KACX,MAAM,EAAE,WAAW;KACpB,CAAC;;;AAIN,SAAO;GACL,kBAAkB,MAAM;AACtB,QAAI,YAAY,KAAK;;GAEvB,GAAG,qBAAqB,kBAAkB;GAC3C;;CAEJ,CAAC"}
|
package/dist/type-aware-jsx.js
CHANGED
|
@@ -8,10 +8,15 @@ let typescript;
|
|
|
8
8
|
const projects = /* @__PURE__ */ new Map();
|
|
9
9
|
const classifiers = /* @__PURE__ */ new WeakMap();
|
|
10
10
|
function getTypeScript() {
|
|
11
|
-
if (!typescript)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
if (!typescript) {
|
|
12
|
+
let module;
|
|
13
|
+
try {
|
|
14
|
+
module = require("typescript");
|
|
15
|
+
} catch {
|
|
16
|
+
throw new Error("tasty: typeAwareJSX requires TypeScript. Install typescript as a dev dependency.");
|
|
17
|
+
}
|
|
18
|
+
if (typeof module.createProgram !== "function") throw new Error(`tasty: typeAwareJSX requires the TypeScript compiler API, which ${module.version ? `typescript ${module.version}` : "the installed typescript"} does not provide. Install TypeScript 5.6–6.x as a dev dependency.`);
|
|
19
|
+
typescript = module;
|
|
15
20
|
}
|
|
16
21
|
return typescript;
|
|
17
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-aware-jsx.js","names":[],"sources":["../src/type-aware-jsx.ts"],"sourcesContent":["import { statSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport type ts from 'typescript';\nimport type { TSESTree } from '@typescript-eslint/utils';\nimport type { RuleContext } from '@typescript-eslint/utils/ts-eslint';\n\n/** Experimental, independently managed TypeScript analysis for either linter. */\nexport interface TypeAwareJSXOptions {\n /** tsconfig path relative to the linter's cwd; otherwise find the nearest one. */\n project?: string;\n}\n\ntype PropKind = 'style' | 'component' | 'unknown';\ntype TypeScript = typeof ts;\ntype Classifier = (attribute: TSESTree.JSXAttribute) => PropKind;\n\ninterface Project {\n config: ts.ParsedCommandLine;\n configVersions: Map<string, string>;\n program?: ts.Program;\n versions: Map<string, string>;\n overlay?: { filename: string; text: string };\n sourceFiles: Map<\n string,\n {\n version: string;\n overlayText?: string;\n parseKey: string;\n source: ts.SourceFile;\n }\n >;\n excludedFiles: Map<string, string>;\n}\n\nconst require = createRequire(import.meta.url);\nlet typescript: TypeScript | undefined;\nconst projects = new Map<string, Project>();\n// All value rules share one classifier for a file, including in Oxlint.\nconst classifiers = new WeakMap<\n object,\n Map<\n string,\n {\n filename: string;\n text: string;\n classify: Classifier;\n }\n >\n>();\n\nfunction getTypeScript(): TypeScript {\n if (!typescript) {\n try {\n typescript = require('typescript') as TypeScript;\n } catch {\n throw new Error(\n 'tasty: typeAwareJSX requires TypeScript. Install typescript as a dev dependency.',\n );\n }\n }\n return typescript;\n}\n\nfunction version(filename: string): string {\n try {\n const stat = statSync(filename);\n return `${stat.mtimeMs}:${stat.ctimeMs}:${stat.size}`;\n } catch {\n return 'missing';\n }\n}\n\nfunction changed(versions: Map<string, string>): boolean {\n for (const [filename, previous] of versions) {\n if (version(filename) !== previous) return true;\n }\n return false;\n}\n\nfunction readConfig(\n T: TypeScript,\n configPath: string,\n configVersions: Map<string, string>,\n): ts.ParsedCommandLine {\n const config = T.getParsedCommandLineOfConfigFile(\n configPath,\n {},\n {\n ...T.sys,\n readFile(filename) {\n configVersions.set(filename, version(filename));\n return T.sys.readFile(filename);\n },\n onUnRecoverableConfigFileDiagnostic(diagnostic) {\n throw new Error(\n `tasty: ${T.flattenDiagnosticMessageText(diagnostic.messageText, '\\n')}`,\n );\n },\n },\n );\n if (!config || config.errors.length) {\n throw new Error(\n `tasty: invalid typeAwareJSX project ${configPath}: ${config?.errors\n .map((d) => T.flattenDiagnosticMessageText(d.messageText, '\\n'))\n .join('\\n')}`,\n );\n }\n return config;\n}\n\nfunction readProject(T: TypeScript, configPath: string): Project {\n const configVersions = new Map<string, string>();\n return {\n config: readConfig(T, configPath, configVersions),\n configVersions,\n versions: new Map(),\n sourceFiles: new Map(),\n excludedFiles: new Map(),\n };\n}\n\nfunction getProgram(\n T: TypeScript,\n configPath: string,\n filename: string,\n text: string,\n): ts.Program {\n let project = projects.get(configPath);\n let rootsChanged = false;\n if (!project || changed(project.configVersions)) {\n project = readProject(T, configPath);\n } else if (\n project.program &&\n !project.program.getSourceFile(filename) &&\n project.excludedFiles.get(filename) !== version(filename)\n ) {\n const refreshed = readProject(T, configPath);\n const previousFiles = project.config.fileNames;\n rootsChanged =\n refreshed.config.fileNames.length !== previousFiles.length ||\n refreshed.config.fileNames.some(\n (file, index) => file !== previousFiles[index],\n );\n if (rootsChanged) project.config = refreshed.config;\n if (!project.config.fileNames.includes(filename))\n project.excludedFiles.set(filename, version(filename));\n else project.excludedFiles.delete(filename);\n }\n // Bound retained compiler graphs in long-lived editor processes.\n projects.delete(configPath);\n projects.set(configPath, project);\n if (projects.size > 3) projects.delete(projects.keys().next().value!);\n\n const sourcesChanged = changed(project.versions);\n const overlay =\n project.excludedFiles.has(filename) &&\n !project.program?.getSourceFile(filename) &&\n !rootsChanged &&\n !sourcesChanged\n ? undefined\n : T.sys.readFile(filename) === text\n ? undefined\n : { filename, text };\n const overlayChanged =\n project.overlay?.filename !== overlay?.filename ||\n project.overlay?.text !== overlay?.text;\n if (!project.program || rootsChanged || overlayChanged || sourcesChanged) {\n const host = T.createCompilerHost(project.config.options, true);\n host.getParsedCommandLine = (path) =>\n readConfig(T, path, project.configVersions);\n const readFile = host.readFile;\n host.readFile = (path) =>\n resolve(path) === overlay?.filename ? overlay.text : readFile(path);\n const getSourceFile = host.getSourceFile;\n host.getSourceFile = (path, options, onError, force) => {\n const key = resolve(path);\n const stamp = version(key);\n const overlayText = key === overlay?.filename ? overlay.text : undefined;\n const parseOptions =\n typeof options === 'number' ? { languageVersion: options } : options;\n const parseKey = [\n parseOptions.languageVersion,\n parseOptions.impliedNodeFormat,\n parseOptions.jsDocParsingMode,\n ].join(':');\n const cached = project.sourceFiles.get(key);\n if (\n !force &&\n cached?.version === stamp &&\n cached.overlayText === overlayText &&\n cached.parseKey === parseKey\n )\n return cached.source;\n const source = getSourceFile(path, options, onError, force);\n if (source)\n project.sourceFiles.set(key, {\n version: stamp,\n overlayText,\n parseKey,\n source,\n });\n else project.sourceFiles.delete(key);\n return source;\n };\n project.program = T.createProgram({\n rootNames: project.config.fileNames,\n options: project.config.options,\n projectReferences: project.config.projectReferences,\n host,\n oldProgram: project.program,\n });\n project.overlay = project.program.getSourceFile(filename)\n ? overlay\n : undefined;\n if (!project.program.getSourceFile(filename))\n project.excludedFiles.set(filename, version(filename));\n project.versions = new Map(\n project.program\n .getSourceFiles()\n .map((file) => [file.fileName, version(file.fileName)]),\n );\n const retained = new Set(\n project.program.getSourceFiles().map((file) => resolve(file.fileName)),\n );\n for (const path of project.sourceFiles.keys()) {\n if (!retained.has(path)) project.sourceFiles.delete(path);\n }\n }\n return project.program;\n}\n\nfunction makeClassifier(\n T: TypeScript,\n program: ts.Program,\n filename: string,\n text: string,\n): Classifier {\n const source = program.getSourceFile(filename);\n // Excluded files and virtual/transformed source keep the existing heuristic.\n if (!source || source.text !== text) return () => 'unknown';\n const checker = program.getTypeChecker();\n const modulePath = T.resolveModuleName(\n '@tenphi/tasty',\n filename,\n program.getCompilerOptions(),\n T.sys,\n ).resolvedModule?.resolvedFileName;\n const moduleFile = modulePath && program.getSourceFile(modulePath);\n const module = moduleFile && checker.getSymbolAtLocation(moduleFile);\n const exports = module ? checker.getExportsOfModule(module) : [];\n const styleTypeSymbols = new Set(\n exports\n ?.filter((s) =>\n ['Styles', 'StyleValue', 'StyleValueStateMap'].includes(s.name),\n )\n .map((s) =>\n s.flags & T.SymbolFlags.Alias ? checker.getAliasedSymbol(s) : s,\n ),\n );\n let symbol = exports?.find((s) => s.name === 'Styles');\n if (symbol && symbol.flags & T.SymbolFlags.Alias) {\n symbol = checker.getAliasedSymbol(symbol);\n }\n const styles = symbol && checker.getDeclaredTypeOfSymbol(symbol);\n if (!styles || styles.flags & (T.TypeFlags.Any | T.TypeFlags.Unknown)) {\n return () => 'unknown';\n }\n const styleDeclarations = new Set(\n styles.getProperties().flatMap((property) => property.declarations ?? []),\n );\n // A dependency may resolve a different copy of either styling package.\n function isStyleDeclaration(declaration: ts.Declaration): boolean {\n return (\n styleDeclarations.has(declaration) ||\n /[/\\\\]node_modules[/\\\\](?:@tenphi[/\\\\]tasty|csstype)[/\\\\]/.test(\n declaration.getSourceFile().fileName,\n )\n );\n }\n const attributes = new Map<number, ts.JsxAttribute>();\n function collect(node: ts.Node): void {\n if (T.isJsxAttribute(node)) attributes.set(node.getStart(source), node);\n T.forEachChild(node, collect);\n }\n collect(source);\n\n function referencesStyles(\n node: ts.Node,\n visited = new Set<ts.Node>(),\n bindings = new Map<ts.Symbol, ts.TypeNode>(),\n ): boolean {\n if (visited.has(node)) return false;\n visited.add(node);\n try {\n if (\n T.isPropertySignature(node) ||\n T.isPropertyDeclaration(node) ||\n T.isParameter(node) ||\n T.isTypeAliasDeclaration(node) ||\n T.isMappedTypeNode(node) ||\n T.isParenthesizedTypeNode(node)\n )\n return node.type\n ? referencesStyles(node.type, visited, bindings)\n : false;\n if (T.isIndexedAccessTypeNode(node)) {\n const object = checker.getTypeFromTypeNode(node.objectType);\n const index = checker.getTypeFromTypeNode(node.indexType);\n const keys = index.isUnion() ? index.types : [index];\n // Trace the selected property, not unrelated style props on the object.\n return (\n object === styles ||\n keys.some((key) => {\n if (!key.isStringLiteral() && !key.isNumberLiteral()) return false;\n const property = checker.getPropertyOfType(\n object,\n String(key.value),\n );\n return property?.declarations?.some(\n (declaration) =>\n isStyleDeclaration(declaration) ||\n referencesStyles(declaration, visited, bindings),\n );\n })\n );\n }\n if (T.isTypeReferenceNode(node) || T.isImportTypeNode(node)) {\n const name = T.isTypeReferenceNode(node)\n ? node.typeName\n : node.qualifier;\n let reference = name && checker.getSymbolAtLocation(name);\n if (reference && reference.flags & T.SymbolFlags.Alias) {\n reference = checker.getAliasedSymbol(reference);\n }\n if (reference && styleTypeSymbols.has(reference)) return true;\n if (reference?.declarations?.some(isStyleDeclaration)) return true;\n const bound = reference && bindings.get(reference);\n if (bound) return referencesStyles(bound, visited, bindings);\n if (\n reference?.declarations?.some((declaration) => {\n if (!T.isTypeAliasDeclaration(declaration)) return false;\n const local = new Map(bindings);\n declaration.typeParameters?.forEach((parameter, index) => {\n const symbol = checker.getSymbolAtLocation(parameter.name);\n const argument = node.typeArguments?.[index] ?? parameter.default;\n if (symbol && argument) local.set(symbol, argument);\n });\n return referencesStyles(declaration.type, visited, local);\n })\n )\n return true;\n }\n if (T.isConditionalTypeNode(node)) {\n // Extract/Exclude-style filters preserve an input value or return never.\n const parameter = (branch: ts.TypeNode) => {\n if (!T.isTypeReferenceNode(branch)) return undefined;\n const symbol = checker.getSymbolAtLocation(branch.typeName);\n return symbol && symbol.flags & T.SymbolFlags.TypeParameter\n ? symbol\n : undefined;\n };\n const trueParameter = parameter(node.trueType);\n const falseParameter = parameter(node.falseType);\n const preservesValue =\n (trueParameter &&\n node.falseType.kind === T.SyntaxKind.NeverKeyword) ||\n (falseParameter &&\n node.trueType.kind === T.SyntaxKind.NeverKeyword) ||\n (trueParameter && trueParameter === falseParameter);\n return (\n Boolean(preservesValue) &&\n (referencesStyles(node.trueType, visited, bindings) ||\n referencesStyles(node.falseType, visited, bindings))\n );\n }\n // Nested fields, function arguments and conditional constraints are content,\n // not evidence that the prop's value itself originates in a style type.\n return (\n (T.isUnionTypeNode(node) || T.isIntersectionTypeNode(node)) &&\n node.types.some((part) => referencesStyles(part, visited, bindings))\n );\n } finally {\n visited.delete(node);\n }\n }\n\n function unresolved(type: ts.Type): boolean {\n if (\n type.flags &\n (T.TypeFlags.Any |\n T.TypeFlags.Unknown |\n T.TypeFlags.TypeParameter |\n T.TypeFlags.Conditional |\n T.TypeFlags.IndexedAccess |\n T.TypeFlags.Never)\n )\n return true;\n return type.isUnionOrIntersection() && type.types.some(unresolved);\n }\n\n function hasPrimitiveFlag(type: ts.Type, flags: number): boolean {\n return (\n Boolean(type.flags & flags) ||\n (type.isIntersection() &&\n type.types.some((part) => hasPrimitiveFlag(part, flags)))\n );\n }\n\n function unresolvedComponentProp(\n node: ts.JsxAttribute,\n name: string,\n ): boolean {\n const tag = node.parent.parent.tagName;\n const component = checker.getTypeAtLocation(tag);\n return [\n ...component.getCallSignatures(),\n ...component.getConstructSignatures(),\n ].some((signature) => {\n const parameter = signature.parameters[0];\n if (!parameter) return false;\n const props = checker.getTypeOfSymbolAtLocation(parameter, tag);\n const property = checker.getPropertyOfType(props, name);\n return property\n ? unresolved(checker.getTypeOfSymbolAtLocation(property, tag))\n : false;\n });\n }\n\n const results = new Map<number, PropKind>();\n return (attribute) => {\n const start = attribute.range[0];\n const cached = results.get(start);\n if (cached) return cached;\n const node = attributes.get(start);\n let kind: PropKind = 'unknown';\n if (node && node.end === attribute.range[1] && T.isIdentifier(node.name)) {\n const props = checker.getContextualType(node.parent);\n const property =\n props && checker.getPropertyOfType(props, node.name.text);\n const declarations = property?.declarations;\n if (property && declarations?.length) {\n const type = checker.getTypeOfSymbolAtLocation(property, node);\n if (\n declarations.some((d) => isStyleDeclaration(d) || referencesStyles(d))\n ) {\n kind = 'style';\n } else if (\n !unresolved(type) &&\n !(\n declarations.some((declaration) =>\n unresolved(checker.getTypeAtLocation(declaration)),\n ) && unresolvedComponentProp(node, node.name.text)\n )\n ) {\n // Broad primitives may be hand-written style props. Preserve checks.\n const nonNullable = checker.getNonNullableType(type);\n const parts = nonNullable.isUnion()\n ? nonNullable.types\n : [nonNullable];\n const primitive =\n T.TypeFlags.StringLike |\n T.TypeFlags.NumberLike |\n T.TypeFlags.BooleanLike |\n T.TypeFlags.BigIntLike;\n const broad =\n T.TypeFlags.String |\n T.TypeFlags.Number |\n T.TypeFlags.Boolean |\n T.TypeFlags.BigInt;\n const broadPrimitive =\n parts.every((part) => hasPrimitiveFlag(part, primitive)) &&\n (Boolean(nonNullable.flags & broad) ||\n parts.some((part) => hasPrimitiveFlag(part, broad)) ||\n parts.every((part) =>\n hasPrimitiveFlag(part, T.TypeFlags.BooleanLike),\n ));\n if (!broadPrimitive) kind = 'component';\n }\n }\n }\n results.set(start, kind);\n return kind;\n };\n}\n\n/** No compiler is loaded, or program created, unless the setting is enabled. */\nexport function jsxPropKind(\n context: RuleContext<string, unknown[]>,\n attribute: TSESTree.JSXAttribute,\n): PropKind {\n const settings = context.settings.tasty as\n | { typeAwareJSX?: boolean | TypeAwareJSXOptions }\n | undefined;\n const option = settings?.typeAwareJSX;\n if (option === undefined || option === false) return 'unknown';\n if (\n option !== true &&\n (!option ||\n typeof option !== 'object' ||\n Array.isArray(option) ||\n (option.project !== undefined && typeof option.project !== 'string'))\n )\n throw new Error(\n 'tasty: typeAwareJSX must be true, false, or { project: string }.',\n );\n\n const filename = resolve(context.cwd, context.filename);\n const explicit = option === true ? undefined : option.project;\n const sourceCode = context.sourceCode;\n const key = explicit ? resolve(context.cwd, explicit) : 'nearest';\n let byProject = classifiers.get(sourceCode);\n if (!byProject) {\n byProject = new Map();\n classifiers.set(sourceCode, byProject);\n }\n let cached = byProject.get(key);\n if (\n !cached ||\n cached.filename !== filename ||\n cached.text !== sourceCode.text\n ) {\n const T = getTypeScript();\n const configPath = explicit\n ? key\n : T.findConfigFile(dirname(filename), T.sys.fileExists);\n if (!configPath)\n throw new Error(\n `tasty: typeAwareJSX could not find a tsconfig for ${filename}.`,\n );\n const program = getProgram(T, configPath, filename, sourceCode.text);\n cached = {\n filename,\n text: sourceCode.text,\n classify: makeClassifier(T, program, filename, sourceCode.text),\n };\n byProject.set(key, cached);\n }\n return cached.classify(attribute);\n}\n\n/** A SourceCode object may be reused by ESLint after dependencies change. */\nexport function finishJSXAnalysis(\n context: RuleContext<string, unknown[]>,\n): void {\n classifiers.delete(context.sourceCode);\n}\n"],"mappings":";;;;;AAmCA,MAAM,UAAU,cAAc,OAAO,KAAK,IAAI;AAC9C,IAAI;AACJ,MAAM,2BAAW,IAAI,KAAsB;AAE3C,MAAM,8BAAc,IAAI,SAUrB;AAEH,SAAS,gBAA4B;AACnC,KAAI,CAAC,WACH,KAAI;AACF,eAAa,QAAQ,aAAa;SAC5B;AACN,QAAM,IAAI,MACR,mFACD;;AAGL,QAAO;;AAGT,SAAS,QAAQ,UAA0B;AACzC,KAAI;EACF,MAAM,OAAO,SAAS,SAAS;AAC/B,SAAO,GAAG,KAAK,QAAQ,GAAG,KAAK,QAAQ,GAAG,KAAK;SACzC;AACN,SAAO;;;AAIX,SAAS,QAAQ,UAAwC;AACvD,MAAK,MAAM,CAAC,UAAU,aAAa,SACjC,KAAI,QAAQ,SAAS,KAAK,SAAU,QAAO;AAE7C,QAAO;;AAGT,SAAS,WACP,GACA,YACA,gBACsB;CACtB,MAAM,SAAS,EAAE,iCACf,YACA,EAAE,EACF;EACE,GAAG,EAAE;EACL,SAAS,UAAU;AACjB,kBAAe,IAAI,UAAU,QAAQ,SAAS,CAAC;AAC/C,UAAO,EAAE,IAAI,SAAS,SAAS;;EAEjC,oCAAoC,YAAY;AAC9C,SAAM,IAAI,MACR,UAAU,EAAE,6BAA6B,WAAW,aAAa,KAAK,GACvE;;EAEJ,CACF;AACD,KAAI,CAAC,UAAU,OAAO,OAAO,OAC3B,OAAM,IAAI,MACR,uCAAuC,WAAW,IAAI,QAAQ,OAC3D,KAAK,MAAM,EAAE,6BAA6B,EAAE,aAAa,KAAK,CAAC,CAC/D,KAAK,KAAK,GACd;AAEH,QAAO;;AAGT,SAAS,YAAY,GAAe,YAA6B;CAC/D,MAAM,iCAAiB,IAAI,KAAqB;AAChD,QAAO;EACL,QAAQ,WAAW,GAAG,YAAY,eAAe;EACjD;EACA,0BAAU,IAAI,KAAK;EACnB,6BAAa,IAAI,KAAK;EACtB,+BAAe,IAAI,KAAK;EACzB;;AAGH,SAAS,WACP,GACA,YACA,UACA,MACY;CACZ,IAAI,UAAU,SAAS,IAAI,WAAW;CACtC,IAAI,eAAe;AACnB,KAAI,CAAC,WAAW,QAAQ,QAAQ,eAAe,CAC7C,WAAU,YAAY,GAAG,WAAW;UAEpC,QAAQ,WACR,CAAC,QAAQ,QAAQ,cAAc,SAAS,IACxC,QAAQ,cAAc,IAAI,SAAS,KAAK,QAAQ,SAAS,EACzD;EACA,MAAM,YAAY,YAAY,GAAG,WAAW;EAC5C,MAAM,gBAAgB,QAAQ,OAAO;AACrC,iBACE,UAAU,OAAO,UAAU,WAAW,cAAc,UACpD,UAAU,OAAO,UAAU,MACxB,MAAM,UAAU,SAAS,cAAc,OACzC;AACH,MAAI,aAAc,SAAQ,SAAS,UAAU;AAC7C,MAAI,CAAC,QAAQ,OAAO,UAAU,SAAS,SAAS,CAC9C,SAAQ,cAAc,IAAI,UAAU,QAAQ,SAAS,CAAC;MACnD,SAAQ,cAAc,OAAO,SAAS;;AAG7C,UAAS,OAAO,WAAW;AAC3B,UAAS,IAAI,YAAY,QAAQ;AACjC,KAAI,SAAS,OAAO,EAAG,UAAS,OAAO,SAAS,MAAM,CAAC,MAAM,CAAC,MAAO;CAErE,MAAM,iBAAiB,QAAQ,QAAQ,SAAS;CAChD,MAAM,UACJ,QAAQ,cAAc,IAAI,SAAS,IACnC,CAAC,QAAQ,SAAS,cAAc,SAAS,IACzC,CAAC,gBACD,CAAC,iBACG,SACA,EAAE,IAAI,SAAS,SAAS,KAAK,OAC3B,SACA;EAAE;EAAU;EAAM;CAC1B,MAAM,iBACJ,QAAQ,SAAS,aAAa,SAAS,YACvC,QAAQ,SAAS,SAAS,SAAS;AACrC,KAAI,CAAC,QAAQ,WAAW,gBAAgB,kBAAkB,gBAAgB;EACxE,MAAM,OAAO,EAAE,mBAAmB,QAAQ,OAAO,SAAS,KAAK;AAC/D,OAAK,wBAAwB,SAC3B,WAAW,GAAG,MAAM,QAAQ,eAAe;EAC7C,MAAM,WAAW,KAAK;AACtB,OAAK,YAAY,SACf,QAAQ,KAAK,KAAK,SAAS,WAAW,QAAQ,OAAO,SAAS,KAAK;EACrE,MAAM,gBAAgB,KAAK;AAC3B,OAAK,iBAAiB,MAAM,SAAS,SAAS,UAAU;GACtD,MAAM,MAAM,QAAQ,KAAK;GACzB,MAAM,QAAQ,QAAQ,IAAI;GAC1B,MAAM,cAAc,QAAQ,SAAS,WAAW,QAAQ,OAAO;GAC/D,MAAM,eACJ,OAAO,YAAY,WAAW,EAAE,iBAAiB,SAAS,GAAG;GAC/D,MAAM,WAAW;IACf,aAAa;IACb,aAAa;IACb,aAAa;IACd,CAAC,KAAK,IAAI;GACX,MAAM,SAAS,QAAQ,YAAY,IAAI,IAAI;AAC3C,OACE,CAAC,SACD,QAAQ,YAAY,SACpB,OAAO,gBAAgB,eACvB,OAAO,aAAa,SAEpB,QAAO,OAAO;GAChB,MAAM,SAAS,cAAc,MAAM,SAAS,SAAS,MAAM;AAC3D,OAAI,OACF,SAAQ,YAAY,IAAI,KAAK;IAC3B,SAAS;IACT;IACA;IACA;IACD,CAAC;OACC,SAAQ,YAAY,OAAO,IAAI;AACpC,UAAO;;AAET,UAAQ,UAAU,EAAE,cAAc;GAChC,WAAW,QAAQ,OAAO;GAC1B,SAAS,QAAQ,OAAO;GACxB,mBAAmB,QAAQ,OAAO;GAClC;GACA,YAAY,QAAQ;GACrB,CAAC;AACF,UAAQ,UAAU,QAAQ,QAAQ,cAAc,SAAS,GACrD,UACA;AACJ,MAAI,CAAC,QAAQ,QAAQ,cAAc,SAAS,CAC1C,SAAQ,cAAc,IAAI,UAAU,QAAQ,SAAS,CAAC;AACxD,UAAQ,WAAW,IAAI,IACrB,QAAQ,QACL,gBAAgB,CAChB,KAAK,SAAS,CAAC,KAAK,UAAU,QAAQ,KAAK,SAAS,CAAC,CAAC,CAC1D;EACD,MAAM,WAAW,IAAI,IACnB,QAAQ,QAAQ,gBAAgB,CAAC,KAAK,SAAS,QAAQ,KAAK,SAAS,CAAC,CACvE;AACD,OAAK,MAAM,QAAQ,QAAQ,YAAY,MAAM,CAC3C,KAAI,CAAC,SAAS,IAAI,KAAK,CAAE,SAAQ,YAAY,OAAO,KAAK;;AAG7D,QAAO,QAAQ;;AAGjB,SAAS,eACP,GACA,SACA,UACA,MACY;CACZ,MAAM,SAAS,QAAQ,cAAc,SAAS;AAE9C,KAAI,CAAC,UAAU,OAAO,SAAS,KAAM,cAAa;CAClD,MAAM,UAAU,QAAQ,gBAAgB;CACxC,MAAM,aAAa,EAAE,kBACnB,iBACA,UACA,QAAQ,oBAAoB,EAC5B,EAAE,IACH,CAAC,gBAAgB;CAClB,MAAM,aAAa,cAAc,QAAQ,cAAc,WAAW;CAClE,MAAM,SAAS,cAAc,QAAQ,oBAAoB,WAAW;CACpE,MAAM,UAAU,SAAS,QAAQ,mBAAmB,OAAO,GAAG,EAAE;CAChE,MAAM,mBAAmB,IAAI,IAC3B,SACI,QAAQ,MACR;EAAC;EAAU;EAAc;EAAqB,CAAC,SAAS,EAAE,KAAK,CAChE,CACA,KAAK,MACJ,EAAE,QAAQ,EAAE,YAAY,QAAQ,QAAQ,iBAAiB,EAAE,GAAG,EAC/D,CACJ;CACD,IAAI,SAAS,SAAS,MAAM,MAAM,EAAE,SAAS,SAAS;AACtD,KAAI,UAAU,OAAO,QAAQ,EAAE,YAAY,MACzC,UAAS,QAAQ,iBAAiB,OAAO;CAE3C,MAAM,SAAS,UAAU,QAAQ,wBAAwB,OAAO;AAChE,KAAI,CAAC,UAAU,OAAO,SAAS,EAAE,UAAU,MAAM,EAAE,UAAU,SAC3D,cAAa;CAEf,MAAM,oBAAoB,IAAI,IAC5B,OAAO,eAAe,CAAC,SAAS,aAAa,SAAS,gBAAgB,EAAE,CAAC,CAC1E;CAED,SAAS,mBAAmB,aAAsC;AAChE,SACE,kBAAkB,IAAI,YAAY,IAClC,2DAA2D,KACzD,YAAY,eAAe,CAAC,SAC7B;;CAGL,MAAM,6BAAa,IAAI,KAA8B;CACrD,SAAS,QAAQ,MAAqB;AACpC,MAAI,EAAE,eAAe,KAAK,CAAE,YAAW,IAAI,KAAK,SAAS,OAAO,EAAE,KAAK;AACvE,IAAE,aAAa,MAAM,QAAQ;;AAE/B,SAAQ,OAAO;CAEf,SAAS,iBACP,MACA,0BAAU,IAAI,KAAc,EAC5B,2BAAW,IAAI,KAA6B,EACnC;AACT,MAAI,QAAQ,IAAI,KAAK,CAAE,QAAO;AAC9B,UAAQ,IAAI,KAAK;AACjB,MAAI;AACF,OACE,EAAE,oBAAoB,KAAK,IAC3B,EAAE,sBAAsB,KAAK,IAC7B,EAAE,YAAY,KAAK,IACnB,EAAE,uBAAuB,KAAK,IAC9B,EAAE,iBAAiB,KAAK,IACxB,EAAE,wBAAwB,KAAK,CAE/B,QAAO,KAAK,OACR,iBAAiB,KAAK,MAAM,SAAS,SAAS,GAC9C;AACN,OAAI,EAAE,wBAAwB,KAAK,EAAE;IACnC,MAAM,SAAS,QAAQ,oBAAoB,KAAK,WAAW;IAC3D,MAAM,QAAQ,QAAQ,oBAAoB,KAAK,UAAU;IACzD,MAAM,OAAO,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,MAAM;AAEpD,WACE,WAAW,UACX,KAAK,MAAM,QAAQ;AACjB,SAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC,IAAI,iBAAiB,CAAE,QAAO;AAK7D,YAJiB,QAAQ,kBACvB,QACA,OAAO,IAAI,MAAM,CAClB,EACgB,cAAc,MAC5B,gBACC,mBAAmB,YAAY,IAC/B,iBAAiB,aAAa,SAAS,SAAS,CACnD;MACD;;AAGN,OAAI,EAAE,oBAAoB,KAAK,IAAI,EAAE,iBAAiB,KAAK,EAAE;IAC3D,MAAM,OAAO,EAAE,oBAAoB,KAAK,GACpC,KAAK,WACL,KAAK;IACT,IAAI,YAAY,QAAQ,QAAQ,oBAAoB,KAAK;AACzD,QAAI,aAAa,UAAU,QAAQ,EAAE,YAAY,MAC/C,aAAY,QAAQ,iBAAiB,UAAU;AAEjD,QAAI,aAAa,iBAAiB,IAAI,UAAU,CAAE,QAAO;AACzD,QAAI,WAAW,cAAc,KAAK,mBAAmB,CAAE,QAAO;IAC9D,MAAM,QAAQ,aAAa,SAAS,IAAI,UAAU;AAClD,QAAI,MAAO,QAAO,iBAAiB,OAAO,SAAS,SAAS;AAC5D,QACE,WAAW,cAAc,MAAM,gBAAgB;AAC7C,SAAI,CAAC,EAAE,uBAAuB,YAAY,CAAE,QAAO;KACnD,MAAM,QAAQ,IAAI,IAAI,SAAS;AAC/B,iBAAY,gBAAgB,SAAS,WAAW,UAAU;MACxD,MAAM,SAAS,QAAQ,oBAAoB,UAAU,KAAK;MAC1D,MAAM,WAAW,KAAK,gBAAgB,UAAU,UAAU;AAC1D,UAAI,UAAU,SAAU,OAAM,IAAI,QAAQ,SAAS;OACnD;AACF,YAAO,iBAAiB,YAAY,MAAM,SAAS,MAAM;MACzD,CAEF,QAAO;;AAEX,OAAI,EAAE,sBAAsB,KAAK,EAAE;IAEjC,MAAM,aAAa,WAAwB;AACzC,SAAI,CAAC,EAAE,oBAAoB,OAAO,CAAE,QAAO;KAC3C,MAAM,SAAS,QAAQ,oBAAoB,OAAO,SAAS;AAC3D,YAAO,UAAU,OAAO,QAAQ,EAAE,YAAY,gBAC1C,SACA;;IAEN,MAAM,gBAAgB,UAAU,KAAK,SAAS;IAC9C,MAAM,iBAAiB,UAAU,KAAK,UAAU;IAChD,MAAM,iBACH,iBACC,KAAK,UAAU,SAAS,EAAE,WAAW,gBACtC,kBACC,KAAK,SAAS,SAAS,EAAE,WAAW,gBACrC,iBAAiB,kBAAkB;AACtC,WACE,QAAQ,eAAe,KACtB,iBAAiB,KAAK,UAAU,SAAS,SAAS,IACjD,iBAAiB,KAAK,WAAW,SAAS,SAAS;;AAKzD,WACG,EAAE,gBAAgB,KAAK,IAAI,EAAE,uBAAuB,KAAK,KAC1D,KAAK,MAAM,MAAM,SAAS,iBAAiB,MAAM,SAAS,SAAS,CAAC;YAE9D;AACR,WAAQ,OAAO,KAAK;;;CAIxB,SAAS,WAAW,MAAwB;AAC1C,MACE,KAAK,SACJ,EAAE,UAAU,MACX,EAAE,UAAU,UACZ,EAAE,UAAU,gBACZ,EAAE,UAAU,cACZ,EAAE,UAAU,gBACZ,EAAE,UAAU,OAEd,QAAO;AACT,SAAO,KAAK,uBAAuB,IAAI,KAAK,MAAM,KAAK,WAAW;;CAGpE,SAAS,iBAAiB,MAAe,OAAwB;AAC/D,SACE,QAAQ,KAAK,QAAQ,MAAM,IAC1B,KAAK,gBAAgB,IACpB,KAAK,MAAM,MAAM,SAAS,iBAAiB,MAAM,MAAM,CAAC;;CAI9D,SAAS,wBACP,MACA,MACS;EACT,MAAM,MAAM,KAAK,OAAO,OAAO;EAC/B,MAAM,YAAY,QAAQ,kBAAkB,IAAI;AAChD,SAAO,CACL,GAAG,UAAU,mBAAmB,EAChC,GAAG,UAAU,wBAAwB,CACtC,CAAC,MAAM,cAAc;GACpB,MAAM,YAAY,UAAU,WAAW;AACvC,OAAI,CAAC,UAAW,QAAO;GACvB,MAAM,QAAQ,QAAQ,0BAA0B,WAAW,IAAI;GAC/D,MAAM,WAAW,QAAQ,kBAAkB,OAAO,KAAK;AACvD,UAAO,WACH,WAAW,QAAQ,0BAA0B,UAAU,IAAI,CAAC,GAC5D;IACJ;;CAGJ,MAAM,0BAAU,IAAI,KAAuB;AAC3C,SAAQ,cAAc;EACpB,MAAM,QAAQ,UAAU,MAAM;EAC9B,MAAM,SAAS,QAAQ,IAAI,MAAM;AACjC,MAAI,OAAQ,QAAO;EACnB,MAAM,OAAO,WAAW,IAAI,MAAM;EAClC,IAAI,OAAiB;AACrB,MAAI,QAAQ,KAAK,QAAQ,UAAU,MAAM,MAAM,EAAE,aAAa,KAAK,KAAK,EAAE;GACxE,MAAM,QAAQ,QAAQ,kBAAkB,KAAK,OAAO;GACpD,MAAM,WACJ,SAAS,QAAQ,kBAAkB,OAAO,KAAK,KAAK,KAAK;GAC3D,MAAM,eAAe,UAAU;AAC/B,OAAI,YAAY,cAAc,QAAQ;IACpC,MAAM,OAAO,QAAQ,0BAA0B,UAAU,KAAK;AAC9D,QACE,aAAa,MAAM,MAAM,mBAAmB,EAAE,IAAI,iBAAiB,EAAE,CAAC,CAEtE,QAAO;aAEP,CAAC,WAAW,KAAK,IACjB,EACE,aAAa,MAAM,gBACjB,WAAW,QAAQ,kBAAkB,YAAY,CAAC,CACnD,IAAI,wBAAwB,MAAM,KAAK,KAAK,KAAK,GAEpD;KAEA,MAAM,cAAc,QAAQ,mBAAmB,KAAK;KACpD,MAAM,QAAQ,YAAY,SAAS,GAC/B,YAAY,QACZ,CAAC,YAAY;KACjB,MAAM,YACJ,EAAE,UAAU,aACZ,EAAE,UAAU,aACZ,EAAE,UAAU,cACZ,EAAE,UAAU;KACd,MAAM,QACJ,EAAE,UAAU,SACZ,EAAE,UAAU,SACZ,EAAE,UAAU,UACZ,EAAE,UAAU;AAQd,SAAI,EANF,MAAM,OAAO,SAAS,iBAAiB,MAAM,UAAU,CAAC,KACvD,QAAQ,YAAY,QAAQ,MAAM,IACjC,MAAM,MAAM,SAAS,iBAAiB,MAAM,MAAM,CAAC,IACnD,MAAM,OAAO,SACX,iBAAiB,MAAM,EAAE,UAAU,YAAY,CAChD,GACgB,QAAO;;;;AAIlC,UAAQ,IAAI,OAAO,KAAK;AACxB,SAAO;;;;AAKX,SAAgB,YACd,SACA,WACU;CAIV,MAAM,SAHW,QAAQ,SAAS,OAGT;AACzB,KAAI,WAAW,UAAa,WAAW,MAAO,QAAO;AACrD,KACE,WAAW,SACV,CAAC,UACA,OAAO,WAAW,YAClB,MAAM,QAAQ,OAAO,IACpB,OAAO,YAAY,UAAa,OAAO,OAAO,YAAY,UAE7D,OAAM,IAAI,MACR,mEACD;CAEH,MAAM,WAAW,QAAQ,QAAQ,KAAK,QAAQ,SAAS;CACvD,MAAM,WAAW,WAAW,OAAO,SAAY,OAAO;CACtD,MAAM,aAAa,QAAQ;CAC3B,MAAM,MAAM,WAAW,QAAQ,QAAQ,KAAK,SAAS,GAAG;CACxD,IAAI,YAAY,YAAY,IAAI,WAAW;AAC3C,KAAI,CAAC,WAAW;AACd,8BAAY,IAAI,KAAK;AACrB,cAAY,IAAI,YAAY,UAAU;;CAExC,IAAI,SAAS,UAAU,IAAI,IAAI;AAC/B,KACE,CAAC,UACD,OAAO,aAAa,YACpB,OAAO,SAAS,WAAW,MAC3B;EACA,MAAM,IAAI,eAAe;EACzB,MAAM,aAAa,WACf,MACA,EAAE,eAAe,QAAQ,SAAS,EAAE,EAAE,IAAI,WAAW;AACzD,MAAI,CAAC,WACH,OAAM,IAAI,MACR,qDAAqD,SAAS,GAC/D;EACH,MAAM,UAAU,WAAW,GAAG,YAAY,UAAU,WAAW,KAAK;AACpE,WAAS;GACP;GACA,MAAM,WAAW;GACjB,UAAU,eAAe,GAAG,SAAS,UAAU,WAAW,KAAK;GAChE;AACD,YAAU,IAAI,KAAK,OAAO;;AAE5B,QAAO,OAAO,SAAS,UAAU;;;AAInC,SAAgB,kBACd,SACM;AACN,aAAY,OAAO,QAAQ,WAAW"}
|
|
1
|
+
{"version":3,"file":"type-aware-jsx.js","names":[],"sources":["../src/type-aware-jsx.ts"],"sourcesContent":["import { statSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, resolve } from 'node:path';\nimport type ts from 'typescript';\nimport type { TSESTree } from '@typescript-eslint/utils';\nimport type { RuleContext } from '@typescript-eslint/utils/ts-eslint';\n\n/** Experimental, independently managed TypeScript analysis for either linter. */\nexport interface TypeAwareJSXOptions {\n /** tsconfig path relative to the linter's cwd; otherwise find the nearest one. */\n project?: string;\n}\n\ntype PropKind = 'style' | 'component' | 'unknown';\ntype TypeScript = typeof ts;\ntype Classifier = (attribute: TSESTree.JSXAttribute) => PropKind;\n\ninterface Project {\n config: ts.ParsedCommandLine;\n configVersions: Map<string, string>;\n program?: ts.Program;\n versions: Map<string, string>;\n overlay?: { filename: string; text: string };\n sourceFiles: Map<\n string,\n {\n version: string;\n overlayText?: string;\n parseKey: string;\n source: ts.SourceFile;\n }\n >;\n excludedFiles: Map<string, string>;\n}\n\nconst require = createRequire(import.meta.url);\nlet typescript: TypeScript | undefined;\nconst projects = new Map<string, Project>();\n// All value rules share one classifier for a file, including in Oxlint.\nconst classifiers = new WeakMap<\n object,\n Map<\n string,\n {\n filename: string;\n text: string;\n classify: Classifier;\n }\n >\n>();\n\nfunction getTypeScript(): TypeScript {\n if (!typescript) {\n let module: Partial<TypeScript>;\n try {\n module = require('typescript') as Partial<TypeScript>;\n } catch {\n throw new Error(\n 'tasty: typeAwareJSX requires TypeScript. Install typescript as a dev dependency.',\n );\n }\n // TypeScript 7 (the native port) exports only its version from the main entry.\n if (typeof module.createProgram !== 'function') {\n throw new Error(\n `tasty: typeAwareJSX requires the TypeScript compiler API, which ${\n module.version\n ? `typescript ${module.version}`\n : 'the installed typescript'\n } does not provide. Install TypeScript 5.6–6.x as a dev dependency.`,\n );\n }\n typescript = module as TypeScript;\n }\n return typescript;\n}\n\nfunction version(filename: string): string {\n try {\n const stat = statSync(filename);\n return `${stat.mtimeMs}:${stat.ctimeMs}:${stat.size}`;\n } catch {\n return 'missing';\n }\n}\n\nfunction changed(versions: Map<string, string>): boolean {\n for (const [filename, previous] of versions) {\n if (version(filename) !== previous) return true;\n }\n return false;\n}\n\nfunction readConfig(\n T: TypeScript,\n configPath: string,\n configVersions: Map<string, string>,\n): ts.ParsedCommandLine {\n const config = T.getParsedCommandLineOfConfigFile(\n configPath,\n {},\n {\n ...T.sys,\n readFile(filename) {\n configVersions.set(filename, version(filename));\n return T.sys.readFile(filename);\n },\n onUnRecoverableConfigFileDiagnostic(diagnostic) {\n throw new Error(\n `tasty: ${T.flattenDiagnosticMessageText(diagnostic.messageText, '\\n')}`,\n );\n },\n },\n );\n if (!config || config.errors.length) {\n throw new Error(\n `tasty: invalid typeAwareJSX project ${configPath}: ${config?.errors\n .map((d) => T.flattenDiagnosticMessageText(d.messageText, '\\n'))\n .join('\\n')}`,\n );\n }\n return config;\n}\n\nfunction readProject(T: TypeScript, configPath: string): Project {\n const configVersions = new Map<string, string>();\n return {\n config: readConfig(T, configPath, configVersions),\n configVersions,\n versions: new Map(),\n sourceFiles: new Map(),\n excludedFiles: new Map(),\n };\n}\n\nfunction getProgram(\n T: TypeScript,\n configPath: string,\n filename: string,\n text: string,\n): ts.Program {\n let project = projects.get(configPath);\n let rootsChanged = false;\n if (!project || changed(project.configVersions)) {\n project = readProject(T, configPath);\n } else if (\n project.program &&\n !project.program.getSourceFile(filename) &&\n project.excludedFiles.get(filename) !== version(filename)\n ) {\n const refreshed = readProject(T, configPath);\n const previousFiles = project.config.fileNames;\n rootsChanged =\n refreshed.config.fileNames.length !== previousFiles.length ||\n refreshed.config.fileNames.some(\n (file, index) => file !== previousFiles[index],\n );\n if (rootsChanged) project.config = refreshed.config;\n if (!project.config.fileNames.includes(filename))\n project.excludedFiles.set(filename, version(filename));\n else project.excludedFiles.delete(filename);\n }\n // Bound retained compiler graphs in long-lived editor processes.\n projects.delete(configPath);\n projects.set(configPath, project);\n if (projects.size > 3) projects.delete(projects.keys().next().value!);\n\n const sourcesChanged = changed(project.versions);\n const overlay =\n project.excludedFiles.has(filename) &&\n !project.program?.getSourceFile(filename) &&\n !rootsChanged &&\n !sourcesChanged\n ? undefined\n : T.sys.readFile(filename) === text\n ? undefined\n : { filename, text };\n const overlayChanged =\n project.overlay?.filename !== overlay?.filename ||\n project.overlay?.text !== overlay?.text;\n if (!project.program || rootsChanged || overlayChanged || sourcesChanged) {\n const host = T.createCompilerHost(project.config.options, true);\n host.getParsedCommandLine = (path) =>\n readConfig(T, path, project.configVersions);\n const readFile = host.readFile;\n host.readFile = (path) =>\n resolve(path) === overlay?.filename ? overlay.text : readFile(path);\n const getSourceFile = host.getSourceFile;\n host.getSourceFile = (path, options, onError, force) => {\n const key = resolve(path);\n const stamp = version(key);\n const overlayText = key === overlay?.filename ? overlay.text : undefined;\n const parseOptions =\n typeof options === 'number' ? { languageVersion: options } : options;\n const parseKey = [\n parseOptions.languageVersion,\n parseOptions.impliedNodeFormat,\n parseOptions.jsDocParsingMode,\n ].join(':');\n const cached = project.sourceFiles.get(key);\n if (\n !force &&\n cached?.version === stamp &&\n cached.overlayText === overlayText &&\n cached.parseKey === parseKey\n )\n return cached.source;\n const source = getSourceFile(path, options, onError, force);\n if (source)\n project.sourceFiles.set(key, {\n version: stamp,\n overlayText,\n parseKey,\n source,\n });\n else project.sourceFiles.delete(key);\n return source;\n };\n project.program = T.createProgram({\n rootNames: project.config.fileNames,\n options: project.config.options,\n projectReferences: project.config.projectReferences,\n host,\n oldProgram: project.program,\n });\n project.overlay = project.program.getSourceFile(filename)\n ? overlay\n : undefined;\n if (!project.program.getSourceFile(filename))\n project.excludedFiles.set(filename, version(filename));\n project.versions = new Map(\n project.program\n .getSourceFiles()\n .map((file) => [file.fileName, version(file.fileName)]),\n );\n const retained = new Set(\n project.program.getSourceFiles().map((file) => resolve(file.fileName)),\n );\n for (const path of project.sourceFiles.keys()) {\n if (!retained.has(path)) project.sourceFiles.delete(path);\n }\n }\n return project.program;\n}\n\nfunction makeClassifier(\n T: TypeScript,\n program: ts.Program,\n filename: string,\n text: string,\n): Classifier {\n const source = program.getSourceFile(filename);\n // Excluded files and virtual/transformed source keep the existing heuristic.\n if (!source || source.text !== text) return () => 'unknown';\n const checker = program.getTypeChecker();\n const modulePath = T.resolveModuleName(\n '@tenphi/tasty',\n filename,\n program.getCompilerOptions(),\n T.sys,\n ).resolvedModule?.resolvedFileName;\n const moduleFile = modulePath && program.getSourceFile(modulePath);\n const module = moduleFile && checker.getSymbolAtLocation(moduleFile);\n const exports = module ? checker.getExportsOfModule(module) : [];\n const styleTypeSymbols = new Set(\n exports\n ?.filter((s) =>\n ['Styles', 'StyleValue', 'StyleValueStateMap'].includes(s.name),\n )\n .map((s) =>\n s.flags & T.SymbolFlags.Alias ? checker.getAliasedSymbol(s) : s,\n ),\n );\n let symbol = exports?.find((s) => s.name === 'Styles');\n if (symbol && symbol.flags & T.SymbolFlags.Alias) {\n symbol = checker.getAliasedSymbol(symbol);\n }\n const styles = symbol && checker.getDeclaredTypeOfSymbol(symbol);\n if (!styles || styles.flags & (T.TypeFlags.Any | T.TypeFlags.Unknown)) {\n return () => 'unknown';\n }\n const styleDeclarations = new Set(\n styles.getProperties().flatMap((property) => property.declarations ?? []),\n );\n // A dependency may resolve a different copy of either styling package.\n function isStyleDeclaration(declaration: ts.Declaration): boolean {\n return (\n styleDeclarations.has(declaration) ||\n /[/\\\\]node_modules[/\\\\](?:@tenphi[/\\\\]tasty|csstype)[/\\\\]/.test(\n declaration.getSourceFile().fileName,\n )\n );\n }\n const attributes = new Map<number, ts.JsxAttribute>();\n function collect(node: ts.Node): void {\n if (T.isJsxAttribute(node)) attributes.set(node.getStart(source), node);\n T.forEachChild(node, collect);\n }\n collect(source);\n\n function referencesStyles(\n node: ts.Node,\n visited = new Set<ts.Node>(),\n bindings = new Map<ts.Symbol, ts.TypeNode>(),\n ): boolean {\n if (visited.has(node)) return false;\n visited.add(node);\n try {\n if (\n T.isPropertySignature(node) ||\n T.isPropertyDeclaration(node) ||\n T.isParameter(node) ||\n T.isTypeAliasDeclaration(node) ||\n T.isMappedTypeNode(node) ||\n T.isParenthesizedTypeNode(node)\n )\n return node.type\n ? referencesStyles(node.type, visited, bindings)\n : false;\n if (T.isIndexedAccessTypeNode(node)) {\n const object = checker.getTypeFromTypeNode(node.objectType);\n const index = checker.getTypeFromTypeNode(node.indexType);\n const keys = index.isUnion() ? index.types : [index];\n // Trace the selected property, not unrelated style props on the object.\n return (\n object === styles ||\n keys.some((key) => {\n if (!key.isStringLiteral() && !key.isNumberLiteral()) return false;\n const property = checker.getPropertyOfType(\n object,\n String(key.value),\n );\n return property?.declarations?.some(\n (declaration) =>\n isStyleDeclaration(declaration) ||\n referencesStyles(declaration, visited, bindings),\n );\n })\n );\n }\n if (T.isTypeReferenceNode(node) || T.isImportTypeNode(node)) {\n const name = T.isTypeReferenceNode(node)\n ? node.typeName\n : node.qualifier;\n let reference = name && checker.getSymbolAtLocation(name);\n if (reference && reference.flags & T.SymbolFlags.Alias) {\n reference = checker.getAliasedSymbol(reference);\n }\n if (reference && styleTypeSymbols.has(reference)) return true;\n if (reference?.declarations?.some(isStyleDeclaration)) return true;\n const bound = reference && bindings.get(reference);\n if (bound) return referencesStyles(bound, visited, bindings);\n if (\n reference?.declarations?.some((declaration) => {\n if (!T.isTypeAliasDeclaration(declaration)) return false;\n const local = new Map(bindings);\n declaration.typeParameters?.forEach((parameter, index) => {\n const symbol = checker.getSymbolAtLocation(parameter.name);\n const argument = node.typeArguments?.[index] ?? parameter.default;\n if (symbol && argument) local.set(symbol, argument);\n });\n return referencesStyles(declaration.type, visited, local);\n })\n )\n return true;\n }\n if (T.isConditionalTypeNode(node)) {\n // Extract/Exclude-style filters preserve an input value or return never.\n const parameter = (branch: ts.TypeNode) => {\n if (!T.isTypeReferenceNode(branch)) return undefined;\n const symbol = checker.getSymbolAtLocation(branch.typeName);\n return symbol && symbol.flags & T.SymbolFlags.TypeParameter\n ? symbol\n : undefined;\n };\n const trueParameter = parameter(node.trueType);\n const falseParameter = parameter(node.falseType);\n const preservesValue =\n (trueParameter &&\n node.falseType.kind === T.SyntaxKind.NeverKeyword) ||\n (falseParameter &&\n node.trueType.kind === T.SyntaxKind.NeverKeyword) ||\n (trueParameter && trueParameter === falseParameter);\n return (\n Boolean(preservesValue) &&\n (referencesStyles(node.trueType, visited, bindings) ||\n referencesStyles(node.falseType, visited, bindings))\n );\n }\n // Nested fields, function arguments and conditional constraints are content,\n // not evidence that the prop's value itself originates in a style type.\n return (\n (T.isUnionTypeNode(node) || T.isIntersectionTypeNode(node)) &&\n node.types.some((part) => referencesStyles(part, visited, bindings))\n );\n } finally {\n visited.delete(node);\n }\n }\n\n function unresolved(type: ts.Type): boolean {\n if (\n type.flags &\n (T.TypeFlags.Any |\n T.TypeFlags.Unknown |\n T.TypeFlags.TypeParameter |\n T.TypeFlags.Conditional |\n T.TypeFlags.IndexedAccess |\n T.TypeFlags.Never)\n )\n return true;\n return type.isUnionOrIntersection() && type.types.some(unresolved);\n }\n\n function hasPrimitiveFlag(type: ts.Type, flags: number): boolean {\n return (\n Boolean(type.flags & flags) ||\n (type.isIntersection() &&\n type.types.some((part) => hasPrimitiveFlag(part, flags)))\n );\n }\n\n function unresolvedComponentProp(\n node: ts.JsxAttribute,\n name: string,\n ): boolean {\n const tag = node.parent.parent.tagName;\n const component = checker.getTypeAtLocation(tag);\n return [\n ...component.getCallSignatures(),\n ...component.getConstructSignatures(),\n ].some((signature) => {\n const parameter = signature.parameters[0];\n if (!parameter) return false;\n const props = checker.getTypeOfSymbolAtLocation(parameter, tag);\n const property = checker.getPropertyOfType(props, name);\n return property\n ? unresolved(checker.getTypeOfSymbolAtLocation(property, tag))\n : false;\n });\n }\n\n const results = new Map<number, PropKind>();\n return (attribute) => {\n const start = attribute.range[0];\n const cached = results.get(start);\n if (cached) return cached;\n const node = attributes.get(start);\n let kind: PropKind = 'unknown';\n if (node && node.end === attribute.range[1] && T.isIdentifier(node.name)) {\n const props = checker.getContextualType(node.parent);\n const property =\n props && checker.getPropertyOfType(props, node.name.text);\n const declarations = property?.declarations;\n if (property && declarations?.length) {\n const type = checker.getTypeOfSymbolAtLocation(property, node);\n if (\n declarations.some((d) => isStyleDeclaration(d) || referencesStyles(d))\n ) {\n kind = 'style';\n } else if (\n !unresolved(type) &&\n !(\n declarations.some((declaration) =>\n unresolved(checker.getTypeAtLocation(declaration)),\n ) && unresolvedComponentProp(node, node.name.text)\n )\n ) {\n // Broad primitives may be hand-written style props. Preserve checks.\n const nonNullable = checker.getNonNullableType(type);\n const parts = nonNullable.isUnion()\n ? nonNullable.types\n : [nonNullable];\n const primitive =\n T.TypeFlags.StringLike |\n T.TypeFlags.NumberLike |\n T.TypeFlags.BooleanLike |\n T.TypeFlags.BigIntLike;\n const broad =\n T.TypeFlags.String |\n T.TypeFlags.Number |\n T.TypeFlags.Boolean |\n T.TypeFlags.BigInt;\n const broadPrimitive =\n parts.every((part) => hasPrimitiveFlag(part, primitive)) &&\n (Boolean(nonNullable.flags & broad) ||\n parts.some((part) => hasPrimitiveFlag(part, broad)) ||\n parts.every((part) =>\n hasPrimitiveFlag(part, T.TypeFlags.BooleanLike),\n ));\n if (!broadPrimitive) kind = 'component';\n }\n }\n }\n results.set(start, kind);\n return kind;\n };\n}\n\n/** No compiler is loaded, or program created, unless the setting is enabled. */\nexport function jsxPropKind(\n context: RuleContext<string, unknown[]>,\n attribute: TSESTree.JSXAttribute,\n): PropKind {\n const settings = context.settings.tasty as\n | { typeAwareJSX?: boolean | TypeAwareJSXOptions }\n | undefined;\n const option = settings?.typeAwareJSX;\n if (option === undefined || option === false) return 'unknown';\n if (\n option !== true &&\n (!option ||\n typeof option !== 'object' ||\n Array.isArray(option) ||\n (option.project !== undefined && typeof option.project !== 'string'))\n )\n throw new Error(\n 'tasty: typeAwareJSX must be true, false, or { project: string }.',\n );\n\n const filename = resolve(context.cwd, context.filename);\n const explicit = option === true ? undefined : option.project;\n const sourceCode = context.sourceCode;\n const key = explicit ? resolve(context.cwd, explicit) : 'nearest';\n let byProject = classifiers.get(sourceCode);\n if (!byProject) {\n byProject = new Map();\n classifiers.set(sourceCode, byProject);\n }\n let cached = byProject.get(key);\n if (\n !cached ||\n cached.filename !== filename ||\n cached.text !== sourceCode.text\n ) {\n const T = getTypeScript();\n const configPath = explicit\n ? key\n : T.findConfigFile(dirname(filename), T.sys.fileExists);\n if (!configPath)\n throw new Error(\n `tasty: typeAwareJSX could not find a tsconfig for ${filename}.`,\n );\n const program = getProgram(T, configPath, filename, sourceCode.text);\n cached = {\n filename,\n text: sourceCode.text,\n classify: makeClassifier(T, program, filename, sourceCode.text),\n };\n byProject.set(key, cached);\n }\n return cached.classify(attribute);\n}\n\n/** A SourceCode object may be reused by ESLint after dependencies change. */\nexport function finishJSXAnalysis(\n context: RuleContext<string, unknown[]>,\n): void {\n classifiers.delete(context.sourceCode);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tenphi/eslint-plugin-tasty",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "ESLint plugin for validating tasty() and tastyStatic() style objects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@tenphi/tasty": ">=3.8.0",
|
|
43
43
|
"eslint": ">=8.0.0",
|
|
44
|
-
"typescript": ">=5.6.3 <
|
|
44
|
+
"typescript": ">=5.6.3 <7"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@typescript-eslint/utils": "^8.56.0",
|