@trackunit/iris-app 2.5.12 → 2.5.14
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/CHANGELOG.md +17 -0
- package/migrations/entry.js.map +1 -0
- package/migrations/p-content-space-codemod/invent-content-space.js +277 -0
- package/migrations/p-content-space-codemod/invent-content-space.js.map +1 -0
- package/migrations/p-content-space-codemod/orchestrator.js +140 -0
- package/migrations/p-content-space-codemod/orchestrator.js.map +1 -0
- package/migrations/p-content-space-codemod/remove-redundant-padding.js +37 -0
- package/migrations/p-content-space-codemod/remove-redundant-padding.js.map +1 -0
- package/migrations/p-content-space-codemod/report-run-messaging.js +73 -0
- package/migrations/p-content-space-codemod/report-run-messaging.js.map +1 -0
- package/migrations/p-content-space-codemod/report-unresolved.js +87 -0
- package/migrations/p-content-space-codemod/report-unresolved.js.map +1 -0
- package/migrations/p-content-space-codemod/resolve-content-shell.js +968 -0
- package/migrations/p-content-space-codemod/resolve-content-shell.js.map +1 -0
- package/migrations/p-content-space-codemod/rewrite-page-content.js +42 -0
- package/migrations/p-content-space-codemod/rewrite-page-content.js.map +1 -0
- package/migrations/p-content-space-codemod/shell-skip-reason.js +41 -0
- package/migrations/p-content-space-codemod/shell-skip-reason.js.map +1 -0
- package/migrations/utils/classname-ast-rewrite.js +220 -0
- package/migrations/utils/classname-ast-rewrite.js.map +1 -0
- package/migrations/utils/resolve-extension-types.js +208 -0
- package/migrations/utils/resolve-extension-types.js.map +1 -0
- package/migrations.json +7 -1
- package/package.json +8 -6
- package/src/executors/submit/executor.js.map +1 -0
- package/src/executors/unpublish/executor.js.map +1 -0
- package/src/executors/utils/authentication.js.map +1 -0
- package/src/executors/utils/irisAppServerSettings.js.map +1 -0
- package/src/executors/utils/src/index.js.map +1 -0
- package/src/generators/ai-agent-sync/generator.js.map +1 -0
- package/src/generators/create/generator.js.map +1 -0
- package/src/generators/extend/dependencies.js.map +1 -0
- package/src/generators/extend/generator.js.map +1 -0
- package/src/generators/preset/generator.js.map +1 -0
- package/src/generators/utils/get-package-manifest.js.map +1 -0
- package/src/generators/utils/link-claude-skills.js.map +1 -0
- package/src/index.js.map +1 -0
- package/src/utils/ast/astUtils.js.map +1 -0
- package/src/utils/fileUpdater.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-content-shell.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app/migrations/p-content-space-codemod/resolve-content-shell.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Tree } from \"@nx/devkit\";\nimport { isTailwindFunction, splitClasses, type ClassnameLocation } from \"@trackunit/css-classname-utils\";\nimport { AST_NODE_TYPES, type TSESTree } from \"@typescript-eslint/types\";\nimport { simpleTraverse } from \"@typescript-eslint/typescript-estree\";\nimport path from \"path\";\nimport { findClassnameLocations, parseTsestreeSource } from \"../utils/classname-ast-rewrite\";\nimport type { ResolvedExtension } from \"../utils/resolve-extension-types\";\nimport { shellSkipReason, type ShellSkipReason, type ShellSkipReasonCode } from \"./shell-skip-reason\";\n\n/**\n * A high-confidence content-region classname host discovered under an\n * extension entry (literal / cva / cn on a div-like shell).\n */\nexport type ResolvedContentShell = {\n readonly filePath: string;\n /** Current classname string at the editable host. */\n readonly classnameValue: string;\n /**\n * Every classname bound to the same host, joined. A cva/cn call can split\n * tokens across arguments (`cvaMerge([\"p-content-space\", \"overflow-auto\"])`);\n * leftover reporting must look at this combined value, not `classnameValue`\n * alone, or it disagrees with invent.\n */\n readonly combinedClassnameValue: string;\n /** AST classname location invent uses to splice the edit. */\n readonly location: ClassnameLocation;\n};\n\nexport type ResolveContentShellResult =\n | { readonly status: \"resolved\"; readonly shell: ResolvedContentShell }\n | { readonly status: \"unresolved\"; readonly reason: ShellSkipReason };\n\n/**\n * Plural discovery result. Multi-route ASA apps may yield 0..N shells:\n * - shared layout content `div` wrapping `<Outlet />` → that layout's shell\n * - no shared layout → one shell per clear route leaf (static imports only)\n * - layout-wins is scoped to that layout's descendant leaves only\n * - unclear / unanalysable routes are named in `skippedRouteNames` when any\n * sibling still resolved (a partial graph must not look fully migrated)\n * - unclear graphs with no resolvable shells → unresolved (never guess a first-div)\n */\nexport type ResolveContentShellsResult =\n | {\n readonly status: \"resolved\";\n readonly shells: ReadonlyArray<ResolvedContentShell>;\n readonly skippedRouteNames: ReadonlyArray<string>;\n }\n | { readonly status: \"unresolved\"; readonly reason: ShellSkipReason };\n\nconst DEFAULT_ENTRY_COMPONENT_FILE = \"index.tsx\";\n\nconst unresolvedShell = (code: ShellSkipReasonCode, detail?: string): ResolveContentShellResult => ({\n status: \"unresolved\",\n reason: shellSkipReason(code, detail),\n});\n\nconst unresolvedShells = (code: ShellSkipReasonCode, detail?: string): ResolveContentShellsResult => ({\n status: \"unresolved\",\n reason: shellSkipReason(code, detail),\n});\n\n/** Intrinsic hosts treated as content-region shells for this walking skeleton. */\nconst DIV_LIKE_ELEMENTS: ReadonlySet<string> = new Set([\"div\", \"main\", \"section\"]);\n\n/**\n * Known non-DOM wrappers to skip when walking from an extension entry toward\n * the content shell (providers, Suspense, fragments).\n * `RouterProvider` is intentionally NOT a wrapper — it branches into light-touch\n * multi-route discovery instead of being skipped.\n */\nconst isKnownWrapperName = (name: string): boolean => {\n if (\n name === \"Suspense\" ||\n name === \"Fragment\" ||\n name === \"TrackunitInternalProviders\" ||\n name === \"TrackunitProviders\"\n ) {\n return true;\n }\n return name.endsWith(\"Provider\") && name !== \"RouterProvider\";\n};\n\n/**\n * Walks from `extension.main` through known non-DOM wrappers and static\n * imports to identify editable content-region classname host(s).\n *\n * Multi-route policy (light-touch, static imports only):\n * 1. Shared layout shell (div-like host wrapping `<Outlet />`) wins → one target.\n * 2. Else each resolvable route leaf with a clear shell is targeted.\n * 3. Exotic / unclear graphs → `{ status: \"unresolved\" }` (never throws; no first-div guess).\n */\nexport const resolveContentShells = (tree: Tree, extension: ResolvedExtension): ResolveContentShellsResult => {\n const entryPath = `${extension.sourceRoot}/${extension.main ?? DEFAULT_ENTRY_COMPONENT_FILE}`;\n if (!tree.exists(entryPath)) {\n return unresolvedShells(\"entry-missing\", entryPath);\n }\n\n return resolveShellsFromFile(tree, entryPath, extension.sourceRoot, new Set());\n};\n\n/**\n * Single-shell convenience wrapper over {@link resolveContentShells}.\n * Returns the first resolved shell when discovery finds one or more; unresolved\n * when none. Prefer {@link resolveContentShells} for RouterProvider / multi-route\n * graphs — an arbitrary one of N leaves is not a useful production answer.\n */\nexport const resolveContentShell = (tree: Tree, extension: ResolvedExtension): ResolveContentShellResult => {\n const result = resolveContentShells(tree, extension);\n if (result.status === \"unresolved\") {\n return { status: \"unresolved\", reason: result.reason };\n }\n const shell = result.shells[0];\n if (shell === undefined) {\n return unresolvedShell(\"unclear-graph\", \"resolved status with empty shells list\");\n }\n return { status: \"resolved\", shell };\n};\n\nconst resolveShellsFromFile = (\n tree: Tree,\n filePath: string,\n sourceRoot: string,\n visited: Set<string>\n): ResolveContentShellsResult => {\n if (visited.has(filePath)) {\n return unresolvedShells(\"cycle\", filePath);\n }\n visited.add(filePath);\n\n const content = tree.read(filePath, \"utf-8\");\n if (content === null) {\n return unresolvedShells(\"entry-missing\", filePath);\n }\n\n let program: TSESTree.Program;\n try {\n program = parseTsestreeSource(content);\n } catch {\n return unresolvedShells(\"parse-failed\", filePath);\n }\n\n const rootJsx = findRootJsxElement(program);\n if (rootJsx === null) {\n return unresolvedShells(\"no-root-jsx\", filePath);\n }\n\n const leaf = unwrapWrappers(rootJsx);\n if (leaf === null) {\n return unresolvedShells(\"empty-wrapper\", filePath);\n }\n\n if (isDivLikeHost(leaf) && leaf.type === AST_NODE_TYPES.JSXElement) {\n const single = pickContentShellInFile(filePath, program, leaf);\n if (single.status === \"unresolved\") {\n return { status: \"unresolved\", reason: single.reason };\n }\n return { status: \"resolved\", shells: [single.shell], skippedRouteNames: [] };\n }\n\n const componentName = getJsxComponentName(leaf);\n if (componentName === null) {\n return unresolvedShells(\"non-host-element\", filePath);\n }\n\n if (componentName === \"RouterProvider\" && leaf.type === AST_NODE_TYPES.JSXElement) {\n return resolveFromRouterProvider(tree, filePath, program, leaf, sourceRoot, visited);\n }\n\n if (isDynamicComponent(program, componentName)) {\n return unresolvedShells(\"dynamic-component\", componentName);\n }\n\n const importPath = resolveStaticLocalImport(tree, program, filePath, sourceRoot, componentName);\n if (importPath === null) {\n return unresolvedShells(\"unresolvable-import\", componentName);\n }\n\n return resolveShellsFromFile(tree, importPath, sourceRoot, visited);\n};\n\n/**\n * Light-touch RouterProvider follow: read `router={name}`, resolve the router\n * module (import or same-file), collect Identifier `component:` targets from\n * `createRootRoute` / `createRoute` / `createRootRouteWithContext`. Skip arrow\n * wrappers and exotic graphs rather than guessing.\n */\nconst resolveFromRouterProvider = (\n tree: Tree,\n filePath: string,\n program: TSESTree.Program,\n routerProvider: TSESTree.JSXElement,\n sourceRoot: string,\n visited: Set<string>\n): ResolveContentShellsResult => {\n const routerName = getRouterPropIdentifier(routerProvider);\n if (routerName === null) {\n return unresolvedShells(\"router-prop-unresolved\");\n }\n\n const routerModulePath = resolveStaticLocalImport(tree, program, filePath, sourceRoot, routerName);\n if (routerModulePath !== null) {\n return collectShellsFromRouterModule(tree, routerModulePath, sourceRoot, visited);\n }\n\n // Same-file router (route factories live alongside RouterProvider).\n return collectShellsFromRouterProgram(tree, filePath, program, sourceRoot, visited);\n};\n\nconst collectShellsFromRouterModule = (\n tree: Tree,\n routerModulePath: string,\n sourceRoot: string,\n visited: Set<string>\n): ResolveContentShellsResult => {\n if (visited.has(routerModulePath)) {\n return unresolvedShells(\"cycle\", routerModulePath);\n }\n visited.add(routerModulePath);\n\n const content = tree.read(routerModulePath, \"utf-8\");\n if (content === null) {\n return unresolvedShells(\"entry-missing\", routerModulePath);\n }\n\n let program: TSESTree.Program;\n try {\n program = parseTsestreeSource(content);\n } catch {\n return unresolvedShells(\"parse-failed\", routerModulePath);\n }\n\n return collectShellsFromRouterProgram(tree, routerModulePath, program, sourceRoot, visited);\n};\n\ntype RouterRoute = {\n readonly variableName: string | null;\n readonly componentName: string | null;\n readonly parentVariableName: string | null;\n};\n\ntype AnalyzedRoute = RouterRoute & {\n readonly analysis: RouteComponentAnalysis | null;\n};\n\nconst collectShellsFromRouterProgram = (\n tree: Tree,\n routerFilePath: string,\n program: TSESTree.Program,\n sourceRoot: string,\n visited: Set<string>\n): ResolveContentShellsResult => {\n const routes = collectRouterRoutes(program);\n if (routes.length === 0) {\n return unresolvedShells(\"router-no-analysable-leaves\", \"no createRoute/createRootRoute factories found\");\n }\n\n if (routes.every(route => route.componentName === null)) {\n return unresolvedShells(\"router-inline-arrow-components\", routerFilePath);\n }\n\n const definedVariableNames = new Set(\n routes.flatMap(route => (route.variableName === null ? [] : [route.variableName]))\n );\n const skippedRouteNames: Array<string> = collectAddChildrenIdentifiers(program).filter(\n name => !definedVariableNames.has(name)\n );\n\n const analyzed: Array<AnalyzedRoute> = [];\n for (const route of routes) {\n if (route.componentName === null) {\n analyzed.push({ ...route, analysis: null });\n continue;\n }\n\n const componentFile = resolveComponentModulePath(tree, program, routerFilePath, sourceRoot, route.componentName);\n if (componentFile === null) {\n skippedRouteNames.push(route.componentName);\n analyzed.push({ ...route, analysis: null });\n continue;\n }\n\n const analysis = analyzeRouteComponent(tree, componentFile, route.componentName, sourceRoot, new Set(visited));\n if (analysis === null) {\n skippedRouteNames.push(route.componentName);\n analyzed.push({ ...route, analysis: null });\n continue;\n }\n\n analyzed.push({ ...route, analysis });\n }\n\n const shells = selectShellsForInvent(analyzed);\n if (shells.length === 0) {\n const skipped = uniqueNames(skippedRouteNames);\n return unresolvedShells(\n \"router-no-analysable-leaves\",\n skipped.length > 0 ? `skipped: ${skipped.join(\", \")}` : routerFilePath\n );\n }\n return {\n status: \"resolved\",\n shells: dedupeShells(shells),\n skippedRouteNames: uniqueNames(skippedRouteNames),\n };\n};\n\ntype RouteComponentAnalysis =\n | { readonly kind: \"layout-shell\"; readonly shell: ResolvedContentShell }\n | { readonly kind: \"leaf-shell\"; readonly shell: ResolvedContentShell };\n\nconst analyzeRouteComponent = (\n tree: Tree,\n filePath: string,\n componentName: string,\n sourceRoot: string,\n visited: Set<string>\n): RouteComponentAnalysis | null => {\n if (visited.has(`${filePath}#${componentName}`)) {\n return null;\n }\n visited.add(`${filePath}#${componentName}`);\n\n const content = tree.read(filePath, \"utf-8\");\n if (content === null) {\n return null;\n }\n\n let program: TSESTree.Program;\n try {\n program = parseTsestreeSource(content);\n } catch {\n return null;\n }\n\n const rootJsx = findJsxReturnedByName(program, componentName);\n if (rootJsx === null) {\n return null;\n }\n\n const leaf = unwrapWrappers(rootJsx);\n if (leaf === null) {\n return null;\n }\n\n if (isDivLikeHost(leaf) && leaf.type === AST_NODE_TYPES.JSXElement) {\n const shellResult = pickContentShellInFile(filePath, program, leaf);\n if (shellResult.status === \"unresolved\") {\n return null;\n }\n const wrapsOutlet =\n elementContainsOutlet(leaf) || hostWrapsOutletOneHop(tree, filePath, program, leaf, sourceRoot, visited);\n return { kind: wrapsOutlet ? \"layout-shell\" : \"leaf-shell\", shell: shellResult.shell };\n }\n\n const childName = getJsxComponentName(leaf);\n if (childName === null || childName === \"Outlet\") {\n return null;\n }\n if (isDynamicComponent(program, childName)) {\n return null;\n }\n\n const importPath = resolveStaticLocalImport(tree, program, filePath, sourceRoot, childName);\n if (importPath === null) {\n return null;\n }\n\n // Preserve nested kind: a one-hop wrapper around an Outlet layout\n // (`Root` → `Shell` with Outlet) must stay `layout-shell` so shared layout\n // wins over clear leaves. Forcing `leaf-shell` here double-invents.\n return analyzeRouteComponent(tree, importPath, childName, sourceRoot, visited);\n};\n\nconst getRouterPropIdentifier = (element: TSESTree.JSXElement): string | null => {\n for (const attribute of element.openingElement.attributes) {\n if (attribute.type !== AST_NODE_TYPES.JSXAttribute) continue;\n if (attribute.name.type !== AST_NODE_TYPES.JSXIdentifier || attribute.name.name !== \"router\") continue;\n if (attribute.value?.type !== AST_NODE_TYPES.JSXExpressionContainer) continue;\n if (attribute.value.expression.type === AST_NODE_TYPES.Identifier) {\n return attribute.value.expression.name;\n }\n }\n return null;\n};\n\nconst getVariableDeclaratorInit = (declarator: TSESTree.VariableDeclarator): TSESTree.Expression | null => {\n if (!(\"init\" in declarator)) {\n return null;\n }\n return declarator.init ?? null;\n};\n\n/**\n * Collects TanStack route factory bindings (`createRootRoute` / `createRoute` /\n * `createRootRouteWithContext`) with parent links from `getParentRoute`.\n * Arrow `component` wrappers have `componentName: null` (not guessed).\n */\nconst collectRouterRoutes = (program: TSESTree.Program): Array<RouterRoute> => {\n const coveredRanges = new Set<string>();\n const routes: Array<RouterRoute> = [];\n\n simpleTraverse(program, {\n enter: node => {\n if (node.type !== AST_NODE_TYPES.VariableDeclarator) return;\n if (node.id.type !== AST_NODE_TYPES.Identifier) return;\n const init = getVariableDeclaratorInit(node);\n if (init === null || init.type !== AST_NODE_TYPES.CallExpression) return;\n if (!isRouteFactoryCall(init)) return;\n const options = init.arguments[0];\n if (options?.type !== AST_NODE_TYPES.ObjectExpression) return;\n coveredRanges.add(`${init.range[0]}:${init.range[1]}`);\n routes.push({\n variableName: node.id.name,\n componentName: getComponentIdentifierFromOptions(options),\n parentVariableName: getParentRouteIdentifier(options),\n });\n },\n });\n\n simpleTraverse(program, {\n enter: node => {\n if (node.type !== AST_NODE_TYPES.CallExpression) return;\n if (!isRouteFactoryCall(node)) return;\n if (coveredRanges.has(`${node.range[0]}:${node.range[1]}`)) return;\n const options = node.arguments[0];\n if (options?.type !== AST_NODE_TYPES.ObjectExpression) return;\n routes.push({\n variableName: null,\n componentName: getComponentIdentifierFromOptions(options),\n parentVariableName: getParentRouteIdentifier(options),\n });\n },\n });\n\n return routes;\n};\n\nconst getParentRouteIdentifier = (options: TSESTree.ObjectExpression): string | null => {\n for (const property of options.properties) {\n if (property.type !== AST_NODE_TYPES.Property) continue;\n if (property.key.type !== AST_NODE_TYPES.Identifier || property.key.name !== \"getParentRoute\") continue;\n if (\n property.value.type !== AST_NODE_TYPES.ArrowFunctionExpression &&\n property.value.type !== AST_NODE_TYPES.FunctionExpression\n ) {\n continue;\n }\n if (property.value.body.type === AST_NODE_TYPES.Identifier) {\n return property.value.body.name;\n }\n if (property.value.body.type === AST_NODE_TYPES.BlockStatement) {\n for (const statement of property.value.body.body) {\n if (statement.type !== AST_NODE_TYPES.ReturnStatement || statement.argument === null) continue;\n const arg = unwrapParentheses(statement.argument);\n if (arg.type === AST_NODE_TYPES.Identifier) {\n return arg.name;\n }\n }\n }\n }\n return null;\n};\n\nconst collectAddChildrenIdentifiers = (program: TSESTree.Program): Array<string> => {\n const names: Array<string> = [];\n simpleTraverse(program, {\n enter: node => {\n if (node.type !== AST_NODE_TYPES.CallExpression) return;\n if (node.callee.type !== AST_NODE_TYPES.MemberExpression || node.callee.computed) return;\n if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return;\n if (node.callee.property.name !== \"addChildren\") return;\n const arg = node.arguments[0];\n if (arg?.type !== AST_NODE_TYPES.ArrayExpression) return;\n for (const element of arg.elements) {\n if (element?.type === AST_NODE_TYPES.Identifier) {\n names.push(element.name);\n }\n }\n },\n });\n return names;\n};\n\nconst CONTENT_SPACE_TOKEN = \"p-content-space\";\n\nconst shellHasContentSpace = (shell: ResolvedContentShell): boolean =>\n splitClasses(shell.classnameValue).includes(CONTENT_SPACE_TOKEN);\n\n/**\n * Layout-wins is per route subtree: a layout covers only descendant leaves.\n * Already-migrated descendant leaves must not get a second inset on the layout.\n */\nconst selectShellsForInvent = (routes: ReadonlyArray<AnalyzedRoute>): Array<ResolvedContentShell> => {\n const byVariable = new Map<string, AnalyzedRoute>();\n for (const route of routes) {\n if (route.variableName !== null) {\n byVariable.set(route.variableName, route);\n }\n }\n\n const layouts = routes.filter(route => route.analysis?.kind === \"layout-shell\");\n const leaves = routes.filter(route => route.analysis?.kind === \"leaf-shell\");\n const coveredLeaves = new Set<AnalyzedRoute>();\n const selected: Array<ResolvedContentShell> = [];\n\n for (const layout of layouts) {\n if (layout.analysis?.kind !== \"layout-shell\") continue;\n const descendants = leaves.filter(leaf => isDescendantOf(leaf, layout, byVariable));\n const descendantsAlreadyMigrated = descendants.some(\n leaf => leaf.analysis !== null && shellHasContentSpace(leaf.analysis.shell)\n );\n if (descendantsAlreadyMigrated) {\n continue;\n }\n selected.push(layout.analysis.shell);\n for (const descendant of descendants) {\n coveredLeaves.add(descendant);\n }\n }\n\n for (const leaf of leaves) {\n if (coveredLeaves.has(leaf) || leaf.analysis?.kind !== \"leaf-shell\") continue;\n selected.push(leaf.analysis.shell);\n }\n\n return selected;\n};\n\nconst isDescendantOf = (\n leaf: AnalyzedRoute,\n layout: AnalyzedRoute,\n byVariable: Map<string, AnalyzedRoute>\n): boolean => {\n if (layout.variableName === null) return false;\n let current = leaf.parentVariableName;\n const seen = new Set<string>();\n while (current !== null && !seen.has(current)) {\n if (current === layout.variableName) return true;\n seen.add(current);\n current = byVariable.get(current)?.parentVariableName ?? null;\n }\n return false;\n};\n\nconst uniqueNames = (names: ReadonlyArray<string>): Array<string> => {\n const seen = new Set<string>();\n const result: Array<string> = [];\n for (const name of names) {\n if (seen.has(name)) continue;\n seen.add(name);\n result.push(name);\n }\n return result;\n};\n\nconst isRouteFactoryCall = (node: TSESTree.CallExpression): boolean => {\n const directName = getCalleeIdentifierName(node.callee);\n if (directName === \"createRootRoute\" || directName === \"createRoute\") {\n return true;\n }\n // createRootRouteWithContext<T>()({ ... })\n if (node.callee.type === AST_NODE_TYPES.CallExpression) {\n const innerName = getCalleeIdentifierName(node.callee.callee);\n return innerName === \"createRootRouteWithContext\";\n }\n return false;\n};\n\nconst getCalleeIdentifierName = (\n callee: TSESTree.Expression | TSESTree.Super | TSESTree.PrivateIdentifier\n): string | null => {\n if (callee.type === AST_NODE_TYPES.Identifier) {\n return callee.name;\n }\n if (callee.type === AST_NODE_TYPES.TSInstantiationExpression) {\n return getCalleeIdentifierName(callee.expression);\n }\n return null;\n};\n\nconst getComponentIdentifierFromOptions = (options: TSESTree.ObjectExpression): string | null => {\n for (const property of options.properties) {\n if (property.type !== AST_NODE_TYPES.Property) continue;\n if (property.key.type !== AST_NODE_TYPES.Identifier || property.key.name !== \"component\") continue;\n if (property.value.type === AST_NODE_TYPES.Identifier) {\n return property.value.name;\n }\n }\n return null;\n};\n\nconst resolveComponentModulePath = (\n tree: Tree,\n program: TSESTree.Program,\n fromFilePath: string,\n sourceRoot: string,\n componentName: string\n): string | null => {\n const imported = resolveStaticLocalImport(tree, program, fromFilePath, sourceRoot, componentName);\n if (imported !== null) {\n return imported;\n }\n if (findJsxReturnedByName(program, componentName) !== null) {\n return fromFilePath;\n }\n return null;\n};\n\nconst elementContainsOutlet = (element: TSESTree.JSXElement | TSESTree.JSXFragment): boolean => {\n let found = false;\n simpleTraverse(element, {\n enter: node => {\n if (found) return;\n if (node.type !== AST_NODE_TYPES.JSXOpeningElement) return;\n const name = getJsxOpeningName(node.name);\n if (name === \"Outlet\") {\n found = true;\n }\n },\n });\n return found;\n};\n\n/**\n * True when a div-like shell's `<Outlet />` lives one custom-component hop\n * below (`<div><Main /></div>` where `Main` returns `<Outlet />`). Without this,\n * the ancestor is padded as a leaf alongside real route leaves.\n */\nconst hostWrapsOutletOneHop = (\n tree: Tree,\n filePath: string,\n program: TSESTree.Program,\n host: TSESTree.JSXElement,\n sourceRoot: string,\n visited: Set<string>\n): boolean => {\n for (const childName of collectCustomChildComponentNames(host)) {\n if (childName === \"Outlet\") {\n return true;\n }\n if (componentReturnsOutletOneHop(tree, filePath, program, childName, sourceRoot, visited)) {\n return true;\n }\n }\n return false;\n};\n\nconst collectCustomChildComponentNames = (host: TSESTree.JSXElement): Array<string> => {\n const names: Array<string> = [];\n for (const child of host.children) {\n if (child.type !== AST_NODE_TYPES.JSXElement) continue;\n const name = getJsxComponentName(child);\n if (name !== null) {\n names.push(name);\n }\n }\n return names;\n};\n\nconst componentReturnsOutletOneHop = (\n tree: Tree,\n fromFilePath: string,\n fromProgram: TSESTree.Program,\n componentName: string,\n sourceRoot: string,\n visited: Set<string>\n): boolean => {\n const visitKey = `${fromFilePath}#outlet-hop#${componentName}`;\n if (visited.has(visitKey)) {\n return false;\n }\n visited.add(visitKey);\n\n let program = fromProgram;\n if (findJsxReturnedByName(fromProgram, componentName) === null) {\n const importPath = resolveStaticLocalImport(tree, fromProgram, fromFilePath, sourceRoot, componentName);\n if (importPath === null) {\n return false;\n }\n const content = tree.read(importPath, \"utf-8\");\n if (content === null) {\n return false;\n }\n try {\n program = parseTsestreeSource(content);\n } catch {\n return false;\n }\n }\n\n const jsx = findJsxReturnedByName(program, componentName);\n if (jsx === null) {\n return false;\n }\n if (getJsxComponentName(jsx) === \"Outlet\") {\n return true;\n }\n return elementContainsOutlet(jsx);\n};\n\nconst dedupeShells = (shells: ReadonlyArray<ResolvedContentShell>): Array<ResolvedContentShell> => {\n const seen = new Set<string>();\n const result: Array<ResolvedContentShell> = [];\n for (const shell of shells) {\n const key = `${shell.filePath}:${shell.location.reportNode.range[0]}:${shell.location.reportNode.range[1]}`;\n if (seen.has(key)) continue;\n seen.add(key);\n result.push(shell);\n }\n return result;\n};\n\n/**\n * Finds the JSX element returned by the entry's primary component:\n * `singleSpaReact({ rootComponent })` when present, otherwise the first\n * exported function/const whose body returns JSX.\n */\nconst findRootJsxElement = (program: TSESTree.Program): TSESTree.JSXElement | TSESTree.JSXFragment | null => {\n const singleSpaRootName = findSingleSpaRootComponentName(program);\n if (singleSpaRootName !== null) {\n return findJsxReturnedByName(program, singleSpaRootName);\n }\n\n for (const statement of program.body) {\n const name = getExportedComponentName(statement);\n if (name === null) continue;\n const jsx = findJsxReturnedByName(program, name);\n if (jsx !== null) return jsx;\n }\n\n return null;\n};\n\nconst findSingleSpaRootComponentName = (program: TSESTree.Program): string | null => {\n let result: string | null = null;\n\n simpleTraverse(program, {\n enter: node => {\n if (result !== null) return;\n if (node.type !== AST_NODE_TYPES.CallExpression) return;\n if (!isCalleeNamed(node.callee, \"singleSpaReact\")) return;\n if (node.arguments[0]?.type !== AST_NODE_TYPES.ObjectExpression) return;\n\n for (const property of node.arguments[0].properties) {\n if (property.type !== AST_NODE_TYPES.Property) continue;\n if (property.key.type !== AST_NODE_TYPES.Identifier || property.key.name !== \"rootComponent\") continue;\n if (property.value.type === AST_NODE_TYPES.Identifier) {\n result = property.value.name;\n }\n }\n },\n });\n\n return result;\n};\n\nconst getExportedComponentName = (statement: TSESTree.ProgramStatement): string | null => {\n if (statement.type === AST_NODE_TYPES.ExportNamedDeclaration) {\n if (statement.declaration?.type === AST_NODE_TYPES.FunctionDeclaration) {\n return statement.declaration.id?.name ?? null;\n }\n if (statement.declaration?.type === AST_NODE_TYPES.VariableDeclaration) {\n const declarator = statement.declaration.declarations[0];\n if (declarator.id.type === AST_NODE_TYPES.Identifier) {\n return declarator.id.name;\n }\n }\n }\n if (statement.type === AST_NODE_TYPES.ExportDefaultDeclaration) {\n if (statement.declaration.type === AST_NODE_TYPES.Identifier) {\n return statement.declaration.name;\n }\n if (statement.declaration.type === AST_NODE_TYPES.FunctionDeclaration) {\n return statement.declaration.id?.name ?? null;\n }\n }\n return null;\n};\n\nconst findJsxReturnedByName = (\n program: TSESTree.Program,\n name: string\n): TSESTree.JSXElement | TSESTree.JSXFragment | null => {\n for (const statement of program.body) {\n const fn = matchNamedFunctionLike(statement, name);\n if (fn !== null) {\n return findReturnedJsx(fn);\n }\n }\n return null;\n};\n\nconst matchNamedFunctionLike = (\n statement: TSESTree.ProgramStatement,\n name: string\n): TSESTree.BlockStatement | TSESTree.Expression | null => {\n const decl =\n statement.type === AST_NODE_TYPES.ExportNamedDeclaration ||\n statement.type === AST_NODE_TYPES.ExportDefaultDeclaration\n ? statement.declaration\n : statement;\n\n if (decl === null) return null;\n\n if (decl.type === AST_NODE_TYPES.FunctionDeclaration && decl.id !== null && decl.id.name === name) {\n return decl.body;\n }\n\n if (decl.type === AST_NODE_TYPES.VariableDeclaration) {\n for (const declarator of decl.declarations) {\n if (declarator.id.type !== AST_NODE_TYPES.Identifier || declarator.id.name !== name) continue;\n const init = declarator.init;\n if (init === null) return null;\n if (init.type === AST_NODE_TYPES.ArrowFunctionExpression || init.type === AST_NODE_TYPES.FunctionExpression) {\n return init.body;\n }\n }\n }\n\n if (statement.type === AST_NODE_TYPES.FunctionDeclaration && statement.id.name === name) {\n return statement.body;\n }\n\n return null;\n};\n\nconst findReturnedJsx = (\n body: TSESTree.BlockStatement | TSESTree.Expression\n): TSESTree.JSXElement | TSESTree.JSXFragment | null => {\n if (body.type === AST_NODE_TYPES.JSXElement || body.type === AST_NODE_TYPES.JSXFragment) {\n return body;\n }\n if (body.type === AST_NODE_TYPES.BlockStatement) {\n for (const statement of body.body) {\n if (statement.type !== AST_NODE_TYPES.ReturnStatement || statement.argument === null) continue;\n const arg = unwrapParentheses(statement.argument);\n if (arg.type === AST_NODE_TYPES.JSXElement || arg.type === AST_NODE_TYPES.JSXFragment) {\n return arg;\n }\n }\n }\n return null;\n};\n\nconst unwrapParentheses = (expression: TSESTree.Expression): TSESTree.Expression => {\n let current = expression;\n while (current.type === AST_NODE_TYPES.TSAsExpression || current.type === AST_NODE_TYPES.TSSatisfiesExpression) {\n current = current.expression;\n }\n return current;\n};\n\n/**\n * Skips known provider / Suspense / fragment wrappers down to the first\n * meaningful child (host element or custom component).\n */\nconst unwrapWrappers = (\n node: TSESTree.JSXElement | TSESTree.JSXFragment\n): TSESTree.JSXElement | TSESTree.JSXFragment | null => {\n let current: TSESTree.JSXElement | TSESTree.JSXFragment = node;\n\n for (;;) {\n if (current.type === AST_NODE_TYPES.JSXFragment) {\n const child = firstJsxChild(current.children);\n if (child === null) return null;\n current = child;\n continue;\n }\n\n const name = getJsxComponentName(current);\n if (name !== null && isKnownWrapperName(name)) {\n const child = firstJsxChild(current.children);\n if (child === null) return null;\n current = child;\n continue;\n }\n\n return current;\n }\n};\n\nconst firstJsxChild = (\n children: ReadonlyArray<TSESTree.JSXChild>\n): TSESTree.JSXElement | TSESTree.JSXFragment | null => {\n for (const child of children) {\n if (child.type === AST_NODE_TYPES.JSXElement || child.type === AST_NODE_TYPES.JSXFragment) {\n return child;\n }\n }\n return null;\n};\n\nconst isDivLikeHost = (element: TSESTree.JSXElement | TSESTree.JSXFragment): boolean => {\n if (element.type !== AST_NODE_TYPES.JSXElement) return false;\n const name = getJsxOpeningName(element.openingElement.name);\n return name !== null && DIV_LIKE_ELEMENTS.has(name);\n};\n\nconst getJsxComponentName = (element: TSESTree.JSXElement | TSESTree.JSXFragment): string | null => {\n if (element.type !== AST_NODE_TYPES.JSXElement) return null;\n const name = getJsxOpeningName(element.openingElement.name);\n if (name === null) return null;\n if (DIV_LIKE_ELEMENTS.has(name)) return null;\n if (/^[a-z]/.test(name)) return null;\n return name;\n};\n\nconst getJsxOpeningName = (name: TSESTree.JSXTagNameExpression): string | null => {\n if (name.type === AST_NODE_TYPES.JSXIdentifier) return name.name;\n return null;\n};\n\n/**\n * Confidence rule for this phase: a single editable content-region classname\n * host that itself owns scrollable overflow (`overflow-auto` / `scroll` /\n * `overlay`, including axis-prefixed forms). Clipping overflow (`hidden` /\n * `clip`), a scrolling descendant, or a header-ish child (`PageHeader` /\n * `Topbar` / `Header`) make the host unresolved — those cases go to the\n * unresolved-surface report for a human to place the inset.\n *\n * Classnames must be bound to the host's `className`/`class` attribute (literal\n * on the attribute, direct Tailwind call in the attribute, or the local\n * binding of that attribute's identifier/callee). Never invent from unrelated\n * file-wide classname locations.\n */\nconst pickContentShellInFile = (\n filePath: string,\n program: TSESTree.Program,\n host: TSESTree.JSXElement\n): ResolveContentShellResult => {\n const hostClassnames = collectEditableClassnamesForHost(program, host);\n if (hostClassnames.length === 0) {\n return unresolvedShell(\"no-editable-classname\", filePath);\n }\n\n if (hostClassnames.some(classname => classListHasClippingOverflow(splitClasses(classname.value)))) {\n return unresolvedShell(\"clipping-overflow-on-host\", filePath);\n }\n\n const candidates = hostClassnames.filter(isContentShellClassname);\n if (candidates.length === 0) {\n return unresolvedShell(\"no-overflow-on-host\", filePath);\n }\n if (candidates.length > 1) {\n return unresolvedShell(\"multiple-overflow-candidates\", filePath);\n }\n\n if (hostRendersHeader(host)) {\n return unresolvedShell(\"header-on-shell\", filePath);\n }\n if (descendantOwnsScroll(program, host)) {\n return unresolvedShell(\"descendant-owns-scroll\", filePath);\n }\n\n const location = candidates[0];\n if (location === undefined) {\n return unresolvedShell(\"unclear-graph\", filePath);\n }\n return {\n status: \"resolved\",\n shell: {\n filePath,\n classnameValue: location.value,\n combinedClassnameValue: hostClassnames.map(hostLocation => hostLocation.value).join(\" \"),\n location,\n },\n };\n};\n\nconst collectEditableClassnamesForHost = (\n program: TSESTree.Program,\n host: TSESTree.JSXElement\n): Array<ClassnameLocation> => {\n const attribute = host.openingElement.attributes.find(\n (attr): attr is TSESTree.JSXAttribute =>\n attr.type === AST_NODE_TYPES.JSXAttribute &&\n attr.name.type === AST_NODE_TYPES.JSXIdentifier &&\n (attr.name.name === \"className\" || attr.name.name === \"class\")\n );\n if (attribute === undefined) return [];\n\n // Direct literal classnames on the attribute.\n const fromAttribute = findClassnameLocations(program).filter(location => {\n if (location.context.type !== \"jsx-attribute\") return false;\n return location.reportNode.range[0] >= attribute.range[0] && location.reportNode.range[1] <= attribute.range[1];\n });\n if (fromAttribute.length > 0) return fromAttribute;\n\n const value = attribute.value;\n if (value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return [];\n const expression = value.expression;\n\n if (expression.type === AST_NODE_TYPES.CallExpression) {\n return collectClassnamesBoundToCallExpression(program, expression);\n }\n if (expression.type === AST_NODE_TYPES.Identifier) {\n return collectClassnamesBoundToIdentifier(program, expression.name);\n }\n return [];\n};\n\n/**\n * `className={cva(\"...\")}` — locations inside this call only.\n * `className={layout()}` — locations inside the local binding of `layout` only.\n */\nconst collectClassnamesBoundToCallExpression = (\n program: TSESTree.Program,\n callExpression: TSESTree.CallExpression\n): Array<ClassnameLocation> => {\n if (callExpression.callee.type !== AST_NODE_TYPES.Identifier) {\n return [];\n }\n\n const calleeName = callExpression.callee.name;\n if (isTailwindFunction(calleeName)) {\n return findClassnameLocations(program).filter(\n location =>\n location.reportNode.range[0] >= callExpression.range[0] &&\n location.reportNode.range[1] <= callExpression.range[1]\n );\n }\n\n return collectClassnamesBoundToIdentifier(program, calleeName);\n};\n\nconst collectClassnamesBoundToIdentifier = (program: TSESTree.Program, name: string): Array<ClassnameLocation> => {\n const bindingRange = findLocalBindingInitializerRange(program, name);\n if (bindingRange === null) {\n return [];\n }\n\n return findClassnameLocations(program).filter(\n location => location.reportNode.range[0] >= bindingRange[0] && location.reportNode.range[1] <= bindingRange[1]\n );\n};\n\nconst findLocalBindingInitializerRange = (program: TSESTree.Program, name: string): TSESTree.Range | null => {\n let result: TSESTree.Range | null = null;\n\n simpleTraverse(program, {\n enter: node => {\n if (result !== null) return;\n if (node.type !== AST_NODE_TYPES.VariableDeclarator) return;\n if (node.id.type !== AST_NODE_TYPES.Identifier || node.id.name !== name) return;\n if (node.init === null) return;\n result = node.init.range;\n },\n });\n\n return result;\n};\n\nconst SCROLLABLE_OVERFLOW = /(^|:)overflow-(x-|y-)?(auto|scroll|overlay)$/;\nconst CLIPPING_OVERFLOW = /(^|:)overflow-(x-|y-)?(hidden|clip)$/;\n\nconst classListHasScrollableOverflow = (classes: ReadonlyArray<string>): boolean =>\n classes.some(cls => SCROLLABLE_OVERFLOW.test(cls));\n\nconst classListHasClippingOverflow = (classes: ReadonlyArray<string>): boolean =>\n classes.some(cls => CLIPPING_OVERFLOW.test(cls));\n\nconst isContentShellClassname = (location: ClassnameLocation): boolean => {\n const classes = splitClasses(location.value);\n if (classListHasClippingOverflow(classes)) return false;\n return classListHasScrollableOverflow(classes);\n};\n\nconst HEADER_ISH_NAMES: ReadonlySet<string> = new Set([\"PageHeader\", \"Topbar\", \"Header\"]);\n\nconst hostRendersHeader = (host: TSESTree.JSXElement): boolean =>\n jsxElementsUnder(host).some(element => {\n const name = getJsxOpeningName(element.openingElement.name);\n return name !== null && HEADER_ISH_NAMES.has(name);\n });\n\nconst descendantOwnsScroll = (program: TSESTree.Program, host: TSESTree.JSXElement): boolean =>\n jsxElementsUnder(host).some(element =>\n collectEditableClassnamesForHost(program, element).some(isContentShellClassname)\n );\n\nconst jsxElementsUnder = (host: TSESTree.JSXElement): Array<TSESTree.JSXElement> => {\n const found: Array<TSESTree.JSXElement> = [];\n const visit = (children: ReadonlyArray<TSESTree.JSXChild>): void => {\n for (const child of children) {\n if (child.type === AST_NODE_TYPES.JSXElement) {\n found.push(child);\n visit(child.children);\n } else if (child.type === AST_NODE_TYPES.JSXFragment) {\n visit(child.children);\n }\n }\n };\n visit(host.children);\n return found;\n};\n\nconst isDynamicComponent = (program: TSESTree.Program, componentName: string): boolean => {\n let isDynamic = false;\n\n simpleTraverse(program, {\n enter: node => {\n if (isDynamic) return;\n if (node.type !== AST_NODE_TYPES.VariableDeclarator) return;\n if (node.id.type !== AST_NODE_TYPES.Identifier || node.id.name !== componentName) return;\n if (node.init === null) return;\n if (containsDynamicImport(node.init)) {\n isDynamic = true;\n }\n },\n });\n\n return isDynamic;\n};\n\nconst containsDynamicImport = (node: TSESTree.Node): boolean => {\n let found = false;\n simpleTraverse(node, {\n enter: child => {\n if (found) return;\n if (child.type === AST_NODE_TYPES.ImportExpression) {\n found = true;\n }\n },\n });\n return found;\n};\n\n/**\n * Resolves a component name to a static relative/local import under\n * `sourceRoot`. Returns null for external packages or missing bindings.\n */\nconst resolveStaticLocalImport = (\n tree: Tree,\n program: TSESTree.Program,\n fromFilePath: string,\n sourceRoot: string,\n componentName: string\n): string | null => {\n for (const statement of program.body) {\n if (statement.type !== AST_NODE_TYPES.ImportDeclaration) continue;\n const specifier = statement.source.value;\n if (typeof specifier !== \"string\") continue;\n const bindsComponent = statement.specifiers.some(spec => {\n if (spec.type === AST_NODE_TYPES.ImportDefaultSpecifier) {\n return spec.local.name === componentName;\n }\n if (spec.type === AST_NODE_TYPES.ImportSpecifier) {\n return spec.local.name === componentName;\n }\n return false;\n });\n if (!bindsComponent) continue;\n\n if (!(specifier.startsWith(\"./\") || specifier.startsWith(\"../\"))) {\n return null;\n }\n\n const fromDir = path.posix.dirname(fromFilePath);\n const resolvedWithoutExt = path.posix.normalize(path.posix.join(fromDir, specifier));\n const candidates = [\n resolvedWithoutExt,\n `${resolvedWithoutExt}.tsx`,\n `${resolvedWithoutExt}.ts`,\n `${resolvedWithoutExt}/index.tsx`,\n `${resolvedWithoutExt}/index.ts`,\n ];\n\n for (const candidate of candidates) {\n if (candidate === fromFilePath) continue;\n if (!candidate.startsWith(`${sourceRoot}/`) && candidate !== sourceRoot) continue;\n if (!(candidate.endsWith(\".tsx\") || candidate.endsWith(\".ts\"))) continue;\n if (tree.exists(candidate)) {\n return candidate;\n }\n }\n }\n\n // Local const binding (e.g. LazyPage) without an import — not followable as a\n // static local module.\n return null;\n};\n\nconst isCalleeNamed = (callee: TSESTree.CallExpression[\"callee\"], name: string): boolean => {\n return callee.type === AST_NODE_TYPES.Identifier && callee.name === name;\n};\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rewritePageContent = rewritePageContent;
|
|
4
|
+
const css_classname_utils_1 = require("@trackunit/css-classname-utils");
|
|
5
|
+
const classname_ast_rewrite_1 = require("../utils/classname-ast-rewrite");
|
|
6
|
+
const PAGE_CONTENT_PATTERN = "page-content";
|
|
7
|
+
const CONTENT_SPACE_TOKEN = "p-content-space";
|
|
8
|
+
const OVERFLOW_AUTO_TOKEN = "overflow-auto";
|
|
9
|
+
/**
|
|
10
|
+
* True when `token` is already present as a whole class token, including when
|
|
11
|
+
* wrapped in Tailwind variant prefixes (e.g. `xl:overflow-hidden`).
|
|
12
|
+
*/
|
|
13
|
+
function hasOverflowToken(classes) {
|
|
14
|
+
return classes.some(cls => /(^|:)overflow-/.test(cls));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Rewrites the legacy `page-content` Tailwind class to
|
|
18
|
+
* `overflow-auto p-content-space` across every rewritable file under a
|
|
19
|
+
* single resolved extension's `sourceRoot`.
|
|
20
|
+
*
|
|
21
|
+
* When the classname already declares its own `overflow-*` token, only
|
|
22
|
+
* `p-content-space` is inserted — emitting a second `overflow-auto` would be
|
|
23
|
+
* dead (or, when an identical `overflow-auto` is already present, a
|
|
24
|
+
* duplicate). Scroll ownership stays with the element's existing overflow
|
|
25
|
+
* declaration.
|
|
26
|
+
*
|
|
27
|
+
* Scoped to one extension per call — the caller (the orchestrator) loops
|
|
28
|
+
* over every Asset Home/Site Home/Admin extension.
|
|
29
|
+
*
|
|
30
|
+
* Only performs the `page-content` classname rewrite: it does not touch
|
|
31
|
+
* `pb-*`/`pb-responsive-space` classes or produce a report, both of which are
|
|
32
|
+
* separate migration steps.
|
|
33
|
+
*/
|
|
34
|
+
function rewritePageContent(tree, extension) {
|
|
35
|
+
return (0, classname_ast_rewrite_1.transformClassnamesUnderSourceRoot)(tree, extension.sourceRoot, content => content.includes(PAGE_CONTENT_PATTERN), value => {
|
|
36
|
+
const replacement = hasOverflowToken((0, css_classname_utils_1.splitClasses)(value))
|
|
37
|
+
? CONTENT_SPACE_TOKEN
|
|
38
|
+
: `${OVERFLOW_AUTO_TOKEN} ${CONTENT_SPACE_TOKEN}`;
|
|
39
|
+
return (0, css_classname_utils_1.replaceClassToken)(value, PAGE_CONTENT_PATTERN, replacement);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=rewrite-page-content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rewrite-page-content.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app/migrations/p-content-space-codemod/rewrite-page-content.ts"],"names":[],"mappings":";;AAmCA,gDAYC;AA9CD,wEAAiF;AACjF,0EAAoF;AAGpF,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAC5C,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAC9C,MAAM,mBAAmB,GAAG,eAAe,CAAC;AAE5C;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAA8B;IACtD,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,kBAAkB,CAAC,IAAU,EAAE,SAA4B;IACzE,OAAO,IAAA,0DAAkC,EACvC,IAAI,EACJ,SAAS,CAAC,UAAU,EACpB,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EACjD,KAAK,CAAC,EAAE;QACN,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAA,kCAAY,EAAC,KAAK,CAAC,CAAC;YACvD,CAAC,CAAC,mBAAmB;YACrB,CAAC,CAAC,GAAG,mBAAmB,IAAI,mBAAmB,EAAE,CAAC;QACpD,OAAO,IAAA,uCAAiB,EAAC,KAAK,EAAE,oBAAoB,EAAE,WAAW,CAAC,CAAC;IACrE,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Tree } from \"@nx/devkit\";\nimport { replaceClassToken, splitClasses } from \"@trackunit/css-classname-utils\";\nimport { transformClassnamesUnderSourceRoot } from \"../utils/classname-ast-rewrite\";\nimport type { ResolvedExtension } from \"../utils/resolve-extension-types\";\n\nconst PAGE_CONTENT_PATTERN = \"page-content\";\nconst CONTENT_SPACE_TOKEN = \"p-content-space\";\nconst OVERFLOW_AUTO_TOKEN = \"overflow-auto\";\n\n/**\n * True when `token` is already present as a whole class token, including when\n * wrapped in Tailwind variant prefixes (e.g. `xl:overflow-hidden`).\n */\nfunction hasOverflowToken(classes: ReadonlyArray<string>): boolean {\n return classes.some(cls => /(^|:)overflow-/.test(cls));\n}\n\n/**\n * Rewrites the legacy `page-content` Tailwind class to\n * `overflow-auto p-content-space` across every rewritable file under a\n * single resolved extension's `sourceRoot`.\n *\n * When the classname already declares its own `overflow-*` token, only\n * `p-content-space` is inserted — emitting a second `overflow-auto` would be\n * dead (or, when an identical `overflow-auto` is already present, a\n * duplicate). Scroll ownership stays with the element's existing overflow\n * declaration.\n *\n * Scoped to one extension per call — the caller (the orchestrator) loops\n * over every Asset Home/Site Home/Admin extension.\n *\n * Only performs the `page-content` classname rewrite: it does not touch\n * `pb-*`/`pb-responsive-space` classes or produce a report, both of which are\n * separate migration steps.\n */\nexport function rewritePageContent(tree: Tree, extension: ResolvedExtension): { filesChanged: Array<string> } {\n return transformClassnamesUnderSourceRoot(\n tree,\n extension.sourceRoot,\n content => content.includes(PAGE_CONTENT_PATTERN),\n value => {\n const replacement = hasOverflowToken(splitClasses(value))\n ? CONTENT_SPACE_TOKEN\n : `${OVERFLOW_AUTO_TOKEN} ${CONTENT_SPACE_TOKEN}`;\n return replaceClassToken(value, PAGE_CONTENT_PATTERN, replacement);\n }\n );\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Why invent/resolve declined to pick an ASA content shell. Surfaced in
|
|
4
|
+
* migration console output and UnresolvedSurfaceReport so humans (and
|
|
5
|
+
* third parties) can plan manual `p-content-space` placement.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.shellSkipReason = void 0;
|
|
9
|
+
const MESSAGES = {
|
|
10
|
+
"entry-missing": "extension entry file was not found under sourceRoot",
|
|
11
|
+
"parse-failed": "extension entry/source could not be parsed as TypeScript/TSX",
|
|
12
|
+
"no-root-jsx": "could not find a root JSX return in the entry component",
|
|
13
|
+
"empty-wrapper": "provider/Suspense/Fragment wrappers had no JSX child to walk into",
|
|
14
|
+
cycle: "component graph walked into a cycle while resolving the content shell",
|
|
15
|
+
"dynamic-component": "content shell is behind a dynamic import / lazy component (not followed)",
|
|
16
|
+
"unresolvable-import": "could not resolve a static local import for the host component",
|
|
17
|
+
"non-host-element": "leaf JSX is not a div/main/section with an inventable className host",
|
|
18
|
+
"router-prop-unresolved": "RouterProvider router={...} prop was not a simple identifier",
|
|
19
|
+
"router-inline-arrow-components": "TanStack routes use inline arrow `component: () => <...>` instead of a named component identifier — invent cannot follow them",
|
|
20
|
+
"router-no-analysable-leaves": "router graph had no analysable named route leaves with a clear overflow content shell",
|
|
21
|
+
"no-editable-classname": "div/main/section host has no editable className/class (literal or bound Tailwind helper)",
|
|
22
|
+
"no-overflow-on-host": "host has a className but does not itself own scrollable overflow (overflow-auto/scroll/overlay) — invent only pads the scroll owner",
|
|
23
|
+
"multiple-overflow-candidates": "host has more than one inventable overflow classname binding (ambiguous)",
|
|
24
|
+
"header-on-shell": "host also renders PageHeader/Topbar/Header — pad the body below the header, not this shell",
|
|
25
|
+
"descendant-owns-scroll": "a descendant owns overflow scrolling — pad that scroll owner, not the outer wrapper",
|
|
26
|
+
"clipping-overflow-on-host": "host uses overflow-hidden/clip (full-bleed / clipping shell) — not inventable as a content inset",
|
|
27
|
+
"unclear-graph": "content-shell graph was unclear; invent refused to guess a first-div",
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Builds a structured skip reason for invent/resolve console + report output.
|
|
31
|
+
*
|
|
32
|
+
* @param code - Stable skip-reason code from the inventable-shell contract
|
|
33
|
+
* @param detail - Optional path / leaf list / host name appended in parentheses
|
|
34
|
+
* @returns {ShellSkipReason} Structured reason with a human-readable message
|
|
35
|
+
*/
|
|
36
|
+
const shellSkipReason = (code, detail) => ({
|
|
37
|
+
code,
|
|
38
|
+
message: detail === undefined || detail.length === 0 ? MESSAGES[code] : `${MESSAGES[code]} (${detail})`,
|
|
39
|
+
});
|
|
40
|
+
exports.shellSkipReason = shellSkipReason;
|
|
41
|
+
//# sourceMappingURL=shell-skip-reason.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-skip-reason.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app/migrations/p-content-space-codemod/shell-skip-reason.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AA4BH,MAAM,QAAQ,GAAwC;IACpD,eAAe,EAAE,qDAAqD;IACtE,cAAc,EAAE,8DAA8D;IAC9E,aAAa,EAAE,yDAAyD;IACxE,eAAe,EAAE,mEAAmE;IACpF,KAAK,EAAE,uEAAuE;IAC9E,mBAAmB,EAAE,0EAA0E;IAC/F,qBAAqB,EAAE,gEAAgE;IACvF,kBAAkB,EAAE,sEAAsE;IAC1F,wBAAwB,EAAE,8DAA8D;IACxF,gCAAgC,EAC9B,+HAA+H;IACjI,6BAA6B,EAC3B,uFAAuF;IACzF,uBAAuB,EAAE,0FAA0F;IACnH,qBAAqB,EACnB,qIAAqI;IACvI,8BAA8B,EAAE,0EAA0E;IAC1G,iBAAiB,EAAE,4FAA4F;IAC/G,wBAAwB,EAAE,qFAAqF;IAC/G,2BAA2B,EACzB,kGAAkG;IACpG,eAAe,EAAE,sEAAsE;CACxF,CAAC;AAEF;;;;;;GAMG;AACI,MAAM,eAAe,GAAG,CAAC,IAAyB,EAAE,MAAe,EAAmB,EAAE,CAAC,CAAC;IAC/F,IAAI;IACJ,OAAO,EAAE,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,MAAM,GAAG;CACxG,CAAC,CAAC;AAHU,QAAA,eAAe,mBAGzB","sourcesContent":["/**\n * Why invent/resolve declined to pick an ASA content shell. Surfaced in\n * migration console output and UnresolvedSurfaceReport so humans (and\n * third parties) can plan manual `p-content-space` placement.\n */\n\nexport type ShellSkipReasonCode =\n | \"entry-missing\"\n | \"parse-failed\"\n | \"no-root-jsx\"\n | \"empty-wrapper\"\n | \"cycle\"\n | \"dynamic-component\"\n | \"unresolvable-import\"\n | \"non-host-element\"\n | \"router-prop-unresolved\"\n | \"router-inline-arrow-components\"\n | \"router-no-analysable-leaves\"\n | \"no-editable-classname\"\n | \"no-overflow-on-host\"\n | \"multiple-overflow-candidates\"\n | \"header-on-shell\"\n | \"descendant-owns-scroll\"\n | \"clipping-overflow-on-host\"\n | \"unclear-graph\";\n\nexport type ShellSkipReason = {\n readonly code: ShellSkipReasonCode;\n /** Human-readable explanation (safe to print to the console). */\n readonly message: string;\n};\n\nconst MESSAGES: Record<ShellSkipReasonCode, string> = {\n \"entry-missing\": \"extension entry file was not found under sourceRoot\",\n \"parse-failed\": \"extension entry/source could not be parsed as TypeScript/TSX\",\n \"no-root-jsx\": \"could not find a root JSX return in the entry component\",\n \"empty-wrapper\": \"provider/Suspense/Fragment wrappers had no JSX child to walk into\",\n cycle: \"component graph walked into a cycle while resolving the content shell\",\n \"dynamic-component\": \"content shell is behind a dynamic import / lazy component (not followed)\",\n \"unresolvable-import\": \"could not resolve a static local import for the host component\",\n \"non-host-element\": \"leaf JSX is not a div/main/section with an inventable className host\",\n \"router-prop-unresolved\": \"RouterProvider router={...} prop was not a simple identifier\",\n \"router-inline-arrow-components\":\n \"TanStack routes use inline arrow `component: () => <...>` instead of a named component identifier — invent cannot follow them\",\n \"router-no-analysable-leaves\":\n \"router graph had no analysable named route leaves with a clear overflow content shell\",\n \"no-editable-classname\": \"div/main/section host has no editable className/class (literal or bound Tailwind helper)\",\n \"no-overflow-on-host\":\n \"host has a className but does not itself own scrollable overflow (overflow-auto/scroll/overlay) — invent only pads the scroll owner\",\n \"multiple-overflow-candidates\": \"host has more than one inventable overflow classname binding (ambiguous)\",\n \"header-on-shell\": \"host also renders PageHeader/Topbar/Header — pad the body below the header, not this shell\",\n \"descendant-owns-scroll\": \"a descendant owns overflow scrolling — pad that scroll owner, not the outer wrapper\",\n \"clipping-overflow-on-host\":\n \"host uses overflow-hidden/clip (full-bleed / clipping shell) — not inventable as a content inset\",\n \"unclear-graph\": \"content-shell graph was unclear; invent refused to guess a first-div\",\n};\n\n/**\n * Builds a structured skip reason for invent/resolve console + report output.\n *\n * @param code - Stable skip-reason code from the inventable-shell contract\n * @param detail - Optional path / leaf list / host name appended in parentheses\n * @returns {ShellSkipReason} Structured reason with a human-readable message\n */\nexport const shellSkipReason = (code: ShellSkipReasonCode, detail?: string): ShellSkipReason => ({\n code,\n message: detail === undefined || detail.length === 0 ? MESSAGES[code] : `${MESSAGES[code]} (${detail})`,\n});\n"]}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRewritableFile = void 0;
|
|
4
|
+
exports.parseTsestreeSource = parseTsestreeSource;
|
|
5
|
+
exports.findClassnameLocations = findClassnameLocations;
|
|
6
|
+
exports.buildClassnameEdits = buildClassnameEdits;
|
|
7
|
+
exports.buildEditsForLocation = buildEditsForLocation;
|
|
8
|
+
exports.applyEdits = applyEdits;
|
|
9
|
+
exports.transformClassnamesUnderSourceRoot = transformClassnamesUnderSourceRoot;
|
|
10
|
+
exports.visitRewritableFiles = visitRewritableFiles;
|
|
11
|
+
const devkit_1 = require("@nx/devkit");
|
|
12
|
+
const css_classname_utils_1 = require("@trackunit/css-classname-utils");
|
|
13
|
+
const types_1 = require("@typescript-eslint/types");
|
|
14
|
+
const typescript_estree_1 = require("@typescript-eslint/typescript-estree");
|
|
15
|
+
/**
|
|
16
|
+
* Shared TSESTree parsing/traversal/splice helpers for classname-rewriting Nx
|
|
17
|
+
* migrations (the `p-content-space-codemod` and any future codemod that needs
|
|
18
|
+
* to detect and rewrite Tailwind classnames across a Tree).
|
|
19
|
+
*
|
|
20
|
+
* `@trackunit/css-classname-utils`'s detection helpers
|
|
21
|
+
* (`findClassnameStringsInAttribute`/`InCall`/`InVariable`) expect TSESTree AST
|
|
22
|
+
* nodes, which today only ESLint's parser produces in this repo. Nx migrations
|
|
23
|
+
* run outside of ESLint, so this module wraps
|
|
24
|
+
* `@typescript-eslint/typescript-estree`'s `parse` (the same underlying parser
|
|
25
|
+
* `@typescript-eslint/parser` delegates to) to turn a raw source string into an
|
|
26
|
+
* equivalent TSESTree `Program`, then re-splices edits directly against the
|
|
27
|
+
* original source string by AST node range (mirroring the range-splice
|
|
28
|
+
* approach `insertAttributeIntoOpeningTag` in
|
|
29
|
+
* `libs/react/components/migrations/utils/jsx-utils.ts` uses for the
|
|
30
|
+
* TypeScript-compiler-API case).
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Parses raw TypeScript/TSX source into a TSESTree `Program` AST.
|
|
34
|
+
*
|
|
35
|
+
* `jsx: true` is always passed (harmless for plain `.ts` files) so callers
|
|
36
|
+
* don't need to branch on file extension before parsing.
|
|
37
|
+
*/
|
|
38
|
+
function parseTsestreeSource(content) {
|
|
39
|
+
return (0, typescript_estree_1.parse)(content, { jsx: true, loc: true, range: true });
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Finds every classname string location in a parsed source: JSX
|
|
43
|
+
* `className`/`class` attributes, Tailwind-function calls (`cva`, `cn`,
|
|
44
|
+
* `clsx`, etc. — see `TAILWIND_FUNCTIONS`), and
|
|
45
|
+
* `*Class`/`*ClassName`/`*Classes`-suffixed variable declarators.
|
|
46
|
+
*
|
|
47
|
+
* Walks the AST with `simpleTraverse` (shipped by
|
|
48
|
+
* `@typescript-eslint/typescript-estree`) instead of a hand-rolled
|
|
49
|
+
* visitor-keys walker, since it already knows every node type's visitor keys
|
|
50
|
+
* for the resolved parser version.
|
|
51
|
+
*/
|
|
52
|
+
function findClassnameLocations(program) {
|
|
53
|
+
const locations = [];
|
|
54
|
+
(0, typescript_estree_1.simpleTraverse)(program, {
|
|
55
|
+
enter: node => {
|
|
56
|
+
if (node.type === types_1.AST_NODE_TYPES.JSXAttribute) {
|
|
57
|
+
locations.push(...(0, css_classname_utils_1.findClassnameStringsInAttribute)(node));
|
|
58
|
+
}
|
|
59
|
+
else if (node.type === types_1.AST_NODE_TYPES.CallExpression) {
|
|
60
|
+
locations.push(...(0, css_classname_utils_1.findClassnameStringsInCall)(node));
|
|
61
|
+
}
|
|
62
|
+
else if (node.type === types_1.AST_NODE_TYPES.VariableDeclarator) {
|
|
63
|
+
locations.push(...(0, css_classname_utils_1.findClassnameStringsInVariable)(node));
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
return locations;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Builds the edit(s) needed to apply `transform` to a `ClassnameLocation`'s
|
|
71
|
+
* `fixNode`, splicing by the node's own `.range` against the original source
|
|
72
|
+
* (there is no ESLint `SourceCode`/fixer available outside of rule
|
|
73
|
+
* execution).
|
|
74
|
+
*
|
|
75
|
+
* - `Literal`: one edit replacing the whole quoted literal, preserving the
|
|
76
|
+
* original quote style via `quoteString`.
|
|
77
|
+
* - `TemplateLiteral`: one edit per quasi whose raw text changes, splicing
|
|
78
|
+
* only the text between the surrounding backtick/`${`/`}` delimiters so the
|
|
79
|
+
* template's interpolated expressions are left untouched.
|
|
80
|
+
*
|
|
81
|
+
* Returns an empty array when `transform` doesn't change the value, so
|
|
82
|
+
* callers can cheaply detect "no-op" locations.
|
|
83
|
+
*
|
|
84
|
+
* Prefer {@link buildEditsForLocation} when the caller has a full
|
|
85
|
+
* `ClassnameLocation` — that path can drop an emptied JSX `className`
|
|
86
|
+
* attribute entirely instead of leaving `className=""`.
|
|
87
|
+
*/
|
|
88
|
+
function buildClassnameEdits(fixNode, transform) {
|
|
89
|
+
if (fixNode.type === types_1.AST_NODE_TYPES.Literal) {
|
|
90
|
+
if (typeof fixNode.value !== "string")
|
|
91
|
+
return [];
|
|
92
|
+
const newValue = transform(fixNode.value);
|
|
93
|
+
if (newValue === fixNode.value)
|
|
94
|
+
return [];
|
|
95
|
+
return [{ range: fixNode.range, text: (0, css_classname_utils_1.quoteString)(newValue, fixNode) }];
|
|
96
|
+
}
|
|
97
|
+
const edits = [];
|
|
98
|
+
for (const quasi of fixNode.quasis) {
|
|
99
|
+
const newRaw = transform(quasi.value.raw);
|
|
100
|
+
if (newRaw === quasi.value.raw)
|
|
101
|
+
continue;
|
|
102
|
+
const start = quasi.range[0] + 1;
|
|
103
|
+
const end = quasi.range[1] - (quasi.tail ? 1 : 2);
|
|
104
|
+
edits.push({ range: [start, end], text: newRaw });
|
|
105
|
+
}
|
|
106
|
+
return edits;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Like {@link buildClassnameEdits}, but when a JSX `className`/`class`
|
|
110
|
+
* attribute's token list becomes empty, removes the whole attribute
|
|
111
|
+
* (including a single run of preceding horizontal whitespace) instead of
|
|
112
|
+
* writing `className=""`.
|
|
113
|
+
*
|
|
114
|
+
* Non-JSX locations (cva/cn/clsx calls, `*ClassName` variables) still fall
|
|
115
|
+
* through to an empty-string literal — deleting those would require
|
|
116
|
+
* statement-level surgery we deliberately do not attempt here.
|
|
117
|
+
*/
|
|
118
|
+
function buildEditsForLocation(location, transform, sourceContent) {
|
|
119
|
+
const { fixNode, context, reportNode } = location;
|
|
120
|
+
if (context.type === "jsx-attribute" &&
|
|
121
|
+
reportNode.type === types_1.AST_NODE_TYPES.JSXAttribute &&
|
|
122
|
+
fixNode.type === types_1.AST_NODE_TYPES.Literal &&
|
|
123
|
+
typeof fixNode.value === "string") {
|
|
124
|
+
const newValue = transform(fixNode.value);
|
|
125
|
+
if (newValue === fixNode.value)
|
|
126
|
+
return [];
|
|
127
|
+
if (newValue === "") {
|
|
128
|
+
return [buildJsxAttributeRemovalEdit(reportNode, sourceContent)];
|
|
129
|
+
}
|
|
130
|
+
return [{ range: fixNode.range, text: (0, css_classname_utils_1.quoteString)(newValue, fixNode) }];
|
|
131
|
+
}
|
|
132
|
+
return buildClassnameEdits(fixNode, transform);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Removes a JSX attribute, swallowing the horizontal whitespace immediately
|
|
136
|
+
* before it so `<div className="x">` becomes `<div>` rather than `<div >`.
|
|
137
|
+
*/
|
|
138
|
+
function buildJsxAttributeRemovalEdit(attribute, sourceContent) {
|
|
139
|
+
let start = attribute.range[0];
|
|
140
|
+
while (start > 0 && /[ \t]/.test(sourceContent[start - 1] ?? "")) {
|
|
141
|
+
start -= 1;
|
|
142
|
+
}
|
|
143
|
+
return { range: [start, attribute.range[1]], text: "" };
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Applies a batch of range-based edits to `content`, splicing in
|
|
147
|
+
* reverse-offset order so that an earlier edit's range is never invalidated
|
|
148
|
+
* by one applied after it.
|
|
149
|
+
*/
|
|
150
|
+
function applyEdits(content, edits) {
|
|
151
|
+
const byDescendingStart = [...edits].sort((a, b) => b.range[0] - a.range[0]);
|
|
152
|
+
let result = content;
|
|
153
|
+
for (const edit of byDescendingStart) {
|
|
154
|
+
const [start, end] = edit.range;
|
|
155
|
+
result = result.slice(0, start) + edit.text + result.slice(end);
|
|
156
|
+
}
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
const REWRITABLE_EXTENSIONS = [".ts", ".tsx"];
|
|
160
|
+
/**
|
|
161
|
+
* Manifest files must never be mutated by a classname-rewriting migration
|
|
162
|
+
* (a hard Success Criterion of GLU-1570). No in-repo extension currently
|
|
163
|
+
* declares a `sourceRoot` that overlaps its own manifest file, but this
|
|
164
|
+
* filename guard is defense-in-depth so that invariant doesn't depend
|
|
165
|
+
* entirely on that data convention holding forever.
|
|
166
|
+
*/
|
|
167
|
+
const MANIFEST_FILENAME_PATTERN = /(^|\/)(iris-app-manifest|extension-manifest)\.ts$/;
|
|
168
|
+
/**
|
|
169
|
+
* `true` for `.ts`/`.tsx` files a classname-rewriting migration is allowed
|
|
170
|
+
* to read/write — excludes `iris-app-manifest.ts`/`extension-manifest.ts`
|
|
171
|
+
* files. Shared by every transform/report module in this codemod so the
|
|
172
|
+
* file-extension allowlist and manifest exclusion live in exactly one place.
|
|
173
|
+
*/
|
|
174
|
+
const isRewritableFile = (filePath) => REWRITABLE_EXTENSIONS.some(ext => filePath.endsWith(ext)) && !MANIFEST_FILENAME_PATTERN.test(filePath);
|
|
175
|
+
exports.isRewritableFile = isRewritableFile;
|
|
176
|
+
/**
|
|
177
|
+
* Walks every rewritable file under `sourceRoot`, and for files passing the
|
|
178
|
+
* cheap `shouldConsider` substring pre-check, parses them, finds every
|
|
179
|
+
* classname location, applies `transform` to each, and writes back any file
|
|
180
|
+
* that actually changed.
|
|
181
|
+
*
|
|
182
|
+
* Shared by `rewritePageContent` and `removeRedundantPadding` so the
|
|
183
|
+
* walk → pre-filter → parse → find → edit → write skeleton lives in exactly
|
|
184
|
+
* one place instead of being duplicated per transform.
|
|
185
|
+
*/
|
|
186
|
+
function transformClassnamesUnderSourceRoot(tree, sourceRoot, shouldConsider, transform) {
|
|
187
|
+
const filesChanged = [];
|
|
188
|
+
(0, devkit_1.visitNotIgnoredFiles)(tree, sourceRoot, filePath => {
|
|
189
|
+
if (!(0, exports.isRewritableFile)(filePath))
|
|
190
|
+
return;
|
|
191
|
+
const content = tree.read(filePath, "utf-8");
|
|
192
|
+
if (content === null || !shouldConsider(content))
|
|
193
|
+
return;
|
|
194
|
+
const program = parseTsestreeSource(content);
|
|
195
|
+
const locations = findClassnameLocations(program);
|
|
196
|
+
const edits = locations.flatMap(location => buildEditsForLocation(location, transform, content));
|
|
197
|
+
if (edits.length === 0)
|
|
198
|
+
return;
|
|
199
|
+
tree.write(filePath, applyEdits(content, edits));
|
|
200
|
+
filesChanged.push(filePath);
|
|
201
|
+
});
|
|
202
|
+
return { filesChanged };
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Read-only walk of every rewritable file under `sourceRoot`, invoking
|
|
206
|
+
* `visitor` with each file's path and content. Never writes. Shared by
|
|
207
|
+
* `findUnresolvedSurface`'s detection pass, which only needs to inspect
|
|
208
|
+
* content, not rewrite it.
|
|
209
|
+
*/
|
|
210
|
+
function visitRewritableFiles(tree, sourceRoot, visitor) {
|
|
211
|
+
(0, devkit_1.visitNotIgnoredFiles)(tree, sourceRoot, filePath => {
|
|
212
|
+
if (!(0, exports.isRewritableFile)(filePath))
|
|
213
|
+
return;
|
|
214
|
+
const content = tree.read(filePath, "utf-8");
|
|
215
|
+
if (content === null)
|
|
216
|
+
return;
|
|
217
|
+
visitor(filePath, content);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=classname-ast-rewrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classname-ast-rewrite.js","sourceRoot":"","sources":["../../../../../../libs/iris-app-sdk/iris-app/migrations/utils/classname-ast-rewrite.ts"],"names":[],"mappings":"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","sourcesContent":["import { visitNotIgnoredFiles, type Tree } from \"@nx/devkit\";\nimport {\n findClassnameStringsInAttribute,\n findClassnameStringsInCall,\n findClassnameStringsInVariable,\n quoteString,\n type ClassnameLocation,\n} from \"@trackunit/css-classname-utils\";\nimport { AST_NODE_TYPES, type TSESTree } from \"@typescript-eslint/types\";\nimport { parse, simpleTraverse } from \"@typescript-eslint/typescript-estree\";\n\n/**\n * Shared TSESTree parsing/traversal/splice helpers for classname-rewriting Nx\n * migrations (the `p-content-space-codemod` and any future codemod that needs\n * to detect and rewrite Tailwind classnames across a Tree).\n *\n * `@trackunit/css-classname-utils`'s detection helpers\n * (`findClassnameStringsInAttribute`/`InCall`/`InVariable`) expect TSESTree AST\n * nodes, which today only ESLint's parser produces in this repo. Nx migrations\n * run outside of ESLint, so this module wraps\n * `@typescript-eslint/typescript-estree`'s `parse` (the same underlying parser\n * `@typescript-eslint/parser` delegates to) to turn a raw source string into an\n * equivalent TSESTree `Program`, then re-splices edits directly against the\n * original source string by AST node range (mirroring the range-splice\n * approach `insertAttributeIntoOpeningTag` in\n * `libs/react/components/migrations/utils/jsx-utils.ts` uses for the\n * TypeScript-compiler-API case).\n */\n\n/**\n * Parses raw TypeScript/TSX source into a TSESTree `Program` AST.\n *\n * `jsx: true` is always passed (harmless for plain `.ts` files) so callers\n * don't need to branch on file extension before parsing.\n */\nexport function parseTsestreeSource(content: string): TSESTree.Program {\n return parse(content, { jsx: true, loc: true, range: true });\n}\n\n/**\n * Finds every classname string location in a parsed source: JSX\n * `className`/`class` attributes, Tailwind-function calls (`cva`, `cn`,\n * `clsx`, etc. — see `TAILWIND_FUNCTIONS`), and\n * `*Class`/`*ClassName`/`*Classes`-suffixed variable declarators.\n *\n * Walks the AST with `simpleTraverse` (shipped by\n * `@typescript-eslint/typescript-estree`) instead of a hand-rolled\n * visitor-keys walker, since it already knows every node type's visitor keys\n * for the resolved parser version.\n */\nexport function findClassnameLocations(program: TSESTree.Program): Array<ClassnameLocation> {\n const locations: Array<ClassnameLocation> = [];\n\n simpleTraverse(program, {\n enter: node => {\n if (node.type === AST_NODE_TYPES.JSXAttribute) {\n locations.push(...findClassnameStringsInAttribute(node));\n } else if (node.type === AST_NODE_TYPES.CallExpression) {\n locations.push(...findClassnameStringsInCall(node));\n } else if (node.type === AST_NODE_TYPES.VariableDeclarator) {\n locations.push(...findClassnameStringsInVariable(node));\n }\n },\n });\n\n return locations;\n}\n\n/** A single range-based text splice against the original source string. */\nexport type ClassnameEdit = {\n range: TSESTree.Range;\n text: string;\n};\n\n/**\n * Builds the edit(s) needed to apply `transform` to a `ClassnameLocation`'s\n * `fixNode`, splicing by the node's own `.range` against the original source\n * (there is no ESLint `SourceCode`/fixer available outside of rule\n * execution).\n *\n * - `Literal`: one edit replacing the whole quoted literal, preserving the\n * original quote style via `quoteString`.\n * - `TemplateLiteral`: one edit per quasi whose raw text changes, splicing\n * only the text between the surrounding backtick/`${`/`}` delimiters so the\n * template's interpolated expressions are left untouched.\n *\n * Returns an empty array when `transform` doesn't change the value, so\n * callers can cheaply detect \"no-op\" locations.\n *\n * Prefer {@link buildEditsForLocation} when the caller has a full\n * `ClassnameLocation` — that path can drop an emptied JSX `className`\n * attribute entirely instead of leaving `className=\"\"`.\n */\nexport function buildClassnameEdits(\n fixNode: ClassnameLocation[\"fixNode\"],\n transform: (value: string) => string\n): Array<ClassnameEdit> {\n if (fixNode.type === AST_NODE_TYPES.Literal) {\n if (typeof fixNode.value !== \"string\") return [];\n const newValue = transform(fixNode.value);\n if (newValue === fixNode.value) return [];\n return [{ range: fixNode.range, text: quoteString(newValue, fixNode) }];\n }\n\n const edits: Array<ClassnameEdit> = [];\n for (const quasi of fixNode.quasis) {\n const newRaw = transform(quasi.value.raw);\n if (newRaw === quasi.value.raw) continue;\n const start = quasi.range[0] + 1;\n const end = quasi.range[1] - (quasi.tail ? 1 : 2);\n edits.push({ range: [start, end], text: newRaw });\n }\n return edits;\n}\n\n/**\n * Like {@link buildClassnameEdits}, but when a JSX `className`/`class`\n * attribute's token list becomes empty, removes the whole attribute\n * (including a single run of preceding horizontal whitespace) instead of\n * writing `className=\"\"`.\n *\n * Non-JSX locations (cva/cn/clsx calls, `*ClassName` variables) still fall\n * through to an empty-string literal — deleting those would require\n * statement-level surgery we deliberately do not attempt here.\n */\nexport function buildEditsForLocation(\n location: ClassnameLocation,\n transform: (value: string) => string,\n sourceContent: string\n): Array<ClassnameEdit> {\n const { fixNode, context, reportNode } = location;\n\n if (\n context.type === \"jsx-attribute\" &&\n reportNode.type === AST_NODE_TYPES.JSXAttribute &&\n fixNode.type === AST_NODE_TYPES.Literal &&\n typeof fixNode.value === \"string\"\n ) {\n const newValue = transform(fixNode.value);\n if (newValue === fixNode.value) return [];\n if (newValue === \"\") {\n return [buildJsxAttributeRemovalEdit(reportNode, sourceContent)];\n }\n return [{ range: fixNode.range, text: quoteString(newValue, fixNode) }];\n }\n\n return buildClassnameEdits(fixNode, transform);\n}\n\n/**\n * Removes a JSX attribute, swallowing the horizontal whitespace immediately\n * before it so `<div className=\"x\">` becomes `<div>` rather than `<div >`.\n */\nfunction buildJsxAttributeRemovalEdit(attribute: TSESTree.JSXAttribute, sourceContent: string): ClassnameEdit {\n let start = attribute.range[0];\n while (start > 0 && /[ \\t]/.test(sourceContent[start - 1] ?? \"\")) {\n start -= 1;\n }\n return { range: [start, attribute.range[1]], text: \"\" };\n}\n\n/**\n * Applies a batch of range-based edits to `content`, splicing in\n * reverse-offset order so that an earlier edit's range is never invalidated\n * by one applied after it.\n */\nexport function applyEdits(content: string, edits: ReadonlyArray<ClassnameEdit>): string {\n const byDescendingStart = [...edits].sort((a, b) => b.range[0] - a.range[0]);\n\n let result = content;\n for (const edit of byDescendingStart) {\n const [start, end] = edit.range;\n result = result.slice(0, start) + edit.text + result.slice(end);\n }\n return result;\n}\n\nconst REWRITABLE_EXTENSIONS: Array<string> = [\".ts\", \".tsx\"];\n\n/**\n * Manifest files must never be mutated by a classname-rewriting migration\n * (a hard Success Criterion of GLU-1570). No in-repo extension currently\n * declares a `sourceRoot` that overlaps its own manifest file, but this\n * filename guard is defense-in-depth so that invariant doesn't depend\n * entirely on that data convention holding forever.\n */\nconst MANIFEST_FILENAME_PATTERN = /(^|\\/)(iris-app-manifest|extension-manifest)\\.ts$/;\n\n/**\n * `true` for `.ts`/`.tsx` files a classname-rewriting migration is allowed\n * to read/write — excludes `iris-app-manifest.ts`/`extension-manifest.ts`\n * files. Shared by every transform/report module in this codemod so the\n * file-extension allowlist and manifest exclusion live in exactly one place.\n */\nexport const isRewritableFile = (filePath: string): boolean =>\n REWRITABLE_EXTENSIONS.some(ext => filePath.endsWith(ext)) && !MANIFEST_FILENAME_PATTERN.test(filePath);\n\n/**\n * Walks every rewritable file under `sourceRoot`, and for files passing the\n * cheap `shouldConsider` substring pre-check, parses them, finds every\n * classname location, applies `transform` to each, and writes back any file\n * that actually changed.\n *\n * Shared by `rewritePageContent` and `removeRedundantPadding` so the\n * walk → pre-filter → parse → find → edit → write skeleton lives in exactly\n * one place instead of being duplicated per transform.\n */\nexport function transformClassnamesUnderSourceRoot(\n tree: Tree,\n sourceRoot: string,\n shouldConsider: (content: string) => boolean,\n transform: (value: string) => string\n): { filesChanged: Array<string> } {\n const filesChanged: Array<string> = [];\n\n visitNotIgnoredFiles(tree, sourceRoot, filePath => {\n if (!isRewritableFile(filePath)) return;\n\n const content = tree.read(filePath, \"utf-8\");\n if (content === null || !shouldConsider(content)) return;\n\n const program = parseTsestreeSource(content);\n const locations = findClassnameLocations(program);\n const edits = locations.flatMap(location => buildEditsForLocation(location, transform, content));\n if (edits.length === 0) return;\n\n tree.write(filePath, applyEdits(content, edits));\n filesChanged.push(filePath);\n });\n\n return { filesChanged };\n}\n\n/**\n * Read-only walk of every rewritable file under `sourceRoot`, invoking\n * `visitor` with each file's path and content. Never writes. Shared by\n * `findUnresolvedSurface`'s detection pass, which only needs to inspect\n * content, not rewrite it.\n */\nexport function visitRewritableFiles(\n tree: Tree,\n sourceRoot: string,\n visitor: (filePath: string, content: string) => void\n): void {\n visitNotIgnoredFiles(tree, sourceRoot, filePath => {\n if (!isRewritableFile(filePath)) return;\n const content = tree.read(filePath, \"utf-8\");\n if (content === null) return;\n visitor(filePath, content);\n });\n}\n"]}
|