@eui/core 22.0.0-alpha.4 → 22.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +97 -0
- package/docs/changelog.html +229 -0
- package/docs/interfaces/Edit-2.html +1 -1
- package/docs/interfaces/Edit-3.html +1 -1
- package/docs/interfaces/Schema-10.html +1 -1
- package/docs/interfaces/Schema-11.html +1 -1
- package/docs/interfaces/Schema-12.html +1 -1
- package/docs/interfaces/Schema-13.html +1 -1
- package/docs/interfaces/Schema-14.html +1 -1
- package/docs/interfaces/Schema-15.html +1 -1
- package/docs/interfaces/Schema-16.html +1 -1
- package/docs/interfaces/Schema-17.html +1 -1
- package/docs/interfaces/Schema-18.html +1 -1
- package/docs/interfaces/Schema-19.html +1 -1
- package/docs/interfaces/Schema-20.html +1 -1
- package/docs/interfaces/Schema-5.html +1 -1
- package/docs/interfaces/Schema-6.html +1 -1
- package/docs/interfaces/Schema-9.html +1 -1
- package/docs/js/search/search_index.js +2 -2
- package/docs/json/documentation.json +624 -624
- package/docs/llms.txt +64 -64
- package/docs/miscellaneous/functions.html +437 -437
- package/docs/miscellaneous/variables.html +10 -10
- package/docs/properties.html +1 -1
- package/package.json +2 -2
|
@@ -850,12 +850,12 @@
|
|
|
850
850
|
},
|
|
851
851
|
{
|
|
852
852
|
"name": "Edit",
|
|
853
|
-
"id": "interface-Edit-
|
|
854
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
853
|
+
"id": "interface-Edit-91c9f900bf3ebb82488fb65644938ef486ceaa447cff8bfd9d710df9595d82acb267b26f3c252173bc684353f362473120226426ed7ee5d98b33e30011dd9383-1",
|
|
854
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
855
855
|
"deprecated": false,
|
|
856
856
|
"deprecationMessage": "",
|
|
857
857
|
"type": "interface",
|
|
858
|
-
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\nconst OLD_TAG = 'eui-toolbar-menu';\nconst NEW_TAG = 'eui-toolbar-mega-menu';\nconst OLD_COMPONENT = 'EuiToolbarMenuComponent';\nconst NEW_COMPONENT = 'EuiToolbarMegaMenuComponent';\nconst OLD_INTERFACE = 'ToolbarItem';\nconst NEW_INTERFACE = 'EuiMenuItem';\nconst NEW_COMPONENT_PATH = '@eui/components/layout';\nconst NEW_INTERFACE_PATH = '@eui/core';\nconst REMOVED_OUTPUT = 'menuItemClick';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\ninterface Edit {\n start: number;\n end: number;\n replacement: string;\n}\n\nexport function migrateEuiToolbarMenu(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let fileCount = 0;\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(OLD_TAG) && !original.includes(OLD_COMPONENT) && !original.includes(OLD_INTERFACE)) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original, path, context);\n } else {\n result = migrateTypeScript(original, path, context);\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-toolbar-menu → eui-toolbar-mega-menu in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n fileCount++;\n }\n });\n\n context.logger.info(`Migrated eui-toolbar-menu → eui-toolbar-mega-menu in ${fileCount} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n\n visitNodes(parsed.nodes, source, edits, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): string {\n let result = migrateInlineTemplates(source, filePath, context);\n result = migrateImportsAndTypes(result, filePath, context);\n return result;\n}\n\nfunction migrateInlineTemplates(source: string, filePath: string, context: SchematicContext): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(OLD_TAG)) {\n ts.forEachChild(node, visit); return; \n}\n const migrated = migrateTemplate(rawTemplate, filePath, context);\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, changes);\n}\n\nfunction migrateImportsAndTypes(source: string, filePath: string, context: SchematicContext): string {\n if (!source.includes(OLD_COMPONENT) && !source.includes(OLD_INTERFACE)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Track if EuiMenuItem is already imported from @eui/core\n let hasEuiMenuItemImport = false;\n\n // First pass: analyze imports\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpec = (stmt.moduleSpecifier as ts.StringLiteral).text;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n for (const specifier of namedBindings.elements) {\n if (specifier.name.text === NEW_INTERFACE && moduleSpec === NEW_INTERFACE_PATH) {\n hasEuiMenuItemImport = true;\n }\n }\n }\n\n // Second pass: collect edits for import declarations\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n const moduleSpec = stmt.moduleSpecifier as ts.StringLiteral;\n const specifiers = namedBindings.elements;\n const hasComponent = specifiers.some((s) => s.name.text === OLD_COMPONENT);\n const hasInterface = specifiers.some((s) => s.name.text === OLD_INTERFACE);\n\n if (hasComponent && hasInterface) {\n // Both are in the same import → must split into two different paths\n const others = specifiers.filter((s) => s.name.text !== OLD_COMPONENT && s.name.text !== OLD_INTERFACE);\n const lines: string[] = [];\n lines.push(`import { ${NEW_COMPONENT} } from '${NEW_COMPONENT_PATH}';`);\n if (!hasEuiMenuItemImport) {\n lines.push(`import { ${NEW_INTERFACE} } from '${NEW_INTERFACE_PATH}';`);\n }\n if (others.length > 0) {\n const otherNames = others.map((s) => s.name.text).join(', ');\n lines.push(`import { ${otherNames} } from '${moduleSpec.text}';`);\n }\n edits.push({\n start: stmt.getStart(sourceFile),\n end: stmt.getEnd(),\n replacement: lines.join('\\n'),\n });\n } else if (hasComponent) {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_COMPONENT_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_COMPONENT) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_COMPONENT,\n });\n }\n }\n } else if (hasInterface) {\n if (hasEuiMenuItemImport) {\n removeImportSpecifier(namedBindings, specifiers.find((s) => s.name.text === OLD_INTERFACE)!, sourceFile, edits);\n } else {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_INTERFACE_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_INTERFACE) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_INTERFACE,\n });\n }\n }\n }\n }\n }\n\n // Third pass: rename identifier references in non-import positions\n const visitRefs = (node: ts.Node): void => {\n if (ts.isImportDeclaration(node)) return; // skip imports (already handled)\n if (ts.isIdentifier(node)) {\n if (node.text === OLD_COMPONENT) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_COMPONENT });\n }\n if (node.text === OLD_INTERFACE) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_INTERFACE });\n }\n }\n ts.forEachChild(node, visitRefs);\n };\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) {\n visitRefs(stmt);\n }\n }\n\n // Warn about ToolbarItem-specific properties\n warnRemovedProperties(sourceFile, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction removeImportSpecifier(\n namedImports: ts.NamedImports,\n specifier: ts.ImportSpecifier,\n sourceFile: ts.SourceFile,\n edits: Edit[],\n): void {\n const elements = namedImports.elements;\n if (elements.length === 1) {\n // Remove the entire import declaration\n const importDecl = namedImports.parent.parent;\n edits.push({\n start: importDecl.getStart(sourceFile),\n end: importDecl.getEnd(),\n replacement: '',\n });\n } else {\n // Remove just this specifier with surrounding comma/whitespace\n const idx = elements.indexOf(specifier);\n let start: number;\n let end: number;\n if (idx < elements.length - 1) {\n start = specifier.getStart(sourceFile);\n end = elements[idx + 1].getStart(sourceFile);\n } else {\n start = elements[idx - 1].getEnd();\n end = specifier.getEnd();\n }\n edits.push({ start, end, replacement: '' });\n }\n}\n\nfunction warnRemovedProperties(sourceFile: ts.SourceFile, filePath: string, context: SchematicContext): void {\n const deprecated = ['isHome', 'isSeparator'];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === OLD_TAG) {\n collectTagRenames(node, source, edits);\n collectOutputRemovals(node, source, edits, filePath, context);\n }\n visitNodes(node.children, source, edits, filePath, context);\n }\n }\n}\n\nfunction collectTagRenames(element: TmplAstElement, source: string, edits: Edit[]): void {\n // Rename opening tag\n const openStart = element.startSourceSpan.start.offset + 1; // skip '<'\n edits.push({ start: openStart, end: openStart + OLD_TAG.length, replacement: NEW_TAG });\n\n // Rename closing tag\n if (element.endSourceSpan) {\n const closeStart = element.endSourceSpan.start.offset + 2; // skip '</'\n edits.push({ start: closeStart, end: closeStart + OLD_TAG.length, replacement: NEW_TAG });\n }\n}\n\nfunction collectOutputRemovals(\n element: TmplAstElement,\n source: string,\n edits: Edit[],\n filePath: string,\n context: SchematicContext,\n): void {\n for (const output of element.outputs) {\n if (output.name === REMOVED_OUTPUT) {\n let start = output.sourceSpan.start.offset;\n // Remove leading whitespace\n while (start > 0 && (source[start - 1] === ' ' || source[start - 1] === '\\t')) {\n start--;\n }\n edits.push({ start, end: output.sourceSpan.end.offset, replacement: '' });\n\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(menuItemClick)\" has been removed. There is no equivalent on eui-toolbar-mega-menu.`,\n );\n }\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n // Deduplicate edits at same position (e.g. module path edits when both Component and ToolbarItem are from same source)\n const unique = deduplicateEdits(edits);\n let result = source;\n for (const edit of unique.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction deduplicateEdits(edits: Edit[]): Edit[] {\n const seen = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n // Last wins for same range\n seen.set(key, edit);\n }\n return Array.from(seen.values());\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
858
|
+
"sourceCode": "import { BindingPipe, parseTemplate, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstBoundText, TmplAstElement, TmplAstNode, TmplAstTemplate, TmplAstTextAttribute, AST, ASTWithSource, Interpolation } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Edit { start: number; end: number; replacement: string; }\n\n// --- Table-level input renames (on elements with euiTable attribute) ---\nconst TABLE_INPUT_RENAMES = new Map([\n ['rows', 'data'],\n ['loading', 'isLoading'],\n ['asyncTable', 'isAsync'],\n ['euiTableResponsive', 'isTableResponsive'],\n ['euiTableFixedLayout', 'isTableFixedLayout'],\n ['euiTableCompact', 'isTableCompact'],\n ['hasStickyColumns', 'hasStickyCols'],\n]);\n\n// --- Child element input renames (scoped to euiTable context) ---\nconst TH_TD_INPUT_RENAMES = new Map([\n ['isStickyColumn', 'isStickyCol'],\n ['sortable', 'isSortable'],\n]);\n\nconst TR_INPUT_RENAMES = new Map([\n ['isSelectableHeader', 'isHeaderSelectable'],\n ['isSelectable', 'isDataSelectable'],\n]);\n\n// --- Removed inputs ---\nconst REMOVED_INPUTS = new Set(['euiTableBordered', 'isHoverable', 'defaultMultiOrder', 'paginable']);\n\n// --- Output renames/removals ---\nconst OUTPUT_RENAMES = new Map([['selectedRows', 'rowsSelect']]);\nconst REMOVED_OUTPUTS = new Set(['multiSortChange']);\n\n// --- Pipe rename ---\nconst OLD_PIPE = 'euiTableHighlightFilter';\nconst NEW_PIPE = 'euiTableHighlight';\n\n// --- TS property renames ---\nconst TS_PROPERTY_RENAMES = new Map([['filteredRows', 'getFilteredData']]);\n\nconst PAGINATOR_IMPORT_PATH = '@eui/components/eui-paginator';\nconst PAGINATOR_COMPONENT = 'EuiPaginatorComponent';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nexport function migrateEuiTable(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const paginatorHtmlFiles = new Set<string>();\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes('euiTable') && !original.includes(OLD_PIPE) && !original.includes('filteredRows') && !original.includes('setSort')) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n const { output, hasPaginator } = migrateTemplateWithPaginator(original, path, context);\n result = output;\n if (hasPaginator) paginatorHtmlFiles.add(path);\n } else {\n const { output, hasPaginator } = migrateTypeScript(original, path, context);\n result = output;\n if (hasPaginator) {\n result = addPaginatorImport(result, path);\n }\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-table breaking changes in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n });\n\n // Handle paginator imports for external templates\n if (paginatorHtmlFiles.size > 0) {\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n if (!path.endsWith('.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const source = buffer.toString('utf-8');\n if (!source.includes('templateUrl')) return;\n\n for (const htmlFile of paginatorHtmlFiles) {\n const htmlFileName = htmlFile.split('/').pop()!;\n if (source.includes(htmlFileName)) {\n const updated = addPaginatorImport(source, path);\n if (updated !== source) {\n if (options.dryRun) {\n logDryRun(context, `Would add paginator import in ${path}`);\n } else {\n tree.overwrite(path, updated);\n }\n count++;\n }\n break;\n }\n }\n });\n }\n\n context.logger.info(`Migrated eui-table in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplateWithPaginator(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n let hasPaginator = false;\n\n const paginatorResult = visitNodesForTable(parsed.nodes, source, edits, false, filePath, context);\n if (paginatorResult) hasPaginator = true;\n\n collectPipeRenames(parsed.nodes, source, edits);\n\n return { output: applyEdits(source, edits), hasPaginator };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n return migrateTemplateWithPaginator(source, filePath, context).output;\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n let result = source;\n let hasPaginator = false;\n\n // Migrate inline templates\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = result.slice(start, end);\n if (!rawTemplate.includes('euiTable') && !rawTemplate.includes(OLD_PIPE)) {\n ts.forEachChild(node, visit); return;\n}\n const { output: migrated, hasPaginator: pag } = migrateTemplateWithPaginator(rawTemplate, filePath, context);\n if (pag) hasPaginator = true;\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n result = applyEdits(result, changes);\n\n // Rename TS property accesses\n result = renameTsProperties(result);\n\n // Warn about setSort\n warnSetSort(result, filePath, context);\n\n return { output: result, hasPaginator };\n}\n\nfunction renameTsProperties(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && TS_PROPERTY_RENAMES.has(node.name.text)) {\n edits.push({ start: node.name.getStart(sourceFile), end: node.name.getEnd(), replacement: TS_PROPERTY_RENAMES.get(node.name.text)! });\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, edits);\n}\n\nfunction warnSetSort(source: string, filePath: string, context: SchematicContext): void {\n if (!source.includes('setSort')) return;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) &&\n ts.isIdentifier(node.expression.name) && node.expression.name.text === 'setSort') {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"setSort\" signature changed from setSort(sort: string, order: \"asc\" | \"desc\") to setSort(Sort[]). Update manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\n// --- Template AST visitors ---\n\nfunction visitNodesForTable(\n nodes: TmplAstNode[], source: string, edits: Edit[], insideEuiTable: boolean, filePath: string, context: SchematicContext,\n): boolean {\n let hasPaginator = false;\n\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n const isEuiTable = hasEuiTableAttribute(node);\n\n if (isEuiTable) {\n collectTableInputRenames(node, edits);\n collectInputRemovals(node, source, edits, filePath, context);\n collectOutputChanges(node, source, edits, filePath, context);\n if (collectPaginatorMigration(node, source, edits)) hasPaginator = true;\n }\n\n if (isEuiTable || insideEuiTable) {\n collectChildElementRenames(node, edits);\n collectChildInputRemovals(node, source, edits, filePath, context);\n collectEmptyMessageRename(node, edits);\n }\n\n const childResult = visitNodesForTable(node.children, source, edits, isEuiTable || insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n\n if (node instanceof TmplAstTemplate) {\n if (insideEuiTable) {\n collectTemplateEmptyMessageRename(node, edits);\n }\n const childResult = visitNodesForTable(node.children, source, edits, insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n }\n\n return hasPaginator;\n}\n\nfunction hasEuiTableAttribute(element: TmplAstElement): boolean {\n return element.attributes.some((a) => a.name === 'euiTable') ||\n element.inputs.some((i) => i.name === 'euiTable');\n}\n\nfunction collectTableInputRenames(element: TmplAstElement, edits: Edit[]): void {\n for (const attr of element.attributes) {\n const newName = TABLE_INPUT_RENAMES.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = TABLE_INPUT_RENAMES.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildElementRenames(element: TmplAstElement, edits: Edit[]): void {\n const renames = (element.name === 'th' || element.name === 'td') ? TH_TD_INPUT_RENAMES\n : element.name === 'tr' ? TR_INPUT_RENAMES : null;\n if (!renames) return;\n\n for (const attr of element.attributes) {\n const newName = renames.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = renames.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n const childRemovedInputs = new Set(['defaultMultiOrder']);\n\n for (const attr of element.attributes) {\n if (childRemovedInputs.has(attr.name)) {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (childRemovedInputs.has(input.name)) {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const attr of element.attributes) {\n if (REMOVED_INPUTS.has(attr.name) && attr.name !== 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (REMOVED_INPUTS.has(input.name) && input.name !== 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectOutputChanges(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const output of element.outputs) {\n const newName = OUTPUT_RENAMES.get(output.name);\n if (newName) {\n edits.push({ start: output.keySpan!.start.offset, end: output.keySpan!.end.offset, replacement: newName });\n }\n if (REMOVED_OUTPUTS.has(output.name)) {\n removeAttribute(output.sourceSpan.start.offset, output.sourceSpan.end.offset, source, edits);\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(${output.name})\" removed. Multi-sort is now supported by (sortChange) output.`,\n );\n }\n }\n}\n\nfunction collectPaginatorMigration(element: TmplAstElement, source: string, edits: Edit[]): boolean {\n let found = false;\n\n for (const attr of element.attributes) {\n if (attr.name === 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n for (const input of element.inputs) {\n if (input.name === 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n\n if (found) {\n // Add [paginator]=\"paginator\" before closing > of opening tag\n const insertPos = element.startSourceSpan.end.offset - 1;\n edits.push({ start: insertPos, end: insertPos, replacement: ' [paginator]=\"paginator\"' });\n\n // Add eui-paginator after </table>\n if (element.endSourceSpan) {\n const afterTable = element.endSourceSpan.end.offset;\n edits.push({\n start: afterTable,\n end: afterTable,\n replacement: '\\n<!-- TODO: Configure paginator and implement onPageChange handler -->\\n<eui-paginator #paginator [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\" />',\n });\n }\n }\n\n return found;\n}\n\nfunction collectEmptyMessageRename(element: TmplAstElement, edits: Edit[]): void {\n // Handle direct attribute on elements (unlikely but handle)\n for (const attr of element.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\nfunction collectTemplateEmptyMessageRename(template: TmplAstTemplate, edits: Edit[]): void {\n for (const attr of template.templateAttrs) {\n if (attr instanceof TmplAstTextAttribute && attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n for (const attr of template.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\n// --- Pipe rename via AST ---\n\nfunction collectPipeRenames(nodes: TmplAstNode[], source: string, edits: Edit[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n for (const output of node.outputs) {\n if (output.handler) visitExpressionForPipes(output.handler, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstTemplate) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstBoundText) {\n visitExpressionForPipes(node.value, edits);\n }\n }\n}\n\nfunction visitExpressionForPipes(expr: AST, edits: Edit[]): void {\n if (expr instanceof ASTWithSource && expr.ast) {\n visitAstForPipes(expr.ast, edits);\n } else {\n visitAstForPipes(expr, edits);\n }\n}\n\nfunction visitAstForPipes(ast: AST, edits: Edit[]): void {\n if (ast instanceof BindingPipe) {\n if (ast.name === OLD_PIPE && ast.nameSpan) {\n edits.push({ start: ast.nameSpan.start, end: ast.nameSpan.end, replacement: NEW_PIPE });\n }\n visitAstForPipes(ast.exp, edits);\n for (const arg of ast.args) {\n visitAstForPipes(arg, edits);\n }\n return;\n }\n\n if (ast instanceof Interpolation) {\n for (const expr of ast.expressions) {\n visitAstForPipes(expr, edits);\n }\n return;\n }\n\n // Recursively visit all properties that could contain AST nodes\n for (const key of Object.keys(ast)) {\n // eslint-disable-next-line\n const val = (ast as any)[key];\n if (val instanceof AST) {\n visitAstForPipes(val, edits);\n } else if (Array.isArray(val)) {\n for (const item of val) {\n if (item instanceof AST) visitAstForPipes(item, edits);\n }\n }\n }\n}\n\n// --- Import handling for paginator ---\n\nfunction addPaginatorImport(source: string, filePath: string): string {\n if (source.includes(PAGINATOR_COMPONENT)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Add import statement after last import\n let lastImportEnd = 0;\n for (const stmt of sourceFile.statements) {\n if (ts.isImportDeclaration(stmt)) {\n lastImportEnd = stmt.getEnd();\n }\n }\n\n if (lastImportEnd > 0) {\n edits.push({\n start: lastImportEnd,\n end: lastImportEnd,\n replacement: `\\nimport { ${PAGINATOR_COMPONENT} } from '${PAGINATOR_IMPORT_PATH}';`,\n });\n }\n\n // Add to component imports array\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === 'imports' && isComponentMetadataProperty(node)) {\n if (ts.isArrayLiteralExpression(node.initializer)) {\n const arr = node.initializer;\n const elements = arr.elements;\n if (elements.length > 0) {\n const lastElement = elements[elements.length - 1];\n edits.push({\n start: lastElement.getEnd(),\n end: lastElement.getEnd(),\n replacement: `, ${PAGINATOR_COMPONENT}`,\n });\n } else {\n const insertPos = arr.getStart(sourceFile) + 1;\n edits.push({ start: insertPos, end: insertPos, replacement: PAGINATOR_COMPONENT });\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return applyEdits(source, edits);\n}\n\n// --- Helpers ---\n\nfunction removeAttribute(start: number, end: number, source: string, edits: Edit[]): void {\n let adjustedStart = start;\n while (adjustedStart > 0 && (source[adjustedStart - 1] === ' ' || source[adjustedStart - 1] === '\\t')) {\n adjustedStart--;\n }\n edits.push({ start: adjustedStart, end, replacement: '' });\n}\n\nfunction logRemovalWarning(name: string, filePath: string, element: TmplAstElement, context: SchematicContext): void {\n const { line } = element.startSourceSpan.start;\n if (name === 'defaultMultiOrder') {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed. Use setSort(Sort[]) to initialize sorting.`);\n } else {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed to align to Design System.`);\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n const unique = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n unique.set(key, edit);\n }\n let result = source;\n for (const edit of [...unique.values()].sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
859
859
|
"displayName": "Edit",
|
|
860
860
|
"properties": [
|
|
861
861
|
{
|
|
@@ -867,7 +867,7 @@
|
|
|
867
867
|
"indexKey": "",
|
|
868
868
|
"optional": false,
|
|
869
869
|
"description": "",
|
|
870
|
-
"line":
|
|
870
|
+
"line": 6,
|
|
871
871
|
"rawdescription": "\n"
|
|
872
872
|
},
|
|
873
873
|
{
|
|
@@ -879,7 +879,7 @@
|
|
|
879
879
|
"indexKey": "",
|
|
880
880
|
"optional": false,
|
|
881
881
|
"description": "",
|
|
882
|
-
"line":
|
|
882
|
+
"line": 6,
|
|
883
883
|
"rawdescription": "\n"
|
|
884
884
|
},
|
|
885
885
|
{
|
|
@@ -891,7 +891,7 @@
|
|
|
891
891
|
"indexKey": "",
|
|
892
892
|
"optional": false,
|
|
893
893
|
"description": "",
|
|
894
|
-
"line":
|
|
894
|
+
"line": 6,
|
|
895
895
|
"rawdescription": "\n"
|
|
896
896
|
}
|
|
897
897
|
],
|
|
@@ -909,12 +909,12 @@
|
|
|
909
909
|
},
|
|
910
910
|
{
|
|
911
911
|
"name": "Edit",
|
|
912
|
-
"id": "interface-Edit-
|
|
913
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
912
|
+
"id": "interface-Edit-e1cd02924eb82a618c71a0b26c081bdd020519d2699aa0e2dc98640c4e0f347c3649b967c5fc87543e41bbbfabd1304835850ccc38f40684d6521c242b2030ed-2",
|
|
913
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
914
914
|
"deprecated": false,
|
|
915
915
|
"deprecationMessage": "",
|
|
916
916
|
"type": "interface",
|
|
917
|
-
"sourceCode": "import { BindingPipe, parseTemplate, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstBoundText, TmplAstElement, TmplAstNode, TmplAstTemplate, TmplAstTextAttribute, AST, ASTWithSource, Interpolation } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Edit { start: number; end: number; replacement: string; }\n\n// --- Table-level input renames (on elements with euiTable attribute) ---\nconst TABLE_INPUT_RENAMES = new Map([\n ['rows', 'data'],\n ['loading', 'isLoading'],\n ['asyncTable', 'isAsync'],\n ['euiTableResponsive', 'isTableResponsive'],\n ['euiTableFixedLayout', 'isTableFixedLayout'],\n ['euiTableCompact', 'isTableCompact'],\n ['hasStickyColumns', 'hasStickyCols'],\n]);\n\n// --- Child element input renames (scoped to euiTable context) ---\nconst TH_TD_INPUT_RENAMES = new Map([\n ['isStickyColumn', 'isStickyCol'],\n ['sortable', 'isSortable'],\n]);\n\nconst TR_INPUT_RENAMES = new Map([\n ['isSelectableHeader', 'isHeaderSelectable'],\n ['isSelectable', 'isDataSelectable'],\n]);\n\n// --- Removed inputs ---\nconst REMOVED_INPUTS = new Set(['euiTableBordered', 'isHoverable', 'defaultMultiOrder', 'paginable']);\n\n// --- Output renames/removals ---\nconst OUTPUT_RENAMES = new Map([['selectedRows', 'rowsSelect']]);\nconst REMOVED_OUTPUTS = new Set(['multiSortChange']);\n\n// --- Pipe rename ---\nconst OLD_PIPE = 'euiTableHighlightFilter';\nconst NEW_PIPE = 'euiTableHighlight';\n\n// --- TS property renames ---\nconst TS_PROPERTY_RENAMES = new Map([['filteredRows', 'getFilteredData']]);\n\nconst PAGINATOR_IMPORT_PATH = '@eui/components/eui-paginator';\nconst PAGINATOR_COMPONENT = 'EuiPaginatorComponent';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nexport function migrateEuiTable(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const paginatorHtmlFiles = new Set<string>();\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes('euiTable') && !original.includes(OLD_PIPE) && !original.includes('filteredRows') && !original.includes('setSort')) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n const { output, hasPaginator } = migrateTemplateWithPaginator(original, path, context);\n result = output;\n if (hasPaginator) paginatorHtmlFiles.add(path);\n } else {\n const { output, hasPaginator } = migrateTypeScript(original, path, context);\n result = output;\n if (hasPaginator) {\n result = addPaginatorImport(result, path);\n }\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-table breaking changes in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n });\n\n // Handle paginator imports for external templates\n if (paginatorHtmlFiles.size > 0) {\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n if (!path.endsWith('.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const source = buffer.toString('utf-8');\n if (!source.includes('templateUrl')) return;\n\n for (const htmlFile of paginatorHtmlFiles) {\n const htmlFileName = htmlFile.split('/').pop()!;\n if (source.includes(htmlFileName)) {\n const updated = addPaginatorImport(source, path);\n if (updated !== source) {\n if (options.dryRun) {\n logDryRun(context, `Would add paginator import in ${path}`);\n } else {\n tree.overwrite(path, updated);\n }\n count++;\n }\n break;\n }\n }\n });\n }\n\n context.logger.info(`Migrated eui-table in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplateWithPaginator(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n let hasPaginator = false;\n\n const paginatorResult = visitNodesForTable(parsed.nodes, source, edits, false, filePath, context);\n if (paginatorResult) hasPaginator = true;\n\n collectPipeRenames(parsed.nodes, source, edits);\n\n return { output: applyEdits(source, edits), hasPaginator };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n return migrateTemplateWithPaginator(source, filePath, context).output;\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n let result = source;\n let hasPaginator = false;\n\n // Migrate inline templates\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = result.slice(start, end);\n if (!rawTemplate.includes('euiTable') && !rawTemplate.includes(OLD_PIPE)) {\n ts.forEachChild(node, visit); return;\n}\n const { output: migrated, hasPaginator: pag } = migrateTemplateWithPaginator(rawTemplate, filePath, context);\n if (pag) hasPaginator = true;\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n result = applyEdits(result, changes);\n\n // Rename TS property accesses\n result = renameTsProperties(result);\n\n // Warn about setSort\n warnSetSort(result, filePath, context);\n\n return { output: result, hasPaginator };\n}\n\nfunction renameTsProperties(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && TS_PROPERTY_RENAMES.has(node.name.text)) {\n edits.push({ start: node.name.getStart(sourceFile), end: node.name.getEnd(), replacement: TS_PROPERTY_RENAMES.get(node.name.text)! });\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, edits);\n}\n\nfunction warnSetSort(source: string, filePath: string, context: SchematicContext): void {\n if (!source.includes('setSort')) return;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) &&\n ts.isIdentifier(node.expression.name) && node.expression.name.text === 'setSort') {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"setSort\" signature changed from setSort(sort: string, order: \"asc\" | \"desc\") to setSort(Sort[]). Update manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\n// --- Template AST visitors ---\n\nfunction visitNodesForTable(\n nodes: TmplAstNode[], source: string, edits: Edit[], insideEuiTable: boolean, filePath: string, context: SchematicContext,\n): boolean {\n let hasPaginator = false;\n\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n const isEuiTable = hasEuiTableAttribute(node);\n\n if (isEuiTable) {\n collectTableInputRenames(node, edits);\n collectInputRemovals(node, source, edits, filePath, context);\n collectOutputChanges(node, source, edits, filePath, context);\n if (collectPaginatorMigration(node, source, edits)) hasPaginator = true;\n }\n\n if (isEuiTable || insideEuiTable) {\n collectChildElementRenames(node, edits);\n collectChildInputRemovals(node, source, edits, filePath, context);\n collectEmptyMessageRename(node, edits);\n }\n\n const childResult = visitNodesForTable(node.children, source, edits, isEuiTable || insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n\n if (node instanceof TmplAstTemplate) {\n if (insideEuiTable) {\n collectTemplateEmptyMessageRename(node, edits);\n }\n const childResult = visitNodesForTable(node.children, source, edits, insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n }\n\n return hasPaginator;\n}\n\nfunction hasEuiTableAttribute(element: TmplAstElement): boolean {\n return element.attributes.some((a) => a.name === 'euiTable') ||\n element.inputs.some((i) => i.name === 'euiTable');\n}\n\nfunction collectTableInputRenames(element: TmplAstElement, edits: Edit[]): void {\n for (const attr of element.attributes) {\n const newName = TABLE_INPUT_RENAMES.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = TABLE_INPUT_RENAMES.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildElementRenames(element: TmplAstElement, edits: Edit[]): void {\n const renames = (element.name === 'th' || element.name === 'td') ? TH_TD_INPUT_RENAMES\n : element.name === 'tr' ? TR_INPUT_RENAMES : null;\n if (!renames) return;\n\n for (const attr of element.attributes) {\n const newName = renames.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = renames.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n const childRemovedInputs = new Set(['defaultMultiOrder']);\n\n for (const attr of element.attributes) {\n if (childRemovedInputs.has(attr.name)) {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (childRemovedInputs.has(input.name)) {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const attr of element.attributes) {\n if (REMOVED_INPUTS.has(attr.name) && attr.name !== 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (REMOVED_INPUTS.has(input.name) && input.name !== 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectOutputChanges(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const output of element.outputs) {\n const newName = OUTPUT_RENAMES.get(output.name);\n if (newName) {\n edits.push({ start: output.keySpan!.start.offset, end: output.keySpan!.end.offset, replacement: newName });\n }\n if (REMOVED_OUTPUTS.has(output.name)) {\n removeAttribute(output.sourceSpan.start.offset, output.sourceSpan.end.offset, source, edits);\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(${output.name})\" removed. Multi-sort is now supported by (sortChange) output.`,\n );\n }\n }\n}\n\nfunction collectPaginatorMigration(element: TmplAstElement, source: string, edits: Edit[]): boolean {\n let found = false;\n\n for (const attr of element.attributes) {\n if (attr.name === 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n for (const input of element.inputs) {\n if (input.name === 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n\n if (found) {\n // Add [paginator]=\"paginator\" before closing > of opening tag\n const insertPos = element.startSourceSpan.end.offset - 1;\n edits.push({ start: insertPos, end: insertPos, replacement: ' [paginator]=\"paginator\"' });\n\n // Add eui-paginator after </table>\n if (element.endSourceSpan) {\n const afterTable = element.endSourceSpan.end.offset;\n edits.push({\n start: afterTable,\n end: afterTable,\n replacement: '\\n<!-- TODO: Configure paginator and implement onPageChange handler -->\\n<eui-paginator #paginator [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\" />',\n });\n }\n }\n\n return found;\n}\n\nfunction collectEmptyMessageRename(element: TmplAstElement, edits: Edit[]): void {\n // Handle direct attribute on elements (unlikely but handle)\n for (const attr of element.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\nfunction collectTemplateEmptyMessageRename(template: TmplAstTemplate, edits: Edit[]): void {\n for (const attr of template.templateAttrs) {\n if (attr instanceof TmplAstTextAttribute && attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n for (const attr of template.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\n// --- Pipe rename via AST ---\n\nfunction collectPipeRenames(nodes: TmplAstNode[], source: string, edits: Edit[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n for (const output of node.outputs) {\n if (output.handler) visitExpressionForPipes(output.handler, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstTemplate) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstBoundText) {\n visitExpressionForPipes(node.value, edits);\n }\n }\n}\n\nfunction visitExpressionForPipes(expr: AST, edits: Edit[]): void {\n if (expr instanceof ASTWithSource && expr.ast) {\n visitAstForPipes(expr.ast, edits);\n } else {\n visitAstForPipes(expr, edits);\n }\n}\n\nfunction visitAstForPipes(ast: AST, edits: Edit[]): void {\n if (ast instanceof BindingPipe) {\n if (ast.name === OLD_PIPE && ast.nameSpan) {\n edits.push({ start: ast.nameSpan.start, end: ast.nameSpan.end, replacement: NEW_PIPE });\n }\n visitAstForPipes(ast.exp, edits);\n for (const arg of ast.args) {\n visitAstForPipes(arg, edits);\n }\n return;\n }\n\n if (ast instanceof Interpolation) {\n for (const expr of ast.expressions) {\n visitAstForPipes(expr, edits);\n }\n return;\n }\n\n // Recursively visit all properties that could contain AST nodes\n for (const key of Object.keys(ast)) {\n // eslint-disable-next-line\n const val = (ast as any)[key];\n if (val instanceof AST) {\n visitAstForPipes(val, edits);\n } else if (Array.isArray(val)) {\n for (const item of val) {\n if (item instanceof AST) visitAstForPipes(item, edits);\n }\n }\n }\n}\n\n// --- Import handling for paginator ---\n\nfunction addPaginatorImport(source: string, filePath: string): string {\n if (source.includes(PAGINATOR_COMPONENT)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Add import statement after last import\n let lastImportEnd = 0;\n for (const stmt of sourceFile.statements) {\n if (ts.isImportDeclaration(stmt)) {\n lastImportEnd = stmt.getEnd();\n }\n }\n\n if (lastImportEnd > 0) {\n edits.push({\n start: lastImportEnd,\n end: lastImportEnd,\n replacement: `\\nimport { ${PAGINATOR_COMPONENT} } from '${PAGINATOR_IMPORT_PATH}';`,\n });\n }\n\n // Add to component imports array\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === 'imports' && isComponentMetadataProperty(node)) {\n if (ts.isArrayLiteralExpression(node.initializer)) {\n const arr = node.initializer;\n const elements = arr.elements;\n if (elements.length > 0) {\n const lastElement = elements[elements.length - 1];\n edits.push({\n start: lastElement.getEnd(),\n end: lastElement.getEnd(),\n replacement: `, ${PAGINATOR_COMPONENT}`,\n });\n } else {\n const insertPos = arr.getStart(sourceFile) + 1;\n edits.push({ start: insertPos, end: insertPos, replacement: PAGINATOR_COMPONENT });\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return applyEdits(source, edits);\n}\n\n// --- Helpers ---\n\nfunction removeAttribute(start: number, end: number, source: string, edits: Edit[]): void {\n let adjustedStart = start;\n while (adjustedStart > 0 && (source[adjustedStart - 1] === ' ' || source[adjustedStart - 1] === '\\t')) {\n adjustedStart--;\n }\n edits.push({ start: adjustedStart, end, replacement: '' });\n}\n\nfunction logRemovalWarning(name: string, filePath: string, element: TmplAstElement, context: SchematicContext): void {\n const { line } = element.startSourceSpan.start;\n if (name === 'defaultMultiOrder') {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed. Use setSort(Sort[]) to initialize sorting.`);\n } else {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed to align to Design System.`);\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n const unique = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n unique.set(key, edit);\n }\n let result = source;\n for (const edit of [...unique.values()].sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
917
|
+
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\nconst OLD_TAG = 'eui-toolbar-menu';\nconst NEW_TAG = 'eui-toolbar-mega-menu';\nconst OLD_COMPONENT = 'EuiToolbarMenuComponent';\nconst NEW_COMPONENT = 'EuiToolbarMegaMenuComponent';\nconst OLD_INTERFACE = 'ToolbarItem';\nconst NEW_INTERFACE = 'EuiMenuItem';\nconst NEW_COMPONENT_PATH = '@eui/components/layout';\nconst NEW_INTERFACE_PATH = '@eui/core';\nconst REMOVED_OUTPUT = 'menuItemClick';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\ninterface Edit {\n start: number;\n end: number;\n replacement: string;\n}\n\nexport function migrateEuiToolbarMenu(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let fileCount = 0;\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(OLD_TAG) && !original.includes(OLD_COMPONENT) && !original.includes(OLD_INTERFACE)) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original, path, context);\n } else {\n result = migrateTypeScript(original, path, context);\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-toolbar-menu → eui-toolbar-mega-menu in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n fileCount++;\n }\n });\n\n context.logger.info(`Migrated eui-toolbar-menu → eui-toolbar-mega-menu in ${fileCount} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n\n visitNodes(parsed.nodes, source, edits, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): string {\n let result = migrateInlineTemplates(source, filePath, context);\n result = migrateImportsAndTypes(result, filePath, context);\n return result;\n}\n\nfunction migrateInlineTemplates(source: string, filePath: string, context: SchematicContext): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(OLD_TAG)) {\n ts.forEachChild(node, visit); return; \n}\n const migrated = migrateTemplate(rawTemplate, filePath, context);\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, changes);\n}\n\nfunction migrateImportsAndTypes(source: string, filePath: string, context: SchematicContext): string {\n if (!source.includes(OLD_COMPONENT) && !source.includes(OLD_INTERFACE)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Track if EuiMenuItem is already imported from @eui/core\n let hasEuiMenuItemImport = false;\n\n // First pass: analyze imports\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpec = (stmt.moduleSpecifier as ts.StringLiteral).text;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n for (const specifier of namedBindings.elements) {\n if (specifier.name.text === NEW_INTERFACE && moduleSpec === NEW_INTERFACE_PATH) {\n hasEuiMenuItemImport = true;\n }\n }\n }\n\n // Second pass: collect edits for import declarations\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n const moduleSpec = stmt.moduleSpecifier as ts.StringLiteral;\n const specifiers = namedBindings.elements;\n const hasComponent = specifiers.some((s) => s.name.text === OLD_COMPONENT);\n const hasInterface = specifiers.some((s) => s.name.text === OLD_INTERFACE);\n\n if (hasComponent && hasInterface) {\n // Both are in the same import → must split into two different paths\n const others = specifiers.filter((s) => s.name.text !== OLD_COMPONENT && s.name.text !== OLD_INTERFACE);\n const lines: string[] = [];\n lines.push(`import { ${NEW_COMPONENT} } from '${NEW_COMPONENT_PATH}';`);\n if (!hasEuiMenuItemImport) {\n lines.push(`import { ${NEW_INTERFACE} } from '${NEW_INTERFACE_PATH}';`);\n }\n if (others.length > 0) {\n const otherNames = others.map((s) => s.name.text).join(', ');\n lines.push(`import { ${otherNames} } from '${moduleSpec.text}';`);\n }\n edits.push({\n start: stmt.getStart(sourceFile),\n end: stmt.getEnd(),\n replacement: lines.join('\\n'),\n });\n } else if (hasComponent) {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_COMPONENT_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_COMPONENT) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_COMPONENT,\n });\n }\n }\n } else if (hasInterface) {\n if (hasEuiMenuItemImport) {\n removeImportSpecifier(namedBindings, specifiers.find((s) => s.name.text === OLD_INTERFACE)!, sourceFile, edits);\n } else {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_INTERFACE_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_INTERFACE) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_INTERFACE,\n });\n }\n }\n }\n }\n }\n\n // Third pass: rename identifier references in non-import positions\n const visitRefs = (node: ts.Node): void => {\n if (ts.isImportDeclaration(node)) return; // skip imports (already handled)\n if (ts.isIdentifier(node)) {\n if (node.text === OLD_COMPONENT) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_COMPONENT });\n }\n if (node.text === OLD_INTERFACE) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_INTERFACE });\n }\n }\n ts.forEachChild(node, visitRefs);\n };\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) {\n visitRefs(stmt);\n }\n }\n\n // Warn about ToolbarItem-specific properties\n warnRemovedProperties(sourceFile, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction removeImportSpecifier(\n namedImports: ts.NamedImports,\n specifier: ts.ImportSpecifier,\n sourceFile: ts.SourceFile,\n edits: Edit[],\n): void {\n const elements = namedImports.elements;\n if (elements.length === 1) {\n // Remove the entire import declaration\n const importDecl = namedImports.parent.parent;\n edits.push({\n start: importDecl.getStart(sourceFile),\n end: importDecl.getEnd(),\n replacement: '',\n });\n } else {\n // Remove just this specifier with surrounding comma/whitespace\n const idx = elements.indexOf(specifier);\n let start: number;\n let end: number;\n if (idx < elements.length - 1) {\n start = specifier.getStart(sourceFile);\n end = elements[idx + 1].getStart(sourceFile);\n } else {\n start = elements[idx - 1].getEnd();\n end = specifier.getEnd();\n }\n edits.push({ start, end, replacement: '' });\n }\n}\n\nfunction warnRemovedProperties(sourceFile: ts.SourceFile, filePath: string, context: SchematicContext): void {\n const deprecated = ['isHome', 'isSeparator'];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === OLD_TAG) {\n collectTagRenames(node, source, edits);\n collectOutputRemovals(node, source, edits, filePath, context);\n }\n visitNodes(node.children, source, edits, filePath, context);\n }\n }\n}\n\nfunction collectTagRenames(element: TmplAstElement, source: string, edits: Edit[]): void {\n // Rename opening tag\n const openStart = element.startSourceSpan.start.offset + 1; // skip '<'\n edits.push({ start: openStart, end: openStart + OLD_TAG.length, replacement: NEW_TAG });\n\n // Rename closing tag\n if (element.endSourceSpan) {\n const closeStart = element.endSourceSpan.start.offset + 2; // skip '</'\n edits.push({ start: closeStart, end: closeStart + OLD_TAG.length, replacement: NEW_TAG });\n }\n}\n\nfunction collectOutputRemovals(\n element: TmplAstElement,\n source: string,\n edits: Edit[],\n filePath: string,\n context: SchematicContext,\n): void {\n for (const output of element.outputs) {\n if (output.name === REMOVED_OUTPUT) {\n let start = output.sourceSpan.start.offset;\n // Remove leading whitespace\n while (start > 0 && (source[start - 1] === ' ' || source[start - 1] === '\\t')) {\n start--;\n }\n edits.push({ start, end: output.sourceSpan.end.offset, replacement: '' });\n\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(menuItemClick)\" has been removed. There is no equivalent on eui-toolbar-mega-menu.`,\n );\n }\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n // Deduplicate edits at same position (e.g. module path edits when both Component and ToolbarItem are from same source)\n const unique = deduplicateEdits(edits);\n let result = source;\n for (const edit of unique.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction deduplicateEdits(edits: Edit[]): Edit[] {\n const seen = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n // Last wins for same range\n seen.set(key, edit);\n }\n return Array.from(seen.values());\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
918
918
|
"displayName": "Edit",
|
|
919
919
|
"properties": [
|
|
920
920
|
{
|
|
@@ -926,7 +926,7 @@
|
|
|
926
926
|
"indexKey": "",
|
|
927
927
|
"optional": false,
|
|
928
928
|
"description": "",
|
|
929
|
-
"line":
|
|
929
|
+
"line": 23,
|
|
930
930
|
"rawdescription": "\n"
|
|
931
931
|
},
|
|
932
932
|
{
|
|
@@ -938,7 +938,7 @@
|
|
|
938
938
|
"indexKey": "",
|
|
939
939
|
"optional": false,
|
|
940
940
|
"description": "",
|
|
941
|
-
"line":
|
|
941
|
+
"line": 24,
|
|
942
942
|
"rawdescription": "\n"
|
|
943
943
|
},
|
|
944
944
|
{
|
|
@@ -950,7 +950,7 @@
|
|
|
950
950
|
"indexKey": "",
|
|
951
951
|
"optional": false,
|
|
952
952
|
"description": "",
|
|
953
|
-
"line":
|
|
953
|
+
"line": 22,
|
|
954
954
|
"rawdescription": "\n"
|
|
955
955
|
}
|
|
956
956
|
],
|
|
@@ -2139,110 +2139,7 @@
|
|
|
2139
2139
|
},
|
|
2140
2140
|
{
|
|
2141
2141
|
"name": "Schema",
|
|
2142
|
-
"id": "interface-Schema-
|
|
2143
|
-
"file": "packages/core/schematics/add-eui-imports/index.ts",
|
|
2144
|
-
"deprecated": false,
|
|
2145
|
-
"deprecationMessage": "",
|
|
2146
|
-
"type": "interface",
|
|
2147
|
-
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode, TmplAstTemplate } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\nimport { SELECTOR_MAP, SelectorEntry, getClassNamesForArray } from './selector-map';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n useClassArray?: boolean;\n}\n\ninterface ImportToAdd {\n /** The symbol to add to imports array (class name or array name for spread) */\n symbol: string;\n /** Whether this should be spread (...EUI_BUTTON) */\n isSpread: boolean;\n /** ES import path */\n importPath: string;\n}\n\nexport function addEuiImports(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n const useClassArray = options.useClassArray ?? false;\n let filesUpdated = 0;\n\n // Index NgModules for standalone:false support\n const ngModuleIndex = buildNgModuleIndex(tree, tree.getDir(scanPath || '/'));\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n if (!path.endsWith('.ts') || path.endsWith('.spec.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n const source = buffer.toString('utf-8');\n\n const sourceFile = ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true);\n const components = findComponentDecorators(sourceFile);\n if (components.length === 0) return;\n\n let modified = false;\n\n for (const { decorator, className: componentClassName, isNonStandalone } of components) {\n const templateHtml = getTemplateContent(tree, path, decorator, source);\n if (!templateHtml) continue;\n\n const matched = matchSelectorsInTemplate(templateHtml);\n if (matched.length === 0) continue;\n\n const importsToAdd = resolveImports(matched, useClassArray);\n if (importsToAdd.length === 0) continue;\n\n if (isNonStandalone) {\n // Find the NgModule that declares this component and add imports there\n const moduleInfo = findDeclaringModule(ngModuleIndex, componentClassName);\n if (!moduleInfo) {\n context.logger.warn(`⚠ Could not find declaring NgModule for ${componentClassName} in ${path}`);\n continue;\n }\n const moduleBuffer = tree.read(moduleInfo.path);\n if (!moduleBuffer) continue;\n const moduleSource = moduleBuffer.toString('utf-8');\n const result = addImportsToFile(moduleSource, moduleInfo.path, moduleInfo.decoratorPos, importsToAdd, useClassArray);\n if (result !== moduleSource) {\n if (options.dryRun) {\n logDryRun(context, `Would add EUI imports to NgModule in ${moduleInfo.path} for component ${componentClassName}`);\n } else {\n tree.overwrite(moduleInfo.path, result);\n }\n modified = true;\n }\n } else {\n // Standalone component — add imports directly\n const currentSource = tree.read(path)!.toString('utf-8');\n const result = addImportsToFile(currentSource, path, decorator.getStart(), importsToAdd, useClassArray);\n if (result !== currentSource) {\n if (options.dryRun) {\n logDryRun(context, `Would add EUI imports to ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n modified = true;\n }\n }\n }\n\n if (modified) filesUpdated++;\n });\n\n context.logger.info(`add-eui-imports: ${filesUpdated} file(s) updated.`);\n if (options.dryRun) logDryRunNote(context);\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\n// --- Selector Matching ---\n\nfunction matchSelectorsInTemplate(html: string): SelectorEntry[] {\n const parsed = parseTemplate(html, '', { preserveWhitespaces: true });\n if (parsed.errors?.length) return [];\n\n const matched: SelectorEntry[] = [];\n visitTemplateNodes(parsed.nodes, matched);\n return matched;\n}\n\nfunction visitTemplateNodes(nodes: TmplAstNode[], matched: SelectorEntry[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n matchElement(node, matched);\n visitTemplateNodes(node.children, matched);\n } else if (node instanceof TmplAstTemplate) {\n visitTemplateNodes(node.children, matched);\n }\n }\n}\n\nfunction matchElement(element: TmplAstElement, matched: SelectorEntry[]): void {\n const tagName = element.name;\n const attrNames = new Set([\n ...element.attributes.map(a => a.name),\n ...element.inputs.map(i => i.name),\n ]);\n\n for (const entry of SELECTOR_MAP) {\n if (entry.element && entry.element !== tagName) continue;\n if (!entry.element && entry.attributes.length === 0) continue;\n if (!entry.attributes.every(attr => attrNames.has(attr))) continue;\n // If no element specified, at least one attribute must match on this element\n if (!entry.element && entry.attributes.length > 0 && !entry.attributes.some(attr => attrNames.has(attr))) continue;\n matched.push(entry);\n }\n}\n\n// --- Import Resolution ---\n\nfunction resolveImports(matched: SelectorEntry[], useClassArray: boolean): ImportToAdd[] {\n const seen = new Set<string>();\n const result: ImportToAdd[] = [];\n\n for (const entry of matched) {\n if (useClassArray && entry.classArray) {\n if (seen.has(entry.classArray)) continue;\n seen.add(entry.classArray);\n result.push({ symbol: entry.classArray, isSpread: true, importPath: entry.importPath });\n } else {\n if (seen.has(entry.className)) continue;\n seen.add(entry.className);\n result.push({ symbol: entry.className, isSpread: false, importPath: entry.importPath });\n }\n }\n\n return result;\n}\n\n// --- Template Extraction ---\n\nfunction getTemplateContent(tree: Tree, tsPath: string, decorator: ts.Decorator, source: string): string | null {\n const call = decorator.expression as ts.CallExpression;\n if (!call.arguments[0] || !ts.isObjectLiteralExpression(call.arguments[0])) return null;\n const metadata = call.arguments[0];\n\n for (const prop of metadata.properties) {\n if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) continue;\n if (prop.name.text === 'template') {\n const init = prop.initializer;\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n return init.text;\n }\n }\n if (prop.name.text === 'templateUrl') {\n if (ts.isStringLiteral(prop.initializer)) {\n const dir = tsPath.substring(0, tsPath.lastIndexOf('/'));\n const templateBuffer = tree.read(`${dir}/${prop.initializer.text}`);\n if (templateBuffer) return templateBuffer.toString('utf-8');\n }\n }\n }\n return null;\n}\n\n// --- Component Decorator Detection ---\n\ninterface ComponentInfo {\n decorator: ts.Decorator;\n className: string;\n isNonStandalone: boolean;\n}\n\nfunction findComponentDecorators(sourceFile: ts.SourceFile): ComponentInfo[] {\n const results: ComponentInfo[] = [];\n const visit = (node: ts.Node): void => {\n if (ts.isClassDeclaration(node) && node.name) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const dec of decs) {\n if (ts.isCallExpression(dec.expression) && ts.isIdentifier(dec.expression.expression) && dec.expression.expression.text === 'Component') {\n const isNonStandalone = hasStandaloneFalse(dec);\n results.push({ decorator: dec, className: node.name.text, isNonStandalone });\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sourceFile);\n return results;\n}\n\nfunction hasStandaloneFalse(decorator: ts.Decorator): boolean {\n const call = decorator.expression as ts.CallExpression;\n if (!call.arguments[0] || !ts.isObjectLiteralExpression(call.arguments[0])) return false;\n for (const prop of call.arguments[0].properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === 'standalone') {\n return prop.initializer.kind === ts.SyntaxKind.FalseKeyword;\n }\n }\n return false;\n}\n\n// --- NgModule Index ---\n\ninterface NgModuleInfo {\n path: string;\n declarations: string[];\n decoratorPos: number;\n}\n\nfunction buildNgModuleIndex(tree: Tree, dir: DirEntry): NgModuleInfo[] {\n const modules: NgModuleInfo[] = [];\n\n visitDir(dir, (path) => {\n if (!path.endsWith('.ts') || path.endsWith('.spec.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n const source = buffer.toString('utf-8');\n if (!source.includes('NgModule')) return;\n\n const sf = ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true);\n const visit = (node: ts.Node): void => {\n if (ts.isClassDeclaration(node)) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const dec of decs) {\n if (ts.isCallExpression(dec.expression) && ts.isIdentifier(dec.expression.expression) && dec.expression.expression.text === 'NgModule') {\n const declarations = extractArrayProperty(dec, 'declarations', source);\n modules.push({ path, declarations, decoratorPos: dec.getStart() });\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n });\n\n return modules;\n}\n\nfunction extractArrayProperty(decorator: ts.Decorator, propName: string, source: string): string[] {\n const call = decorator.expression as ts.CallExpression;\n if (!call.arguments[0] || !ts.isObjectLiteralExpression(call.arguments[0])) return [];\n for (const prop of call.arguments[0].properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === propName) {\n if (ts.isArrayLiteralExpression(prop.initializer)) {\n return prop.initializer.elements\n .filter(ts.isIdentifier)\n .map(id => id.text);\n }\n }\n }\n return [];\n}\n\nfunction findDeclaringModule(modules: NgModuleInfo[], componentClassName: string): NgModuleInfo | undefined {\n return modules.find(m => m.declarations.includes(componentClassName));\n}\n\n// --- Import Addition ---\n\nfunction addImportsToFile(source: string, filePath: string, decoratorStartHint: number, imports: ImportToAdd[], useClassArray: boolean): string {\n const sf = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n // Find the imports array in the decorator closest to decoratorStartHint\n const importsArrayInfo = findDecoratorImportsArray(sf, source, decoratorStartHint);\n if (!importsArrayInfo) return source;\n\n const { arrayNode, decoratorType } = importsArrayInfo;\n\n // Determine what's already in the imports array\n const existingSymbols = new Set<string>();\n const existingSpreads = new Set<string>();\n for (const el of arrayNode.elements) {\n if (ts.isSpreadElement(el) && ts.isIdentifier(el.expression)) {\n existingSpreads.add(el.expression.text);\n } else if (ts.isIdentifier(el)) {\n existingSymbols.add(el.text);\n }\n }\n\n // Filter out already-present imports and compute what to add/remove\n const toAdd: ImportToAdd[] = [];\n const toRemoveFromArray: string[] = []; // individual class names to consolidate\n\n for (const imp of imports) {\n if (imp.isSpread) {\n if (existingSpreads.has(imp.symbol)) continue; // Already has ...EUI_X\n toAdd.push(imp);\n // Consolidate: remove individual class names covered by this array\n if (useClassArray) {\n const coveredClasses = getClassNamesForArray(imp.symbol);\n for (const cls of coveredClasses) {\n if (existingSymbols.has(cls)) toRemoveFromArray.push(cls);\n }\n }\n } else {\n if (existingSymbols.has(imp.symbol)) continue;\n // Also skip if a spread already covers this class\n const coveringArray = imports.find(i => i.isSpread && getClassNamesForArray(i.symbol).includes(imp.symbol));\n if (coveringArray && (existingSpreads.has(coveringArray.symbol) || toAdd.some(a => a.symbol === coveringArray.symbol))) continue;\n toAdd.push(imp);\n }\n }\n\n if (toAdd.length === 0 && toRemoveFromArray.length === 0) return source;\n\n // Build new array content\n let result = source;\n result = updateDecoratorImportsArray(result, filePath, arrayNode, toAdd, toRemoveFromArray);\n\n // Add ES imports\n result = addEsImports(result, filePath, toAdd);\n\n // Remove consolidated class names from ES imports\n if (toRemoveFromArray.length > 0) {\n result = removeFromEsImports(result, filePath, toRemoveFromArray);\n }\n\n return result;\n}\n\ninterface ImportsArrayInfo {\n arrayNode: ts.ArrayLiteralExpression;\n decoratorType: 'Component' | 'NgModule';\n}\n\nfunction findDecoratorImportsArray(sf: ts.SourceFile, source: string, decoratorStartHint: number): ImportsArrayInfo | null {\n let found: ImportsArrayInfo | null = null;\n\n const visit = (node: ts.Node): void => {\n if (found) return;\n if (ts.isClassDeclaration(node)) {\n const decs = ts.getDecorators(node);\n if (!decs) return;\n for (const dec of decs) {\n if (!ts.isCallExpression(dec.expression)) continue;\n if (!ts.isIdentifier(dec.expression.expression)) continue;\n const decName = dec.expression.expression.text;\n if (decName !== 'Component' && decName !== 'NgModule') continue;\n if (Math.abs(dec.getStart() - decoratorStartHint) > 5) continue; // Match by position\n\n const metadata = dec.expression.arguments[0];\n if (!ts.isObjectLiteralExpression(metadata)) continue;\n\n for (const prop of metadata.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === 'imports') {\n if (ts.isArrayLiteralExpression(prop.initializer)) {\n found = { arrayNode: prop.initializer, decoratorType: decName as 'Component' | 'NgModule' };\n return;\n }\n }\n }\n\n // No imports array found — create one\n if (!found && decName === 'Component') {\n // We need to add `imports: []` to the decorator\n // Insert after the last property\n const lastProp = metadata.properties[metadata.properties.length - 1];\n if (lastProp) {\n const insertPos = lastProp.getEnd();\n const indent = detectIndent(source, metadata.getStart());\n const insertion = `,\\n${indent} imports: []`;\n const newSource = source.slice(0, insertPos) + insertion + source.slice(insertPos);\n // Re-parse to get the array node\n const newSf = ts.createSourceFile('', newSource, ts.ScriptTarget.Latest, true);\n const newArray = findImportsArrayInSource(newSf);\n if (newArray) {\n // We can't return a node from a different source file in the general case.\n // Instead, we'll handle the \"no imports array\" case by adding it inline.\n found = null; // Will be handled separately\n }\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\nfunction findImportsArrayInSource(sf: ts.SourceFile): ts.ArrayLiteralExpression | null {\n let found: ts.ArrayLiteralExpression | null = null;\n const visit = (node: ts.Node): void => {\n if (found) return;\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === 'imports' && ts.isArrayLiteralExpression(node.initializer)) {\n found = node.initializer;\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\nfunction updateDecoratorImportsArray(source: string, filePath: string, arrayNode: ts.ArrayLiteralExpression, toAdd: ImportToAdd[], toRemove: string[]): string {\n const sf = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n // Rebuild the array content\n const existingElements: string[] = [];\n for (const el of arrayNode.elements) {\n const text = source.slice(el.getStart(sf), el.getEnd()).trim();\n // Check if this element should be removed (consolidation)\n if (ts.isIdentifier(el) && toRemove.includes(el.text)) continue;\n existingElements.push(text);\n }\n\n // Add new entries\n for (const imp of toAdd) {\n const entry = imp.isSpread ? `...${imp.symbol}` : imp.symbol;\n if (!existingElements.includes(entry)) {\n existingElements.push(entry);\n }\n }\n\n // Determine formatting\n const arrayStart = arrayNode.getStart(sf);\n const arrayEnd = arrayNode.getEnd();\n const originalText = source.slice(arrayStart, arrayEnd);\n const isMultiline = originalText.includes('\\n');\n\n let newArrayText: string;\n if (isMultiline || existingElements.length > 3) {\n const indent = detectIndent(source, arrayStart);\n const itemIndent = indent + ' ';\n newArrayText = `[\\n${existingElements.map(e => `${itemIndent}${e},`).join('\\n')}\\n${indent}]`;\n } else {\n newArrayText = `[${existingElements.join(', ')}]`;\n }\n\n return source.slice(0, arrayStart) + newArrayText + source.slice(arrayEnd);\n}\n\nfunction addEsImports(source: string, filePath: string, imports: ImportToAdd[]): string {\n let result = source;\n\n // Group by import path\n const byPath = new Map<string, string[]>();\n for (const imp of imports) {\n const existing = byPath.get(imp.importPath) || [];\n existing.push(imp.symbol);\n byPath.set(imp.importPath, existing);\n }\n\n for (const [importPath, symbols] of byPath) {\n const sf = ts.createSourceFile(filePath, result, ts.ScriptTarget.Latest, true);\n\n // Check if there's already an import from this path\n const existingImport = sf.statements.find(\n (s): s is ts.ImportDeclaration =>\n ts.isImportDeclaration(s) && ts.isStringLiteral(s.moduleSpecifier) && s.moduleSpecifier.text === importPath,\n );\n\n if (existingImport?.importClause?.namedBindings && ts.isNamedImports(existingImport.importClause.namedBindings)) {\n // Extend existing import\n const namedBindings = existingImport.importClause.namedBindings;\n const existingNames = namedBindings.elements.map(el => el.name.text);\n const newNames = symbols.filter(s => !existingNames.includes(s));\n if (newNames.length === 0) continue;\n\n const allNames = [...existingNames, ...newNames].sort();\n const newClause = `{ ${allNames.join(', ')} }`;\n result = result.slice(0, namedBindings.getStart(sf)) + newClause + result.slice(namedBindings.getEnd());\n } else {\n // Add new import statement\n const sortedSymbols = [...symbols].sort();\n const newImport = `import { ${sortedSymbols.join(', ')} } from '${importPath}';\\n`;\n\n // Insert after the last existing import\n const lastImport = [...sf.statements].reverse().find(ts.isImportDeclaration);\n if (lastImport) {\n const pos = lastImport.getEnd();\n result = result.slice(0, pos) + '\\n' + newImport.trimEnd() + result.slice(pos);\n } else {\n result = newImport + result;\n }\n }\n }\n\n return result;\n}\n\nfunction detectIndent(source: string, pos: number): string {\n const lineStart = source.lastIndexOf('\\n', pos - 1) + 1;\n const match = source.slice(lineStart, pos).match(/^(\\s*)/);\n return match ? match[1] : '';\n}\n\nfunction removeFromEsImports(source: string, filePath: string, symbolsToRemove: string[]): string {\n let result = source;\n const sf = ts.createSourceFile(filePath, result, ts.ScriptTarget.Latest, true);\n\n for (const stmt of sf.statements) {\n if (!ts.isImportDeclaration(stmt) || !stmt.importClause?.namedBindings || !ts.isNamedImports(stmt.importClause.namedBindings)) continue;\n const namedBindings = stmt.importClause.namedBindings;\n const existingNames = namedBindings.elements.map(el => el.name.text);\n const remaining = existingNames.filter(n => !symbolsToRemove.includes(n));\n\n if (remaining.length === existingNames.length) continue; // Nothing to remove from this import\n\n if (remaining.length === 0) {\n // Remove the entire import statement\n result = result.slice(0, stmt.getStart(sf)) + result.slice(stmt.getEnd()).replace(/^\\r?\\n/, '');\n } else {\n const newClause = `{ ${remaining.join(', ')} }`;\n result = result.slice(0, namedBindings.getStart(sf)) + newClause + result.slice(namedBindings.getEnd());\n }\n break; // Only process the first matching import for the consolidated symbols\n }\n\n return result;\n}\n",
|
|
2148
|
-
"displayName": "Schema",
|
|
2149
|
-
"properties": [
|
|
2150
|
-
{
|
|
2151
|
-
"name": "dryRun",
|
|
2152
|
-
"coverageIgnore": false,
|
|
2153
|
-
"deprecated": false,
|
|
2154
|
-
"deprecationMessage": "",
|
|
2155
|
-
"type": "boolean",
|
|
2156
|
-
"indexKey": "",
|
|
2157
|
-
"optional": true,
|
|
2158
|
-
"description": "",
|
|
2159
|
-
"line": 9,
|
|
2160
|
-
"rawdescription": "\n"
|
|
2161
|
-
},
|
|
2162
|
-
{
|
|
2163
|
-
"name": "path",
|
|
2164
|
-
"coverageIgnore": false,
|
|
2165
|
-
"deprecated": false,
|
|
2166
|
-
"deprecationMessage": "",
|
|
2167
|
-
"type": "string",
|
|
2168
|
-
"indexKey": "",
|
|
2169
|
-
"optional": true,
|
|
2170
|
-
"description": "",
|
|
2171
|
-
"line": 8,
|
|
2172
|
-
"rawdescription": "\n"
|
|
2173
|
-
},
|
|
2174
|
-
{
|
|
2175
|
-
"name": "useClassArray",
|
|
2176
|
-
"coverageIgnore": false,
|
|
2177
|
-
"deprecated": false,
|
|
2178
|
-
"deprecationMessage": "",
|
|
2179
|
-
"type": "boolean",
|
|
2180
|
-
"indexKey": "",
|
|
2181
|
-
"optional": true,
|
|
2182
|
-
"description": "",
|
|
2183
|
-
"line": 10,
|
|
2184
|
-
"rawdescription": "\n"
|
|
2185
|
-
}
|
|
2186
|
-
],
|
|
2187
|
-
"indexSignatures": [],
|
|
2188
|
-
"kind": 172,
|
|
2189
|
-
"methods": [],
|
|
2190
|
-
"extends": [],
|
|
2191
|
-
"relationships": {
|
|
2192
|
-
"incoming": [],
|
|
2193
|
-
"outgoing": []
|
|
2194
|
-
}
|
|
2195
|
-
},
|
|
2196
|
-
{
|
|
2197
|
-
"name": "Schema",
|
|
2198
|
-
"id": "interface-Schema-4fe31ff3e9f1d34845a6b865d605e215f33552094b88c3d0eab0b180187fe64ce4d68d687516cb3d62c57d2678a103969b2dacbb18a49b26060f78096678fcce-1",
|
|
2199
|
-
"file": "packages/core/schematics/fix-no-multiple-empty-lines/index.ts",
|
|
2200
|
-
"deprecated": false,
|
|
2201
|
-
"deprecationMessage": "",
|
|
2202
|
-
"type": "interface",
|
|
2203
|
-
"sourceCode": "import { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst MULTIPLE_EMPTY_LINES = /\\n{3,}/g;\n\nexport function fixNoMultipleEmptyLines(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (filePath) => {\n const buffer = tree.read(filePath);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n const result = original.replace(MULTIPLE_EMPTY_LINES, '\\n\\n');\n\n if (result !== original) {\n if (filePath.endsWith('.ts')) {\n const sourceFile = ts.createSourceFile(filePath, result, ts.ScriptTarget.Latest, true);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((sourceFile as any).parseDiagnostics?.length) {\n context.logger.warn(`Skipping ${filePath}: file would not parse after transformation.`);\n return;\n }\n }\n if (options.dryRun) {\n logDryRun(context, `Would collapse multiple empty lines in ${filePath}`);\n } else {\n tree.overwrite(filePath, result);\n }\n count++;\n }\n });\n\n context.logger.info(`Fixed multiple empty lines in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.ts') && !file.endsWith('.html') && !file.endsWith('.scss') && !file.endsWith('.css')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
2204
|
-
"displayName": "Schema",
|
|
2205
|
-
"properties": [
|
|
2206
|
-
{
|
|
2207
|
-
"name": "dryRun",
|
|
2208
|
-
"coverageIgnore": false,
|
|
2209
|
-
"deprecated": false,
|
|
2210
|
-
"deprecationMessage": "",
|
|
2211
|
-
"type": "boolean",
|
|
2212
|
-
"indexKey": "",
|
|
2213
|
-
"optional": true,
|
|
2214
|
-
"description": "",
|
|
2215
|
-
"line": 7,
|
|
2216
|
-
"rawdescription": "\n"
|
|
2217
|
-
},
|
|
2218
|
-
{
|
|
2219
|
-
"name": "path",
|
|
2220
|
-
"coverageIgnore": false,
|
|
2221
|
-
"deprecated": false,
|
|
2222
|
-
"deprecationMessage": "",
|
|
2223
|
-
"type": "string",
|
|
2224
|
-
"indexKey": "",
|
|
2225
|
-
"optional": true,
|
|
2226
|
-
"description": "",
|
|
2227
|
-
"line": 6,
|
|
2228
|
-
"rawdescription": "\n"
|
|
2229
|
-
}
|
|
2230
|
-
],
|
|
2231
|
-
"indexSignatures": [],
|
|
2232
|
-
"kind": 172,
|
|
2233
|
-
"methods": [],
|
|
2234
|
-
"extends": [],
|
|
2235
|
-
"isDuplicate": true,
|
|
2236
|
-
"duplicateId": 1,
|
|
2237
|
-
"duplicateName": "Schema-1",
|
|
2238
|
-
"relationships": {
|
|
2239
|
-
"incoming": [],
|
|
2240
|
-
"outgoing": []
|
|
2241
|
-
}
|
|
2242
|
-
},
|
|
2243
|
-
{
|
|
2244
|
-
"name": "Schema",
|
|
2245
|
-
"id": "interface-Schema-5cd6db1920bd5b70a44c0b8a7f7e30f600bfd16a9950f218e6d451a1755ced95b462ef9a62ee87e39bcb8c392981b8d2597895bf0a272fd8aea71f03429ed976-2",
|
|
2142
|
+
"id": "interface-Schema-5cd6db1920bd5b70a44c0b8a7f7e30f600bfd16a9950f218e6d451a1755ced95b462ef9a62ee87e39bcb8c392981b8d2597895bf0a272fd8aea71f03429ed976",
|
|
2246
2143
|
"file": "packages/core/schematics/icon-migrate/schema.ts",
|
|
2247
2144
|
"deprecated": false,
|
|
2248
2145
|
"deprecationMessage": "",
|
|
@@ -2279,9 +2176,6 @@
|
|
|
2279
2176
|
"kind": 172,
|
|
2280
2177
|
"methods": [],
|
|
2281
2178
|
"extends": [],
|
|
2282
|
-
"isDuplicate": true,
|
|
2283
|
-
"duplicateId": 2,
|
|
2284
|
-
"duplicateName": "Schema-2",
|
|
2285
2179
|
"relationships": {
|
|
2286
2180
|
"incoming": [],
|
|
2287
2181
|
"outgoing": []
|
|
@@ -2289,7 +2183,7 @@
|
|
|
2289
2183
|
},
|
|
2290
2184
|
{
|
|
2291
2185
|
"name": "Schema",
|
|
2292
|
-
"id": "interface-Schema-56b9fe60701ca349dc90e152829b0a18bb7a8a9bb303c4bac05f9764cd2e933cce0879775ca17168b4c881e202d0258af3668a2a3a1b940e561f7e4b2349b5cc-
|
|
2186
|
+
"id": "interface-Schema-56b9fe60701ca349dc90e152829b0a18bb7a8a9bb303c4bac05f9764cd2e933cce0879775ca17168b4c881e202d0258af3668a2a3a1b940e561f7e4b2349b5cc-1",
|
|
2293
2187
|
"file": "packages/core/schematics/migrate/schema.ts",
|
|
2294
2188
|
"deprecated": false,
|
|
2295
2189
|
"deprecationMessage": "",
|
|
@@ -2339,8 +2233,8 @@
|
|
|
2339
2233
|
"methods": [],
|
|
2340
2234
|
"extends": [],
|
|
2341
2235
|
"isDuplicate": true,
|
|
2342
|
-
"duplicateId":
|
|
2343
|
-
"duplicateName": "Schema-
|
|
2236
|
+
"duplicateId": 1,
|
|
2237
|
+
"duplicateName": "Schema-1",
|
|
2344
2238
|
"relationships": {
|
|
2345
2239
|
"incoming": [],
|
|
2346
2240
|
"outgoing": []
|
|
@@ -2348,7 +2242,7 @@
|
|
|
2348
2242
|
},
|
|
2349
2243
|
{
|
|
2350
2244
|
"name": "Schema",
|
|
2351
|
-
"id": "interface-Schema-e96d29c1785a16147de773cebe7ab5d4ed82aa23c6b1f7737113252a14d156e236f46f7a16340432dec900b664c8005be0aef5d0a628c2f5b8dd2ec7e41edf56-
|
|
2245
|
+
"id": "interface-Schema-e96d29c1785a16147de773cebe7ab5d4ed82aa23c6b1f7737113252a14d156e236f46f7a16340432dec900b664c8005be0aef5d0a628c2f5b8dd2ec7e41edf56-2",
|
|
2352
2246
|
"file": "packages/core/schematics/migrate-eui-accent/index.ts",
|
|
2353
2247
|
"deprecated": false,
|
|
2354
2248
|
"deprecationMessage": "",
|
|
@@ -2386,8 +2280,8 @@
|
|
|
2386
2280
|
"methods": [],
|
|
2387
2281
|
"extends": [],
|
|
2388
2282
|
"isDuplicate": true,
|
|
2389
|
-
"duplicateId":
|
|
2390
|
-
"duplicateName": "Schema-
|
|
2283
|
+
"duplicateId": 2,
|
|
2284
|
+
"duplicateName": "Schema-2",
|
|
2391
2285
|
"relationships": {
|
|
2392
2286
|
"incoming": [],
|
|
2393
2287
|
"outgoing": []
|
|
@@ -2395,7 +2289,7 @@
|
|
|
2395
2289
|
},
|
|
2396
2290
|
{
|
|
2397
2291
|
"name": "Schema",
|
|
2398
|
-
"id": "interface-Schema-585b211d989563bbec5bd67bcdb58d5f264396adbe0ed2e51d0b4a0ecaf8b3ec36d821647c170d616bb409fc603c5a4c0e699eb7511e02c6add8d8670fc9cb9f-
|
|
2292
|
+
"id": "interface-Schema-585b211d989563bbec5bd67bcdb58d5f264396adbe0ed2e51d0b4a0ecaf8b3ec36d821647c170d616bb409fc603c5a4c0e699eb7511e02c6add8d8670fc9cb9f-3",
|
|
2399
2293
|
"file": "packages/core/schematics/migrate-eui-alert/index.ts",
|
|
2400
2294
|
"deprecated": false,
|
|
2401
2295
|
"deprecationMessage": "",
|
|
@@ -2433,8 +2327,8 @@
|
|
|
2433
2327
|
"methods": [],
|
|
2434
2328
|
"extends": [],
|
|
2435
2329
|
"isDuplicate": true,
|
|
2436
|
-
"duplicateId":
|
|
2437
|
-
"duplicateName": "Schema-
|
|
2330
|
+
"duplicateId": 3,
|
|
2331
|
+
"duplicateName": "Schema-3",
|
|
2438
2332
|
"relationships": {
|
|
2439
2333
|
"incoming": [],
|
|
2440
2334
|
"outgoing": []
|
|
@@ -2442,7 +2336,7 @@
|
|
|
2442
2336
|
},
|
|
2443
2337
|
{
|
|
2444
2338
|
"name": "Schema",
|
|
2445
|
-
"id": "interface-Schema-c7e2cc0add09c97d83ec2675d59c86951681f8e2d49f133fb2f216ca98d0da1fdf892d45af31f19ecbbfd0d32f4ad70dd99e862f75725d3812f66a73ec34362c-
|
|
2339
|
+
"id": "interface-Schema-c7e2cc0add09c97d83ec2675d59c86951681f8e2d49f133fb2f216ca98d0da1fdf892d45af31f19ecbbfd0d32f4ad70dd99e862f75725d3812f66a73ec34362c-4",
|
|
2446
2340
|
"file": "packages/core/schematics/migrate-eui-avatar/index.ts",
|
|
2447
2341
|
"deprecated": false,
|
|
2448
2342
|
"deprecationMessage": "",
|
|
@@ -2480,8 +2374,8 @@
|
|
|
2480
2374
|
"methods": [],
|
|
2481
2375
|
"extends": [],
|
|
2482
2376
|
"isDuplicate": true,
|
|
2483
|
-
"duplicateId":
|
|
2484
|
-
"duplicateName": "Schema-
|
|
2377
|
+
"duplicateId": 4,
|
|
2378
|
+
"duplicateName": "Schema-4",
|
|
2485
2379
|
"relationships": {
|
|
2486
2380
|
"incoming": [],
|
|
2487
2381
|
"outgoing": []
|
|
@@ -2489,7 +2383,7 @@
|
|
|
2489
2383
|
},
|
|
2490
2384
|
{
|
|
2491
2385
|
"name": "Schema",
|
|
2492
|
-
"id": "interface-Schema-c0c08f5e83da9afa13ce8375f982fb280b9bde854e00c914f41b04d44deecd531496c2cee264b50314e92a6260c26cebe35741a2cf5ec068d8b6da5c5267539e-
|
|
2386
|
+
"id": "interface-Schema-c0c08f5e83da9afa13ce8375f982fb280b9bde854e00c914f41b04d44deecd531496c2cee264b50314e92a6260c26cebe35741a2cf5ec068d8b6da5c5267539e-5",
|
|
2493
2387
|
"file": "packages/core/schematics/migrate-eui-button/index.ts",
|
|
2494
2388
|
"deprecated": false,
|
|
2495
2389
|
"deprecationMessage": "",
|
|
@@ -2527,8 +2421,8 @@
|
|
|
2527
2421
|
"methods": [],
|
|
2528
2422
|
"extends": [],
|
|
2529
2423
|
"isDuplicate": true,
|
|
2530
|
-
"duplicateId":
|
|
2531
|
-
"duplicateName": "Schema-
|
|
2424
|
+
"duplicateId": 5,
|
|
2425
|
+
"duplicateName": "Schema-5",
|
|
2532
2426
|
"relationships": {
|
|
2533
2427
|
"incoming": [],
|
|
2534
2428
|
"outgoing": []
|
|
@@ -2536,12 +2430,12 @@
|
|
|
2536
2430
|
},
|
|
2537
2431
|
{
|
|
2538
2432
|
"name": "Schema",
|
|
2539
|
-
"id": "interface-Schema-
|
|
2540
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
2433
|
+
"id": "interface-Schema-39d3d52e788050bebc4e0b99ed0756f7e9727556cb090ae8796bd4261a56463fe1f479c322b23028cd4134d71e4d1dc44cd248ac62a9a148b5fc46a665466f7c-6",
|
|
2434
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
2541
2435
|
"deprecated": false,
|
|
2542
2436
|
"deprecationMessage": "",
|
|
2543
2437
|
"type": "interface",
|
|
2544
|
-
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstElement, TmplAstNode, TmplAstTextAttribute } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\nconst CHIP_LIST_TAG = 'eui-chip-list';\nconst CHIP_LIST_ATTR = 'euiChipList';\nconst CHIP_TAG = 'eui-chip';\nconst CHIP_ATTR = 'euiChip';\n\nconst PROPAGATED_INPUTS = new Set([\n 'euiPrimary', 'euiSecondary', 'euiSuccess', 'euiInfo', 'euiWarning',\n 'euiDanger', 'euiAccent', 'euiVariant', 'euiSizeS', 'euiSizeVariant',\n 'euiOutline', 'euiDisabled',\n]);\n\nconst WARN_PROPERTIES = new Set([...PROPAGATED_INPUTS, 'chipRemove', 'isChipsRemovable', 'chipsLabelTruncateCount',\n 'maxVisibleChipsCount', 'isMaxVisibleChipsOpened', 'toggleLinkMoreLabel', 'toggleLinkLessLabel',\n 'isChipsSorted', 'chipsSortOrder']);\n\nconst REMOVED_INPUTS = new Set(['maxVisibleChipsCount', 'isMaxVisibleChipsOpened', 'toggleLinkMoreLabel', 'toggleLinkLessLabel', 'isChipsSorted', 'chipsSortOrder']);\n\nconst TRUNCATE_PIPE_IMPORT = 'EuiTruncatePipe';\nconst TRUNCATE_PIPE_PATH = '@eui/components/pipes';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\ninterface Edit {\n start: number;\n end: number;\n replacement: string;\n}\n\nexport function migrateEuiChipList(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const filesNeedingTruncateImport = new Set<string>();\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(CHIP_LIST_TAG) && !original.includes(CHIP_LIST_ATTR)) return;\n\n let result: string;\n let addedTruncate = false;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original);\n if (result !== original && result.includes('euiTruncate') && !original.includes('euiTruncate')) {\n // Find the associated .ts file\n const tsPath = path.replace(/\\.html$/, '.ts');\n if (tree.exists(tsPath)) {\n filesNeedingTruncateImport.add(tsPath);\n } else {\n // Try component naming convention\n const componentTsPath = path.replace(/\\.html$/, '.component.ts');\n if (tree.exists(componentTsPath)) {\n filesNeedingTruncateImport.add(componentTsPath);\n }\n }\n }\n } else {\n result = migrateInlineTemplates(original);\n if (result !== original && result.includes('euiTruncate') && !original.includes('euiTruncate')) {\n addedTruncate = true;\n }\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would move variant/size/outline inputs to child eui-chip in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n\n if (addedTruncate) {\n filesNeedingTruncateImport.add(path);\n }\n\n // Warn about TS usages of removed properties\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts')) {\n if ([...WARN_PROPERTIES].some((p) => original.includes(p))) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && WARN_PROPERTIES.has(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${path}:${line + 1} - \"${node.name.text}\" has been removed from eui-chip-list. Move it to individual eui-chip elements.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n }\n });\n\n // Add EuiTruncatePipe import to component files that need it\n for (const tsPath of filesNeedingTruncateImport) {\n const buffer = tree.read(tsPath);\n if (!buffer) continue;\n const source = buffer.toString('utf-8');\n if (source.includes(TRUNCATE_PIPE_IMPORT)) continue;\n const result = addTruncatePipeImport(source, tsPath);\n if (result !== source) {\n if (!options.dryRun) {\n tree.overwrite(tsPath, result);\n }\n }\n }\n\n context.logger.info(`Migrated eui-chip-list inputs/outputs to child eui-chip in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction addTruncatePipeImport(source: string, filePath: string): string {\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n const edits: Edit[] = [];\n\n // 1. Add ES import statement for EuiTruncatePipe\n let hasEsImport = false;\n let lastImportEnd = 0;\n\n for (const stmt of sourceFile.statements) {\n if (ts.isImportDeclaration(stmt)) {\n lastImportEnd = stmt.getEnd();\n const moduleSpec = (stmt.moduleSpecifier as ts.StringLiteral).text;\n if (moduleSpec === TRUNCATE_PIPE_PATH) {\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings && ts.isNamedImports(namedBindings)) {\n if (namedBindings.elements.some((el) => el.name.text === TRUNCATE_PIPE_IMPORT)) {\n hasEsImport = true;\n } else {\n // Add to existing import from same path\n const lastEl = namedBindings.elements[namedBindings.elements.length - 1];\n edits.push({ start: lastEl.getEnd(), end: lastEl.getEnd(), replacement: `, ${TRUNCATE_PIPE_IMPORT}` });\n hasEsImport = true;\n }\n }\n }\n }\n }\n\n if (!hasEsImport) {\n const importStatement = `\\nimport { ${TRUNCATE_PIPE_IMPORT} } from '${TRUNCATE_PIPE_PATH}';`;\n edits.push({ start: lastImportEnd, end: lastImportEnd, replacement: importStatement });\n }\n\n // 2. Add EuiTruncatePipe to @Component imports array\n const visit = (node: ts.Node): void => {\n if (ts.isClassDeclaration(node)) {\n const decs = ts.getDecorators(node);\n if (!decs) return;\n for (const dec of decs) {\n if (!ts.isCallExpression(dec.expression) || !ts.isIdentifier(dec.expression.expression) || dec.expression.expression.text !== 'Component') continue;\n const metadata = dec.expression.arguments[0];\n if (!ts.isObjectLiteralExpression(metadata)) continue;\n for (const prop of metadata.properties) {\n if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name) || prop.name.text !== 'imports') continue;\n if (!ts.isArrayLiteralExpression(prop.initializer)) continue;\n const arr = prop.initializer;\n const arrText = source.slice(arr.getStart(sourceFile), arr.getEnd());\n if (arrText.includes(TRUNCATE_PIPE_IMPORT)) continue;\n if (arr.elements.length > 0) {\n const lastElement = arr.elements[arr.elements.length - 1];\n edits.push({ start: lastElement.getEnd(), end: lastElement.getEnd(), replacement: `,\\n ${TRUNCATE_PIPE_IMPORT}` });\n } else {\n edits.push({ start: arr.getStart(sourceFile) + 1, end: arr.getEnd() - 1, replacement: TRUNCATE_PIPE_IMPORT });\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sourceFile);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n\n visitNodes(parsed.nodes, source, edits);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(CHIP_LIST_TAG) && !rawTemplate.includes(CHIP_LIST_ATTR)) {\n ts.forEachChild(node, visit);\n return;\n }\n const migrated = migrateTemplate(rawTemplate);\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return applyEdits(source, changes);\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, edits: Edit[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (isChipListElement(node)) {\n migrateChipListElement(node, source, edits);\n }\n visitNodes(node.children, source, edits);\n }\n }\n}\n\nfunction isChipListElement(element: TmplAstElement): boolean {\n if (element.name === CHIP_LIST_TAG) return true;\n return element.attributes.some((a) => a.name === CHIP_LIST_ATTR);\n}\n\nfunction isChipElement(element: TmplAstElement): boolean {\n if (element.name === CHIP_TAG) return true;\n return element.attributes.some((a) => a.name === CHIP_ATTR);\n}\n\nfunction findChildChips(nodes: TmplAstNode[]): TmplAstElement[] {\n const chips: TmplAstElement[] = [];\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (isChipElement(node)) {\n chips.push(node);\n } else {\n chips.push(...findChildChips(node.children));\n }\n }\n }\n return chips;\n}\n\nfunction migrateChipListElement(element: TmplAstElement, source: string, edits: Edit[]): void {\n const childChips = findChildChips(element.children);\n const insertions: string[] = [];\n let truncateValue: string | null = null;\n\n // Collect and remove propagated static attributes\n for (const attr of element.attributes) {\n if (PROPAGATED_INPUTS.has(attr.name)) {\n edits.push(removalEdit(attr, source));\n insertions.push(attr.value ? `${attr.name}=\"${attr.value}\"` : attr.name);\n }\n if (attr.name === 'isChipsRemovable') {\n edits.push(removalEdit(attr, source));\n insertions.push('isChipRemovable');\n }\n if (attr.name === 'chipsLabelTruncateCount') {\n edits.push(removalEdit(attr, source));\n truncateValue = attr.value || null;\n }\n if (REMOVED_INPUTS.has(attr.name)) {\n edits.push(removalEdit(attr, source));\n }\n }\n\n // Collect and remove propagated bound inputs\n for (const input of element.inputs) {\n if (PROPAGATED_INPUTS.has(input.name)) {\n edits.push(removalEdit(input, source));\n const raw = source.slice(input.sourceSpan.start.offset, input.sourceSpan.end.offset);\n insertions.push(raw);\n }\n if (input.name === 'isChipsRemovable') {\n edits.push(removalEdit(input, source));\n const valueText = extractBindingValue(input, source);\n insertions.push(`[isChipRemovable]=\"${valueText}\"`);\n }\n if (input.name === 'chipsLabelTruncateCount') {\n edits.push(removalEdit(input, source));\n truncateValue = extractBindingValue(input, source);\n }\n if (REMOVED_INPUTS.has(input.name)) {\n edits.push(removalEdit(input, source));\n }\n }\n\n // Collect and remove (chipRemove) output\n let chipRemoveHandler: string | null = null;\n for (const output of element.outputs) {\n if (output.name === 'chipRemove') {\n edits.push(removalEdit(output, source));\n chipRemoveHandler = extractHandlerExpression(output, source);\n }\n }\n\n if (chipRemoveHandler) {\n insertions.push(`(remove)=\"${chipRemoveHandler}\"`);\n }\n\n // Add collected attributes to each child eui-chip\n if (insertions.length > 0) {\n for (const chip of childChips) {\n const existingNames = getExistingAttrNames(chip);\n const toInsert = insertions.filter((ins) => {\n const name = extractAttrName(ins);\n return !existingNames.has(name);\n });\n if (toInsert.length > 0) {\n const insertPos = chip.startSourceSpan.end.offset - 1;\n edits.push({ start: insertPos, end: insertPos, replacement: ' ' + toInsert.join(' ') });\n }\n }\n }\n\n // Add euiTruncate pipe to chip label content\n if (truncateValue) {\n for (const chip of childChips) {\n const labelEdit = buildTruncatePipeEdit(chip, source, truncateValue);\n if (labelEdit) edits.push(labelEdit);\n }\n }\n}\n\nfunction buildTruncatePipeEdit(chip: TmplAstElement, source: string, truncateValue: string): Edit | null {\n // Find <span euiLabel>...</span> inside the chip\n const labelEl = findLabelElement(chip.children);\n if (labelEl && labelEl.endSourceSpan) {\n const contentStart = labelEl.startSourceSpan.end.offset;\n const contentEnd = labelEl.endSourceSpan.start.offset;\n const content = source.slice(contentStart, contentEnd);\n if (content && !content.includes('euiTruncate')) {\n const trimmed = content.trim();\n const interpMatch = trimmed.match(/^\\{\\{\\s*(.+?)\\s*\\}\\}$/);\n if (interpMatch) {\n return { start: contentStart, end: contentEnd, replacement: `{{ ${interpMatch[1]} | euiTruncate: ${truncateValue} }}` };\n }\n return { start: contentStart, end: contentEnd, replacement: `{{ '${trimmed}' | euiTruncate: ${truncateValue} }}` };\n }\n }\n\n // Check direct text content inside chip (no label element)\n if (chip.endSourceSpan) {\n const chipContentStart = chip.startSourceSpan.end.offset;\n const chipContentEnd = chip.endSourceSpan.start.offset;\n const chipContent = source.slice(chipContentStart, chipContentEnd);\n const trimmed = chipContent.trim();\n const interpMatch = trimmed.match(/^\\{\\{\\s*(.+?)\\s*\\}\\}$/);\n if (interpMatch && !chipContent.includes('euiTruncate')) {\n return { start: chipContentStart, end: chipContentEnd, replacement: `{{ ${interpMatch[1]} | euiTruncate: ${truncateValue} }}` };\n }\n }\n return null;\n}\n\nfunction findLabelElement(nodes: TmplAstNode[]): TmplAstElement | null {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.attributes.some((a) => a.name === 'euiLabel')) return node;\n const nested = findLabelElement(node.children);\n if (nested) return nested;\n }\n }\n return null;\n}\n\nfunction getExistingAttrNames(element: TmplAstElement): Set<string> {\n const names = new Set<string>();\n for (const attr of element.attributes) names.add(attr.name);\n for (const input of element.inputs) names.add(input.name);\n for (const output of element.outputs) names.add(output.name);\n return names;\n}\n\nfunction extractAttrName(insertion: string): string {\n const outputMatch = insertion.match(/^\\(([^)]+)\\)/);\n if (outputMatch) return outputMatch[1];\n const inputMatch = insertion.match(/^\\[([^\\]]+)\\]/);\n if (inputMatch) return inputMatch[1];\n return insertion.split('=')[0];\n}\n\nfunction removalEdit(node: TmplAstTextAttribute | TmplAstBoundAttribute | TmplAstBoundEvent, source: string): Edit {\n let start = node.sourceSpan.start.offset;\n while (start > 0 && (source[start - 1] === ' ' || source[start - 1] === '\\t')) {\n start--;\n }\n return { start, end: node.sourceSpan.end.offset, replacement: '' };\n}\n\nfunction extractBindingValue(input: TmplAstBoundAttribute, source: string): string {\n const raw = source.slice(input.sourceSpan.start.offset, input.sourceSpan.end.offset);\n const match = raw.match(/=[\"']([^\"']*)[\"']/);\n return match ? match[1] : 'true';\n}\n\nfunction extractHandlerExpression(output: TmplAstBoundEvent, source: string): string {\n const raw = source.slice(output.sourceSpan.start.offset, output.sourceSpan.end.offset);\n const match = raw.match(/=[\"']([^\"']*)[\"']/);\n return match ? match[1] : '';\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n const unique = deduplicateEdits(edits);\n let result = source;\n for (const edit of unique.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction deduplicateEdits(edits: Edit[]): Edit[] {\n const seen = new Map<string, Edit>();\n for (const edit of edits) {\n seen.set(`${edit.start}:${edit.end}`, edit);\n }\n return Array.from(seen.values());\n}\n",
|
|
2438
|
+
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstElement, TmplAstNode, TmplAstTextAttribute } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst REMOVED_INPUTS = new Set(['isSquared']);\n\nexport function migrateEuiChip(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes('eui-chip') && !original.includes('euiChip')) return;\n\n const result = path.endsWith('.html')\n ? migrateTemplate(original)\n : migrateInlineTemplates(original);\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would remove 'isSquared' input in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n\n // Warn about TS usages inline\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts') && original.includes('isSquared')) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && node.name.text === 'isSquared') {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(`${path}:${line + 1} - \"isSquared\" is no longer a valid input on eui-chip. Remove this assignment.`);\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n });\n\n context.logger.info(`Removed deprecated eui-chip 'isSquared' input from ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const removals: { start: number; end: number }[] = [];\n\n visitNodes(parsed.nodes, removals);\n\n let result = source;\n for (const { start, end } of removals.sort((a, b) => b.start - a.start)) {\n let adjustedStart = start;\n while (adjustedStart > 0 && (result[adjustedStart - 1] === ' ' || result[adjustedStart - 1] === '\\t')) {\n adjustedStart--;\n }\n result = result.slice(0, adjustedStart) + result.slice(end);\n }\n\n return result;\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const templateRegex = /template\\s*:\\s*`([^`]*)`/gs;\n return source.replace(templateRegex, (match, templateContent: string) => {\n if (!templateContent.includes('eui-chip') && !templateContent.includes('euiChip')) return match;\n const migrated = migrateTemplate(templateContent);\n if (migrated === templateContent) return match;\n return match.replace(templateContent, migrated);\n });\n}\n\nfunction isChipElement(element: TmplAstElement): boolean {\n if (element.name === 'eui-chip') return true;\n return element.attributes.some((a) => a.name === 'euiChip');\n}\n\nfunction visitNodes(nodes: TmplAstNode[], removals: { start: number; end: number }[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (isChipElement(node)) collectRemovals(node, removals);\n visitNodes(node.children, removals);\n }\n }\n}\n\nfunction collectRemovals(element: TmplAstElement, removals: { start: number; end: number }[]): void {\n for (const attr of element.attributes) {\n if (REMOVED_INPUTS.has(attr.name)) {\n removals.push(getAttributeSpan(attr));\n }\n }\n for (const input of element.inputs) {\n if (REMOVED_INPUTS.has(input.name)) {\n removals.push(getAttributeSpan(input));\n }\n }\n}\n\nfunction getAttributeSpan(attr: TmplAstTextAttribute | TmplAstBoundAttribute): { start: number; end: number } {\n return { start: attr.sourceSpan.start.offset, end: attr.sourceSpan.end.offset };\n}\n",
|
|
2545
2439
|
"displayName": "Schema",
|
|
2546
2440
|
"properties": [
|
|
2547
2441
|
{
|
|
@@ -2553,7 +2447,7 @@
|
|
|
2553
2447
|
"indexKey": "",
|
|
2554
2448
|
"optional": true,
|
|
2555
2449
|
"description": "",
|
|
2556
|
-
"line":
|
|
2450
|
+
"line": 8,
|
|
2557
2451
|
"rawdescription": "\n"
|
|
2558
2452
|
},
|
|
2559
2453
|
{
|
|
@@ -2565,7 +2459,7 @@
|
|
|
2565
2459
|
"indexKey": "",
|
|
2566
2460
|
"optional": true,
|
|
2567
2461
|
"description": "",
|
|
2568
|
-
"line":
|
|
2462
|
+
"line": 7,
|
|
2569
2463
|
"rawdescription": "\n"
|
|
2570
2464
|
}
|
|
2571
2465
|
],
|
|
@@ -2574,8 +2468,8 @@
|
|
|
2574
2468
|
"methods": [],
|
|
2575
2469
|
"extends": [],
|
|
2576
2470
|
"isDuplicate": true,
|
|
2577
|
-
"duplicateId":
|
|
2578
|
-
"duplicateName": "Schema-
|
|
2471
|
+
"duplicateId": 6,
|
|
2472
|
+
"duplicateName": "Schema-6",
|
|
2579
2473
|
"relationships": {
|
|
2580
2474
|
"incoming": [],
|
|
2581
2475
|
"outgoing": []
|
|
@@ -2583,12 +2477,12 @@
|
|
|
2583
2477
|
},
|
|
2584
2478
|
{
|
|
2585
2479
|
"name": "Schema",
|
|
2586
|
-
"id": "interface-Schema-
|
|
2587
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2480
|
+
"id": "interface-Schema-311bef7d5e4b40b356b0fdb5e35dd89e48a5c5beec29eeb865c22c2ca1c4c4fb1fd0bb4391ed0b33825a6d1d744bc3a2e9822b347fbc686a537e15b170c279dd-7",
|
|
2481
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
2588
2482
|
"deprecated": false,
|
|
2589
2483
|
"deprecationMessage": "",
|
|
2590
2484
|
"type": "interface",
|
|
2591
|
-
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst COMPONENT_TAG = 'eui-discussion-thread';\n\nexport function migrateEuiDiscussionThread(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(COMPONENT_TAG)) return;\n\n const result = path.endsWith('.html')\n ? migrateTemplate(original)\n : migrateInlineTemplates(original);\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would remove [trackBy] binding in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n\n // Warn about TS usages inline\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts') && original.includes('trackByFn')) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && node.name.text === 'trackByFn') {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(`${path}:${line + 1} - \"trackByFn\" has been removed from ${COMPONENT_TAG}. Remove this reference manually.`);\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n });\n\n context.logger.info(`Removed trackByFn-based [trackBy] bindings from ${COMPONENT_TAG} in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const removals: { start: number; end: number }[] = [];\n\n visitNodes(parsed.nodes, source, removals);\n\n let result = source;\n for (const { start, end } of removals.sort((a, b) => b.start - a.start)) {\n let adjustedStart = start;\n while (adjustedStart > 0 && (result[adjustedStart - 1] === ' ' || result[adjustedStart - 1] === '\\t')) {\n adjustedStart--;\n }\n result = result.slice(0, adjustedStart) + result.slice(end);\n }\n\n return result;\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const templateRegex = /template\\s*:\\s*`([^`]*)`/gs;\n return source.replace(templateRegex, (match, templateContent: string) => {\n if (!templateContent.includes(COMPONENT_TAG)) return match;\n const migrated = migrateTemplate(templateContent);\n if (migrated === templateContent) return match;\n return match.replace(templateContent, migrated);\n });\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, removals: { start: number; end: number }[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === COMPONENT_TAG) collectRemovals(node, source, removals);\n visitNodes(node.children, source, removals);\n }\n }\n}\n\nfunction collectRemovals(element: TmplAstElement, source: string, removals: { start: number; end: number }[]): void {\n for (const input of element.inputs) {\n if (input.name === 'trackBy') {\n const valueSource = source.slice(input.sourceSpan.start.offset, input.sourceSpan.end.offset);\n if (valueSource.includes('trackByFn')) {\n removals.push({ start: input.sourceSpan.start.offset, end: input.sourceSpan.end.offset });\n }\n }\n }\n}\n",
|
|
2485
|
+
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstElement, TmplAstNode, TmplAstTextAttribute } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\nconst CHIP_LIST_TAG = 'eui-chip-list';\nconst CHIP_LIST_ATTR = 'euiChipList';\nconst CHIP_TAG = 'eui-chip';\nconst CHIP_ATTR = 'euiChip';\n\nconst PROPAGATED_INPUTS = new Set([\n 'euiPrimary', 'euiSecondary', 'euiSuccess', 'euiInfo', 'euiWarning',\n 'euiDanger', 'euiAccent', 'euiVariant', 'euiSizeS', 'euiSizeVariant',\n 'euiOutline', 'euiDisabled',\n]);\n\nconst WARN_PROPERTIES = new Set([...PROPAGATED_INPUTS, 'chipRemove', 'isChipsRemovable', 'chipsLabelTruncateCount',\n 'maxVisibleChipsCount', 'isMaxVisibleChipsOpened', 'toggleLinkMoreLabel', 'toggleLinkLessLabel',\n 'isChipsSorted', 'chipsSortOrder']);\n\nconst REMOVED_INPUTS = new Set(['maxVisibleChipsCount', 'isMaxVisibleChipsOpened', 'toggleLinkMoreLabel', 'toggleLinkLessLabel', 'isChipsSorted', 'chipsSortOrder']);\n\nconst TRUNCATE_PIPE_IMPORT = 'EuiTruncatePipe';\nconst TRUNCATE_PIPE_PATH = '@eui/components/pipes';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\ninterface Edit {\n start: number;\n end: number;\n replacement: string;\n}\n\nexport function migrateEuiChipList(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const filesNeedingTruncateImport = new Set<string>();\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(CHIP_LIST_TAG) && !original.includes(CHIP_LIST_ATTR)) return;\n\n let result: string;\n let addedTruncate = false;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original);\n if (result !== original && result.includes('euiTruncate') && !original.includes('euiTruncate')) {\n // Find the associated .ts file\n const tsPath = path.replace(/\\.html$/, '.ts');\n if (tree.exists(tsPath)) {\n filesNeedingTruncateImport.add(tsPath);\n } else {\n // Try component naming convention\n const componentTsPath = path.replace(/\\.html$/, '.component.ts');\n if (tree.exists(componentTsPath)) {\n filesNeedingTruncateImport.add(componentTsPath);\n }\n }\n }\n } else {\n result = migrateInlineTemplates(original);\n if (result !== original && result.includes('euiTruncate') && !original.includes('euiTruncate')) {\n addedTruncate = true;\n }\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would move variant/size/outline inputs to child eui-chip in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n\n if (addedTruncate) {\n filesNeedingTruncateImport.add(path);\n }\n\n // Warn about TS usages of removed properties\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts')) {\n if ([...WARN_PROPERTIES].some((p) => original.includes(p))) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && WARN_PROPERTIES.has(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${path}:${line + 1} - \"${node.name.text}\" has been removed from eui-chip-list. Move it to individual eui-chip elements.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n }\n });\n\n // Add EuiTruncatePipe import to component files that need it\n for (const tsPath of filesNeedingTruncateImport) {\n const buffer = tree.read(tsPath);\n if (!buffer) continue;\n const source = buffer.toString('utf-8');\n if (source.includes(TRUNCATE_PIPE_IMPORT)) continue;\n const result = addTruncatePipeImport(source, tsPath);\n if (result !== source) {\n if (!options.dryRun) {\n tree.overwrite(tsPath, result);\n }\n }\n }\n\n context.logger.info(`Migrated eui-chip-list inputs/outputs to child eui-chip in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction addTruncatePipeImport(source: string, filePath: string): string {\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n const edits: Edit[] = [];\n\n // 1. Add ES import statement for EuiTruncatePipe\n let hasEsImport = false;\n let lastImportEnd = 0;\n\n for (const stmt of sourceFile.statements) {\n if (ts.isImportDeclaration(stmt)) {\n lastImportEnd = stmt.getEnd();\n const moduleSpec = (stmt.moduleSpecifier as ts.StringLiteral).text;\n if (moduleSpec === TRUNCATE_PIPE_PATH) {\n const namedBindings = stmt.importClause?.namedBindings;\n if (namedBindings && ts.isNamedImports(namedBindings)) {\n if (namedBindings.elements.some((el) => el.name.text === TRUNCATE_PIPE_IMPORT)) {\n hasEsImport = true;\n } else {\n // Add to existing import from same path\n const lastEl = namedBindings.elements[namedBindings.elements.length - 1];\n edits.push({ start: lastEl.getEnd(), end: lastEl.getEnd(), replacement: `, ${TRUNCATE_PIPE_IMPORT}` });\n hasEsImport = true;\n }\n }\n }\n }\n }\n\n if (!hasEsImport) {\n const importStatement = `\\nimport { ${TRUNCATE_PIPE_IMPORT} } from '${TRUNCATE_PIPE_PATH}';`;\n edits.push({ start: lastImportEnd, end: lastImportEnd, replacement: importStatement });\n }\n\n // 2. Add EuiTruncatePipe to @Component imports array\n const visit = (node: ts.Node): void => {\n if (ts.isClassDeclaration(node)) {\n const decs = ts.getDecorators(node);\n if (!decs) return;\n for (const dec of decs) {\n if (!ts.isCallExpression(dec.expression) || !ts.isIdentifier(dec.expression.expression) || dec.expression.expression.text !== 'Component') continue;\n const metadata = dec.expression.arguments[0];\n if (!ts.isObjectLiteralExpression(metadata)) continue;\n for (const prop of metadata.properties) {\n if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name) || prop.name.text !== 'imports') continue;\n if (!ts.isArrayLiteralExpression(prop.initializer)) continue;\n const arr = prop.initializer;\n const arrText = source.slice(arr.getStart(sourceFile), arr.getEnd());\n if (arrText.includes(TRUNCATE_PIPE_IMPORT)) continue;\n if (arr.elements.length > 0) {\n const lastElement = arr.elements[arr.elements.length - 1];\n edits.push({ start: lastElement.getEnd(), end: lastElement.getEnd(), replacement: `,\\n ${TRUNCATE_PIPE_IMPORT}` });\n } else {\n edits.push({ start: arr.getStart(sourceFile) + 1, end: arr.getEnd() - 1, replacement: TRUNCATE_PIPE_IMPORT });\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sourceFile);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n\n visitNodes(parsed.nodes, source, edits);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(CHIP_LIST_TAG) && !rawTemplate.includes(CHIP_LIST_ATTR)) {\n ts.forEachChild(node, visit);\n return;\n }\n const migrated = migrateTemplate(rawTemplate);\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return applyEdits(source, changes);\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, edits: Edit[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (isChipListElement(node)) {\n migrateChipListElement(node, source, edits);\n }\n visitNodes(node.children, source, edits);\n }\n }\n}\n\nfunction isChipListElement(element: TmplAstElement): boolean {\n if (element.name === CHIP_LIST_TAG) return true;\n return element.attributes.some((a) => a.name === CHIP_LIST_ATTR);\n}\n\nfunction isChipElement(element: TmplAstElement): boolean {\n if (element.name === CHIP_TAG) return true;\n return element.attributes.some((a) => a.name === CHIP_ATTR);\n}\n\nfunction findChildChips(nodes: TmplAstNode[]): TmplAstElement[] {\n const chips: TmplAstElement[] = [];\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (isChipElement(node)) {\n chips.push(node);\n } else {\n chips.push(...findChildChips(node.children));\n }\n }\n }\n return chips;\n}\n\nfunction migrateChipListElement(element: TmplAstElement, source: string, edits: Edit[]): void {\n const childChips = findChildChips(element.children);\n const insertions: string[] = [];\n let truncateValue: string | null = null;\n\n // Collect and remove propagated static attributes\n for (const attr of element.attributes) {\n if (PROPAGATED_INPUTS.has(attr.name)) {\n edits.push(removalEdit(attr, source));\n insertions.push(attr.value ? `${attr.name}=\"${attr.value}\"` : attr.name);\n }\n if (attr.name === 'isChipsRemovable') {\n edits.push(removalEdit(attr, source));\n insertions.push('isChipRemovable');\n }\n if (attr.name === 'chipsLabelTruncateCount') {\n edits.push(removalEdit(attr, source));\n truncateValue = attr.value || null;\n }\n if (REMOVED_INPUTS.has(attr.name)) {\n edits.push(removalEdit(attr, source));\n }\n }\n\n // Collect and remove propagated bound inputs\n for (const input of element.inputs) {\n if (PROPAGATED_INPUTS.has(input.name)) {\n edits.push(removalEdit(input, source));\n const raw = source.slice(input.sourceSpan.start.offset, input.sourceSpan.end.offset);\n insertions.push(raw);\n }\n if (input.name === 'isChipsRemovable') {\n edits.push(removalEdit(input, source));\n const valueText = extractBindingValue(input, source);\n insertions.push(`[isChipRemovable]=\"${valueText}\"`);\n }\n if (input.name === 'chipsLabelTruncateCount') {\n edits.push(removalEdit(input, source));\n truncateValue = extractBindingValue(input, source);\n }\n if (REMOVED_INPUTS.has(input.name)) {\n edits.push(removalEdit(input, source));\n }\n }\n\n // Collect and remove (chipRemove) output\n let chipRemoveHandler: string | null = null;\n for (const output of element.outputs) {\n if (output.name === 'chipRemove') {\n edits.push(removalEdit(output, source));\n chipRemoveHandler = extractHandlerExpression(output, source);\n }\n }\n\n if (chipRemoveHandler) {\n insertions.push(`(remove)=\"${chipRemoveHandler}\"`);\n }\n\n // Add collected attributes to each child eui-chip\n if (insertions.length > 0) {\n for (const chip of childChips) {\n const existingNames = getExistingAttrNames(chip);\n const toInsert = insertions.filter((ins) => {\n const name = extractAttrName(ins);\n return !existingNames.has(name);\n });\n if (toInsert.length > 0) {\n const insertPos = chip.startSourceSpan.end.offset - 1;\n edits.push({ start: insertPos, end: insertPos, replacement: ' ' + toInsert.join(' ') });\n }\n }\n }\n\n // Add euiTruncate pipe to chip label content\n if (truncateValue) {\n for (const chip of childChips) {\n const labelEdit = buildTruncatePipeEdit(chip, source, truncateValue);\n if (labelEdit) edits.push(labelEdit);\n }\n }\n}\n\nfunction buildTruncatePipeEdit(chip: TmplAstElement, source: string, truncateValue: string): Edit | null {\n // Find <span euiLabel>...</span> inside the chip\n const labelEl = findLabelElement(chip.children);\n if (labelEl && labelEl.endSourceSpan) {\n const contentStart = labelEl.startSourceSpan.end.offset;\n const contentEnd = labelEl.endSourceSpan.start.offset;\n const content = source.slice(contentStart, contentEnd);\n if (content && !content.includes('euiTruncate')) {\n const trimmed = content.trim();\n const interpMatch = trimmed.match(/^\\{\\{\\s*(.+?)\\s*\\}\\}$/);\n if (interpMatch) {\n return { start: contentStart, end: contentEnd, replacement: `{{ ${interpMatch[1]} | euiTruncate: ${truncateValue} }}` };\n }\n return { start: contentStart, end: contentEnd, replacement: `{{ '${trimmed}' | euiTruncate: ${truncateValue} }}` };\n }\n }\n\n // Check direct text content inside chip (no label element)\n if (chip.endSourceSpan) {\n const chipContentStart = chip.startSourceSpan.end.offset;\n const chipContentEnd = chip.endSourceSpan.start.offset;\n const chipContent = source.slice(chipContentStart, chipContentEnd);\n const trimmed = chipContent.trim();\n const interpMatch = trimmed.match(/^\\{\\{\\s*(.+?)\\s*\\}\\}$/);\n if (interpMatch && !chipContent.includes('euiTruncate')) {\n return { start: chipContentStart, end: chipContentEnd, replacement: `{{ ${interpMatch[1]} | euiTruncate: ${truncateValue} }}` };\n }\n }\n return null;\n}\n\nfunction findLabelElement(nodes: TmplAstNode[]): TmplAstElement | null {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.attributes.some((a) => a.name === 'euiLabel')) return node;\n const nested = findLabelElement(node.children);\n if (nested) return nested;\n }\n }\n return null;\n}\n\nfunction getExistingAttrNames(element: TmplAstElement): Set<string> {\n const names = new Set<string>();\n for (const attr of element.attributes) names.add(attr.name);\n for (const input of element.inputs) names.add(input.name);\n for (const output of element.outputs) names.add(output.name);\n return names;\n}\n\nfunction extractAttrName(insertion: string): string {\n const outputMatch = insertion.match(/^\\(([^)]+)\\)/);\n if (outputMatch) return outputMatch[1];\n const inputMatch = insertion.match(/^\\[([^\\]]+)\\]/);\n if (inputMatch) return inputMatch[1];\n return insertion.split('=')[0];\n}\n\nfunction removalEdit(node: TmplAstTextAttribute | TmplAstBoundAttribute | TmplAstBoundEvent, source: string): Edit {\n let start = node.sourceSpan.start.offset;\n while (start > 0 && (source[start - 1] === ' ' || source[start - 1] === '\\t')) {\n start--;\n }\n return { start, end: node.sourceSpan.end.offset, replacement: '' };\n}\n\nfunction extractBindingValue(input: TmplAstBoundAttribute, source: string): string {\n const raw = source.slice(input.sourceSpan.start.offset, input.sourceSpan.end.offset);\n const match = raw.match(/=[\"']([^\"']*)[\"']/);\n return match ? match[1] : 'true';\n}\n\nfunction extractHandlerExpression(output: TmplAstBoundEvent, source: string): string {\n const raw = source.slice(output.sourceSpan.start.offset, output.sourceSpan.end.offset);\n const match = raw.match(/=[\"']([^\"']*)[\"']/);\n return match ? match[1] : '';\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n const unique = deduplicateEdits(edits);\n let result = source;\n for (const edit of unique.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction deduplicateEdits(edits: Edit[]): Edit[] {\n const seen = new Map<string, Edit>();\n for (const edit of edits) {\n seen.set(`${edit.start}:${edit.end}`, edit);\n }\n return Array.from(seen.values());\n}\n",
|
|
2592
2486
|
"displayName": "Schema",
|
|
2593
2487
|
"properties": [
|
|
2594
2488
|
{
|
|
@@ -2600,7 +2494,7 @@
|
|
|
2600
2494
|
"indexKey": "",
|
|
2601
2495
|
"optional": true,
|
|
2602
2496
|
"description": "",
|
|
2603
|
-
"line":
|
|
2497
|
+
"line": 28,
|
|
2604
2498
|
"rawdescription": "\n"
|
|
2605
2499
|
},
|
|
2606
2500
|
{
|
|
@@ -2612,7 +2506,7 @@
|
|
|
2612
2506
|
"indexKey": "",
|
|
2613
2507
|
"optional": true,
|
|
2614
2508
|
"description": "",
|
|
2615
|
-
"line":
|
|
2509
|
+
"line": 27,
|
|
2616
2510
|
"rawdescription": "\n"
|
|
2617
2511
|
}
|
|
2618
2512
|
],
|
|
@@ -2621,8 +2515,8 @@
|
|
|
2621
2515
|
"methods": [],
|
|
2622
2516
|
"extends": [],
|
|
2623
2517
|
"isDuplicate": true,
|
|
2624
|
-
"duplicateId":
|
|
2625
|
-
"duplicateName": "Schema-
|
|
2518
|
+
"duplicateId": 7,
|
|
2519
|
+
"duplicateName": "Schema-7",
|
|
2626
2520
|
"relationships": {
|
|
2627
2521
|
"incoming": [],
|
|
2628
2522
|
"outgoing": []
|
|
@@ -2630,12 +2524,12 @@
|
|
|
2630
2524
|
},
|
|
2631
2525
|
{
|
|
2632
2526
|
"name": "Schema",
|
|
2633
|
-
"id": "interface-Schema-
|
|
2634
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2527
|
+
"id": "interface-Schema-869dfc324e9111966817cbebb3553eabfe200acfe33bb77efa71a6c46e1cba0ff5852de7b9ade3060f87264035b99591361331a9e0622daaac22b8d59146c761-8",
|
|
2528
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
2635
2529
|
"deprecated": false,
|
|
2636
2530
|
"deprecationMessage": "",
|
|
2637
2531
|
"type": "interface",
|
|
2638
|
-
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstElement, TmplAstNode
|
|
2532
|
+
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst COMPONENT_TAG = 'eui-discussion-thread';\n\nexport function migrateEuiDiscussionThread(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(COMPONENT_TAG)) return;\n\n const result = path.endsWith('.html')\n ? migrateTemplate(original)\n : migrateInlineTemplates(original);\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would remove [trackBy] binding in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n\n // Warn about TS usages inline\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts') && original.includes('trackByFn')) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && node.name.text === 'trackByFn') {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(`${path}:${line + 1} - \"trackByFn\" has been removed from ${COMPONENT_TAG}. Remove this reference manually.`);\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n });\n\n context.logger.info(`Removed trackByFn-based [trackBy] bindings from ${COMPONENT_TAG} in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const removals: { start: number; end: number }[] = [];\n\n visitNodes(parsed.nodes, source, removals);\n\n let result = source;\n for (const { start, end } of removals.sort((a, b) => b.start - a.start)) {\n let adjustedStart = start;\n while (adjustedStart > 0 && (result[adjustedStart - 1] === ' ' || result[adjustedStart - 1] === '\\t')) {\n adjustedStart--;\n }\n result = result.slice(0, adjustedStart) + result.slice(end);\n }\n\n return result;\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const templateRegex = /template\\s*:\\s*`([^`]*)`/gs;\n return source.replace(templateRegex, (match, templateContent: string) => {\n if (!templateContent.includes(COMPONENT_TAG)) return match;\n const migrated = migrateTemplate(templateContent);\n if (migrated === templateContent) return match;\n return match.replace(templateContent, migrated);\n });\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, removals: { start: number; end: number }[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === COMPONENT_TAG) collectRemovals(node, source, removals);\n visitNodes(node.children, source, removals);\n }\n }\n}\n\nfunction collectRemovals(element: TmplAstElement, source: string, removals: { start: number; end: number }[]): void {\n for (const input of element.inputs) {\n if (input.name === 'trackBy') {\n const valueSource = source.slice(input.sourceSpan.start.offset, input.sourceSpan.end.offset);\n if (valueSource.includes('trackByFn')) {\n removals.push({ start: input.sourceSpan.start.offset, end: input.sourceSpan.end.offset });\n }\n }\n }\n}\n",
|
|
2639
2533
|
"displayName": "Schema",
|
|
2640
2534
|
"properties": [
|
|
2641
2535
|
{
|
|
@@ -2668,8 +2562,8 @@
|
|
|
2668
2562
|
"methods": [],
|
|
2669
2563
|
"extends": [],
|
|
2670
2564
|
"isDuplicate": true,
|
|
2671
|
-
"duplicateId":
|
|
2672
|
-
"duplicateName": "Schema-
|
|
2565
|
+
"duplicateId": 8,
|
|
2566
|
+
"duplicateName": "Schema-8",
|
|
2673
2567
|
"relationships": {
|
|
2674
2568
|
"incoming": [],
|
|
2675
2569
|
"outgoing": []
|
|
@@ -2677,7 +2571,7 @@
|
|
|
2677
2571
|
},
|
|
2678
2572
|
{
|
|
2679
2573
|
"name": "Schema",
|
|
2680
|
-
"id": "interface-Schema-375dc0924084a2acbafe4a6a32577d59f631c9a386d151180d8fb1c89e7e7cd23da9fd459e597592ed823692adb6ad2633c50baf16621f003246e8c9bb1c6ce0-
|
|
2574
|
+
"id": "interface-Schema-375dc0924084a2acbafe4a6a32577d59f631c9a386d151180d8fb1c89e7e7cd23da9fd459e597592ed823692adb6ad2633c50baf16621f003246e8c9bb1c6ce0-9",
|
|
2681
2575
|
"file": "packages/core/schematics/migrate-eui-editor/index.ts",
|
|
2682
2576
|
"deprecated": false,
|
|
2683
2577
|
"deprecationMessage": "",
|
|
@@ -2715,8 +2609,8 @@
|
|
|
2715
2609
|
"methods": [],
|
|
2716
2610
|
"extends": [],
|
|
2717
2611
|
"isDuplicate": true,
|
|
2718
|
-
"duplicateId":
|
|
2719
|
-
"duplicateName": "Schema-
|
|
2612
|
+
"duplicateId": 9,
|
|
2613
|
+
"duplicateName": "Schema-9",
|
|
2720
2614
|
"relationships": {
|
|
2721
2615
|
"incoming": [],
|
|
2722
2616
|
"outgoing": []
|
|
@@ -2724,12 +2618,12 @@
|
|
|
2724
2618
|
},
|
|
2725
2619
|
{
|
|
2726
2620
|
"name": "Schema",
|
|
2727
|
-
"id": "interface-Schema-
|
|
2728
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2621
|
+
"id": "interface-Schema-0ee574e11dd651dd971057cb66220845e5b87b2949c69c623c8ddf7355af92a396c58c237a52a05f18c22a5332a2695b717bcfeb8ea840c4e7df8d0084c2b49c-10",
|
|
2622
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
2729
2623
|
"deprecated": false,
|
|
2730
2624
|
"deprecationMessage": "",
|
|
2731
2625
|
"type": "interface",
|
|
2732
|
-
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst COMPONENT_TAG = 'eui-
|
|
2626
|
+
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst COMPONENT_TAG = 'eui-fieldset';\nconst OLD_NAME = 'iconSvgType';\nconst NEW_NAME = 'iconSvgName';\n\nexport function migrateEuiFieldset(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(COMPONENT_TAG)) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original);\n } else {\n result = migrateInlineTemplates(original);\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would rename '${OLD_NAME}' → '${NEW_NAME}' in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n\n // Warn about TS property access usages (merged from warnTsUsages)\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts') && original.includes(OLD_NAME)) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && node.name.text === OLD_NAME) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(`${path}:${line + 1} - \"${OLD_NAME}\" has been renamed to \"${NEW_NAME}\" on ${COMPONENT_TAG}. Update this reference manually.`);\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n });\n\n context.logger.info(`Renamed '${OLD_NAME}' → '${NEW_NAME}' on ${COMPONENT_TAG} in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: { start: number; end: number; replacement: string }[] = [];\n\n visitNodes(parsed.nodes, edits);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: { start: number; end: number; text: string }[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(COMPONENT_TAG)) {\n ts.forEachChild(node, visit); return; \n}\n const migrated = migrateTemplate(rawTemplate);\n if (migrated !== rawTemplate) changes.push({ start, end, text: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n let result = source;\n for (const change of changes.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, change.start) + change.text + result.slice(change.end);\n }\n return result;\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction visitNodes(nodes: TmplAstNode[], edits: { start: number; end: number; replacement: string }[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === COMPONENT_TAG) collectRenames(node, edits);\n visitNodes(node.children, edits);\n }\n }\n}\n\nfunction collectRenames(element: TmplAstElement, edits: { start: number; end: number; replacement: string }[]): void {\n for (const attr of element.attributes) {\n if (attr.name === OLD_NAME) {\n edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: NEW_NAME });\n }\n }\n for (const input of element.inputs) {\n if (input.name === OLD_NAME) {\n edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: NEW_NAME });\n }\n }\n}\n\nfunction applyEdits(source: string, edits: { start: number; end: number; replacement: string }[]): string {\n let result = source;\n for (const edit of edits.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n",
|
|
2733
2627
|
"displayName": "Schema",
|
|
2734
2628
|
"properties": [
|
|
2735
2629
|
{
|
|
@@ -2762,8 +2656,8 @@
|
|
|
2762
2656
|
"methods": [],
|
|
2763
2657
|
"extends": [],
|
|
2764
2658
|
"isDuplicate": true,
|
|
2765
|
-
"duplicateId":
|
|
2766
|
-
"duplicateName": "Schema-
|
|
2659
|
+
"duplicateId": 10,
|
|
2660
|
+
"duplicateName": "Schema-10",
|
|
2767
2661
|
"relationships": {
|
|
2768
2662
|
"incoming": [],
|
|
2769
2663
|
"outgoing": []
|
|
@@ -2771,12 +2665,12 @@
|
|
|
2771
2665
|
},
|
|
2772
2666
|
{
|
|
2773
2667
|
"name": "Schema",
|
|
2774
|
-
"id": "interface-Schema-
|
|
2775
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2668
|
+
"id": "interface-Schema-b3ff4600c4a5ca1888c45e5baf3600fa6dc6477f1e473e5241ff6682e2929dc8950a5dfa8b1048a348dba7ad1f0ce8cc3681471933911b689e04713334ef4811-11",
|
|
2669
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
2776
2670
|
"deprecated": false,
|
|
2777
2671
|
"deprecationMessage": "",
|
|
2778
2672
|
"type": "interface",
|
|
2779
|
-
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst COMPONENT_TAG = 'eui-
|
|
2673
|
+
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst COMPONENT_TAG = 'eui-icon-svg';\n\nconst INPUT_RENAMES = new Map([\n ['variant', 'fillColor'],\n ['aria-label', 'ariaLabel'],\n]);\n\nconst TS_PROPERTY_RENAMES = new Map([\n ['variant', 'fillColor'],\n]);\n\nexport function migrateEuiIconSvg(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(COMPONENT_TAG)) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original);\n } else {\n result = migrateInlineTemplates(original);\n result = renameTsPropertyAccesses(result);\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would rename deprecated inputs in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n });\n\n context.logger.info(`Migrated eui-icon-svg inputs in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: { start: number; end: number; replacement: string }[] = [];\n\n visitNodes(parsed.nodes, edits);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: { start: number; end: number; text: string }[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(COMPONENT_TAG)) {\n ts.forEachChild(node, visit);\n return;\n }\n const migrated = migrateTemplate(rawTemplate);\n if (migrated !== rawTemplate) {\n changes.push({ start, end, text: migrated });\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n let result = source;\n for (const change of changes.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, change.start) + change.text + result.slice(change.end);\n }\n return result;\n}\n\nfunction renameTsPropertyAccesses(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: { start: number; end: number; replacement: string }[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && TS_PROPERTY_RENAMES.has(node.name.text)) {\n edits.push({ start: node.name.getStart(sourceFile), end: node.name.getEnd(), replacement: TS_PROPERTY_RENAMES.get(node.name.text)! });\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return applyEdits(source, edits);\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) {\n current = current.expression;\n }\n return current;\n}\n\nfunction visitNodes(nodes: TmplAstNode[], edits: { start: number; end: number; replacement: string }[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === COMPONENT_TAG) {\n collectRenames(node, edits);\n }\n visitNodes(node.children, edits);\n }\n }\n}\n\nfunction collectRenames(element: TmplAstElement, edits: { start: number; end: number; replacement: string }[]): void {\n for (const attr of element.attributes) {\n const newName = INPUT_RENAMES.get(attr.name);\n if (newName) {\n edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n }\n for (const input of element.inputs) {\n const newName = INPUT_RENAMES.get(input.name);\n if (newName) {\n edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n }\n}\n\nfunction applyEdits(source: string, edits: { start: number; end: number; replacement: string }[]): string {\n let result = source;\n for (const edit of edits.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n",
|
|
2780
2674
|
"displayName": "Schema",
|
|
2781
2675
|
"properties": [
|
|
2782
2676
|
{
|
|
@@ -2809,8 +2703,8 @@
|
|
|
2809
2703
|
"methods": [],
|
|
2810
2704
|
"extends": [],
|
|
2811
2705
|
"isDuplicate": true,
|
|
2812
|
-
"duplicateId":
|
|
2813
|
-
"duplicateName": "Schema-
|
|
2706
|
+
"duplicateId": 11,
|
|
2707
|
+
"duplicateName": "Schema-11",
|
|
2814
2708
|
"relationships": {
|
|
2815
2709
|
"incoming": [],
|
|
2816
2710
|
"outgoing": []
|
|
@@ -2818,7 +2712,7 @@
|
|
|
2818
2712
|
},
|
|
2819
2713
|
{
|
|
2820
2714
|
"name": "Schema",
|
|
2821
|
-
"id": "interface-Schema-21147930d3fbc38fbb3052a2ed9e7aa2b7505e6ed8c88c28796ce7101bd2ad914726eb230dda5826647036190edec6dae7e7e1d172387cd3803aa00bcdf790be-
|
|
2715
|
+
"id": "interface-Schema-21147930d3fbc38fbb3052a2ed9e7aa2b7505e6ed8c88c28796ce7101bd2ad914726eb230dda5826647036190edec6dae7e7e1d172387cd3803aa00bcdf790be-12",
|
|
2822
2716
|
"file": "packages/core/schematics/migrate-eui-icon-toggle/index.ts",
|
|
2823
2717
|
"deprecated": false,
|
|
2824
2718
|
"deprecationMessage": "",
|
|
@@ -2856,8 +2750,8 @@
|
|
|
2856
2750
|
"methods": [],
|
|
2857
2751
|
"extends": [],
|
|
2858
2752
|
"isDuplicate": true,
|
|
2859
|
-
"duplicateId":
|
|
2860
|
-
"duplicateName": "Schema-
|
|
2753
|
+
"duplicateId": 12,
|
|
2754
|
+
"duplicateName": "Schema-12",
|
|
2861
2755
|
"relationships": {
|
|
2862
2756
|
"incoming": [],
|
|
2863
2757
|
"outgoing": []
|
|
@@ -2865,7 +2759,7 @@
|
|
|
2865
2759
|
},
|
|
2866
2760
|
{
|
|
2867
2761
|
"name": "Schema",
|
|
2868
|
-
"id": "interface-Schema-a806c1769fb526271565003a6a3ef9ab4c67e421d93ee0cb54e1f6de223807afc1f16ad294656ef614a77a91a38cc914ce41ac97ed3a8a4195a1e74a729c0c08-
|
|
2762
|
+
"id": "interface-Schema-a806c1769fb526271565003a6a3ef9ab4c67e421d93ee0cb54e1f6de223807afc1f16ad294656ef614a77a91a38cc914ce41ac97ed3a8a4195a1e74a729c0c08-13",
|
|
2869
2763
|
"file": "packages/core/schematics/migrate-eui-popover/index.ts",
|
|
2870
2764
|
"deprecated": false,
|
|
2871
2765
|
"deprecationMessage": "",
|
|
@@ -2903,8 +2797,8 @@
|
|
|
2903
2797
|
"methods": [],
|
|
2904
2798
|
"extends": [],
|
|
2905
2799
|
"isDuplicate": true,
|
|
2906
|
-
"duplicateId":
|
|
2907
|
-
"duplicateName": "Schema-
|
|
2800
|
+
"duplicateId": 13,
|
|
2801
|
+
"duplicateName": "Schema-13",
|
|
2908
2802
|
"relationships": {
|
|
2909
2803
|
"incoming": [],
|
|
2910
2804
|
"outgoing": []
|
|
@@ -2912,12 +2806,12 @@
|
|
|
2912
2806
|
},
|
|
2913
2807
|
{
|
|
2914
2808
|
"name": "Schema",
|
|
2915
|
-
"id": "interface-Schema-
|
|
2916
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2809
|
+
"id": "interface-Schema-90e62c16ce9ada881e8d434336bb633dae9745236106ddf60964afbd11de6aa579255a13d6036b384281860eb6ed2ee329194b519c51fdaf20f79bc511d0f64f-14",
|
|
2810
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
2917
2811
|
"deprecated": false,
|
|
2918
2812
|
"deprecationMessage": "",
|
|
2919
2813
|
"type": "interface",
|
|
2920
|
-
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface TextChange {\n start: number;\n end: number;\n text: string;\n}\n\ninterface MigrationResult {\n content: string;\n migrated: number;\n skipped: number;\n}\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst OLD_LABEL = 'eui-tab-label';\nconst OLD_SUB_LABEL = 'euiTabSubLabel';\nconst OLD_CONTENT = 'eui-tab-content';\nconst NEW_HEADER = 'eui-tab-header';\nconst NEW_HEADER_LABEL = 'eui-tab-header-label';\nconst NEW_HEADER_SUB_LABEL = 'eui-tab-header-sub-label';\nconst NEW_BODY = 'eui-tab-body';\n\nexport function migrateEuiTabs(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let migrated = 0;\n let skipped = 0;\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) {\n return;\n }\n\n const original = buffer.toString('utf-8');\n const result = path.endsWith('.html')\n ? migrateTemplate(original, path, context)\n : migrateInlineTemplates(original, path, context);\n\n migrated += result.migrated;\n skipped += result.skipped;\n\n if (result.content !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate ${result.migrated} tab block(s) in ${path}`);\n } else {\n tree.overwrite(path, result.content);\n }\n }\n });\n\n context.logger.info(`Migrated ${migrated} EUI tab template block(s).`);\n if (skipped > 0) {\n context.logger.warn(`Skipped ${skipped} malformed EUI tab template block(s).`);\n }\n if (options.dryRun) {\n logDryRunNote(context);\n }\n\n return tree;\n };\n}\n\nfunction migrateInlineTemplates(source: string, filePath: string, context: SchematicContext): MigrationResult {\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: TextChange[] = [];\n let migrated = 0;\n let skipped = 0;\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const initializer = unwrapExpression(node.initializer);\n\n if (ts.isStringLiteral(initializer) || ts.isNoSubstitutionTemplateLiteral(initializer)) {\n const start = initializer.getStart(sourceFile) + 1;\n const end = initializer.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n const result = migrateTemplate(rawTemplate, `${filePath}@inline-template`, context);\n\n migrated += result.migrated;\n skipped += result.skipped;\n\n if (result.content !== rawTemplate) {\n changes.push({ start, end, text: result.content });\n }\n } else if (ts.isTemplateExpression(initializer)) {\n context.logger.warn(`Skipping interpolated inline template in ${filePath}.`);\n skipped++;\n }\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return {\n content: applyChanges(source, changes),\n migrated,\n skipped,\n };\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (\n (ts.isIdentifier(name) && name.text === 'template') ||\n (ts.isStringLiteral(name) && name.text === 'template')\n );\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n\n while (ts.isParenthesizedExpression(current)) {\n current = current.expression;\n }\n\n return current;\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) {\n return false;\n }\n\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) {\n return false;\n }\n\n return (\n ts.isDecorator(callExpression.parent) &&\n ts.isIdentifier(callExpression.expression) &&\n callExpression.expression.text === 'Component'\n );\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): MigrationResult {\n const parsed = parseTemplate(source, filePath, { preserveWhitespaces: true });\n const changes: TextChange[] = [];\n let migrated = 0;\n let skipped = 0;\n\n for (const error of parsed.errors ?? []) {\n context.logger.warn(`Template parse warning in ${filePath}: ${error.msg}`);\n }\n\n for (const tab of findElements(parsed.nodes, 'eui-tab')) {\n const label = findDirectChild(tab, OLD_LABEL);\n const content = findDirectChild(tab, OLD_CONTENT);\n const hasOldMarkup = Boolean(label || content);\n const hasNewMarkup = Boolean(findDirectChild(tab, NEW_HEADER) || findDirectChild(tab, NEW_BODY));\n\n if (!hasOldMarkup || hasNewMarkup) {\n continue;\n }\n\n if (!label || !content) {\n context.logger.warn(`Skipping malformed <eui-tab> in ${filePath}.`);\n skipped++;\n continue;\n }\n\n changes.push({\n start: label.sourceSpan.start.offset,\n end: label.sourceSpan.end.offset,\n text: buildHeaderReplacement(source, label),\n });\n changes.push({\n start: content.sourceSpan.start.offset,\n end: content.sourceSpan.end.offset,\n text: buildBodyReplacement(source, content),\n });\n migrated++;\n }\n\n return {\n content: applyChanges(source, withoutOverlaps(changes)),\n migrated,\n skipped,\n };\n}\n\nfunction findElements(nodes: readonly TmplAstNode[], name: string): TmplAstElement[] {\n const matches: TmplAstElement[] = [];\n\n for (const node of nodes) {\n if (isElement(node)) {\n if (node.name === name) {\n matches.push(node);\n }\n matches.push(...findElements(node.children, name));\n }\n }\n\n return matches;\n}\n\nfunction findDirectChild(element: TmplAstElement, name: string): TmplAstElement | undefined {\n return element.children.find((child): child is TmplAstElement => isElement(child) && child.name === name);\n}\n\nfunction isElement(node: TmplAstNode): node is TmplAstElement {\n return node instanceof TmplAstElement;\n}\n\nfunction buildHeaderReplacement(source: string, label: TmplAstElement): string {\n const indent = getIndent(source, label.sourceSpan.start.offset);\n const labelAttributes = getAttributeText(source, label, OLD_LABEL);\n const subLabels = findElements(label.children, OLD_SUB_LABEL);\n const mainLabelContent = removeElementRanges(getInnerText(source, label), label, subLabels);\n const lines = [\n `<${NEW_HEADER}>`,\n `${indent} <${NEW_HEADER_LABEL}${labelAttributes}>`,\n ...formatInnerLines(mainLabelContent, `${indent} `),\n `${indent} </${NEW_HEADER_LABEL}>`,\n ];\n\n for (const subLabel of subLabels) {\n const subLabelAttributes = getAttributeText(source, subLabel, OLD_SUB_LABEL);\n lines.push(\n `${indent} <${NEW_HEADER_SUB_LABEL}${subLabelAttributes}>`,\n ...formatInnerLines(getInnerText(source, subLabel), `${indent} `),\n `${indent} </${NEW_HEADER_SUB_LABEL}>`,\n );\n }\n\n lines.push(`${indent}</${NEW_HEADER}>`);\n\n return lines.join('\\n');\n}\n\nfunction buildBodyReplacement(source: string, content: TmplAstElement): string {\n const indent = getIndent(source, content.sourceSpan.start.offset);\n const attributes = getAttributeText(source, content, OLD_CONTENT);\n const innerText = getInnerText(source, content);\n const trimmed = innerText.trim();\n\n if (trimmed && !trimmed.includes('\\n')) {\n return `<${NEW_BODY}${attributes}>${trimmed}</${NEW_BODY}>`;\n }\n\n return [\n `<${NEW_BODY}${attributes}>`,\n ...formatInnerLines(innerText, `${indent} `),\n `${indent}</${NEW_BODY}>`,\n ].join('\\n');\n}\n\nfunction getInnerText(source: string, element: TmplAstElement): string {\n if (!element.endSourceSpan) {\n return '';\n }\n\n return source.slice(element.startSourceSpan.end.offset, element.endSourceSpan.start.offset);\n}\n\nfunction removeElementRanges(source: string, parent: TmplAstElement, elements: readonly TmplAstElement[]): string {\n const parentContentStart = parent.startSourceSpan.end.offset;\n let result = source;\n\n for (const element of [...elements].sort((a, b) => b.sourceSpan.start.offset - a.sourceSpan.start.offset)) {\n const start = element.sourceSpan.start.offset - parentContentStart;\n const end = element.sourceSpan.end.offset - parentContentStart;\n result = result.slice(0, start) + result.slice(end);\n }\n\n return result;\n}\n\nfunction getAttributeText(source: string, element: TmplAstElement, tagName: string): string {\n const startTag = source.slice(element.startSourceSpan.start.offset, element.startSourceSpan.end.offset);\n const tagStart = startTag.indexOf(tagName);\n\n if (tagStart === -1) {\n return '';\n }\n\n const contentEnd = startTag.endsWith('/>') ? startTag.length - 2 : startTag.length - 1;\n return startTag.slice(tagStart + tagName.length, contentEnd).trimEnd();\n}\n\nfunction getIndent(source: string, offset: number): string {\n const lineStart = source.lastIndexOf('\\n', offset - 1) + 1;\n const prefix = source.slice(lineStart, offset);\n return prefix.match(/^\\s*/)?.[0] ?? '';\n}\n\nfunction formatInnerLines(source: string, indent: string): string[] {\n const trimmed = source.trim();\n\n if (!trimmed) {\n return [];\n }\n\n return trimmed.split(/\\r?\\n/).map((line) => `${indent}${line.trim()}`);\n}\n\nfunction withoutOverlaps(changes: TextChange[]): TextChange[] {\n const accepted: TextChange[] = [];\n\n for (const change of [...changes].sort((a, b) => a.start - b.start || b.end - a.end)) {\n if (!accepted.some((current) => change.start < current.end && current.start < change.end)) {\n accepted.push(change);\n }\n }\n\n return accepted;\n}\n\nfunction applyChanges(source: string, changes: readonly TextChange[]): string {\n let result = source;\n\n for (const change of [...changes].sort((a, b) => b.start - a.start)) {\n result = result.slice(0, change.start) + change.text + result.slice(change.end);\n }\n\n return result;\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
2814
|
+
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstElement, TmplAstNode, TmplAstTextAttribute } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst INPUT_RENAMES = new Map([\n ['iconLabelClass', 'icon'],\n ['iconLabelStyleClass', 'fillColor'],\n]);\n\nexport function migrateEuiProgressCircle(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const oldNames = [...INPUT_RENAMES.keys()];\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n\n if (original.includes('eui-progress-circle')) {\n const result = path.endsWith('.html')\n ? migrateTemplate(original)\n : migrateInlineTemplates(original);\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would rename deprecated inputs in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n }\n\n // Warn about TS property access usages (merged from warnTsUsages)\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts')) {\n if (oldNames.some((name) => original.includes(name))) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && INPUT_RENAMES.has(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const newName = INPUT_RENAMES.get(node.name.text);\n context.logger.warn(\n `${path}:${line + 1} - \"${node.name.text}\" has been renamed to \"${newName}\" on eui-progress-circle. Update this reference manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n }\n });\n\n context.logger.info(`Renamed deprecated eui-progress-circle inputs in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: { start: number; end: number; replacement: string }[] = [];\n\n visitNodes(parsed.nodes, edits);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: { start: number; end: number; text: string }[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes('eui-progress-circle')) {\n ts.forEachChild(node, visit);\n return;\n }\n const migrated = migrateTemplate(rawTemplate);\n if (migrated !== rawTemplate) {\n changes.push({ start, end, text: migrated });\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n let result = source;\n for (const change of changes.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, change.start) + change.text + result.slice(change.end);\n }\n return result;\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) {\n current = current.expression;\n }\n return current;\n}\n\nfunction visitNodes(nodes: TmplAstNode[], edits: { start: number; end: number; replacement: string }[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === 'eui-progress-circle') {\n collectRenames(node, edits);\n }\n visitNodes(node.children, edits);\n }\n }\n}\n\nfunction collectRenames(element: TmplAstElement, edits: { start: number; end: number; replacement: string }[]): void {\n for (const attr of element.attributes) {\n const newName = INPUT_RENAMES.get(attr.name);\n if (newName) {\n edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n }\n for (const input of element.inputs) {\n const newName = INPUT_RENAMES.get(input.name);\n if (newName) {\n edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n }\n}\n\nfunction applyEdits(source: string, edits: { start: number; end: number; replacement: string }[]): string {\n let result = source;\n for (const edit of edits.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n",
|
|
2921
2815
|
"displayName": "Schema",
|
|
2922
2816
|
"properties": [
|
|
2923
2817
|
{
|
|
@@ -2929,7 +2823,7 @@
|
|
|
2929
2823
|
"indexKey": "",
|
|
2930
2824
|
"optional": true,
|
|
2931
2825
|
"description": "",
|
|
2932
|
-
"line":
|
|
2826
|
+
"line": 8,
|
|
2933
2827
|
"rawdescription": "\n"
|
|
2934
2828
|
},
|
|
2935
2829
|
{
|
|
@@ -2941,7 +2835,7 @@
|
|
|
2941
2835
|
"indexKey": "",
|
|
2942
2836
|
"optional": true,
|
|
2943
2837
|
"description": "",
|
|
2944
|
-
"line":
|
|
2838
|
+
"line": 7,
|
|
2945
2839
|
"rawdescription": "\n"
|
|
2946
2840
|
}
|
|
2947
2841
|
],
|
|
@@ -2950,8 +2844,8 @@
|
|
|
2950
2844
|
"methods": [],
|
|
2951
2845
|
"extends": [],
|
|
2952
2846
|
"isDuplicate": true,
|
|
2953
|
-
"duplicateId":
|
|
2954
|
-
"duplicateName": "Schema-
|
|
2847
|
+
"duplicateId": 14,
|
|
2848
|
+
"duplicateName": "Schema-14",
|
|
2955
2849
|
"relationships": {
|
|
2956
2850
|
"incoming": [],
|
|
2957
2851
|
"outgoing": []
|
|
@@ -2959,12 +2853,12 @@
|
|
|
2959
2853
|
},
|
|
2960
2854
|
{
|
|
2961
2855
|
"name": "Schema",
|
|
2962
|
-
"id": "interface-Schema-
|
|
2963
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2856
|
+
"id": "interface-Schema-91c9f900bf3ebb82488fb65644938ef486ceaa447cff8bfd9d710df9595d82acb267b26f3c252173bc684353f362473120226426ed7ee5d98b33e30011dd9383-15",
|
|
2857
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
2964
2858
|
"deprecated": false,
|
|
2965
2859
|
"deprecationMessage": "",
|
|
2966
2860
|
"type": "interface",
|
|
2967
|
-
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstElement, TmplAstNode, TmplAstTextAttribute } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst INPUT_RENAMES = new Map([\n ['iconLabelClass', 'icon'],\n ['iconLabelStyleClass', 'fillColor'],\n]);\n\nexport function migrateEuiProgressCircle(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const oldNames = [...INPUT_RENAMES.keys()];\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n\n if (original.includes('eui-progress-circle')) {\n const result = path.endsWith('.html')\n ? migrateTemplate(original)\n : migrateInlineTemplates(original);\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would rename deprecated inputs in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n }\n\n // Warn about TS property access usages (merged from warnTsUsages)\n if (path.endsWith('.ts') && !path.endsWith('.spec.ts')) {\n if (oldNames.some((name) => original.includes(name))) {\n const sourceFile = ts.createSourceFile(path, original, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && INPUT_RENAMES.has(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const newName = INPUT_RENAMES.get(node.name.text);\n context.logger.warn(\n `${path}:${line + 1} - \"${node.name.text}\" has been renamed to \"${newName}\" on eui-progress-circle. Update this reference manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n }\n }\n });\n\n context.logger.info(`Renamed deprecated eui-progress-circle inputs in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\nfunction migrateTemplate(source: string): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: { start: number; end: number; replacement: string }[] = [];\n\n visitNodes(parsed.nodes, edits);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateInlineTemplates(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: { start: number; end: number; text: string }[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes('eui-progress-circle')) {\n ts.forEachChild(node, visit);\n return;\n }\n const migrated = migrateTemplate(rawTemplate);\n if (migrated !== rawTemplate) {\n changes.push({ start, end, text: migrated });\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n let result = source;\n for (const change of changes.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, change.start) + change.text + result.slice(change.end);\n }\n return result;\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) {\n current = current.expression;\n }\n return current;\n}\n\nfunction visitNodes(nodes: TmplAstNode[], edits: { start: number; end: number; replacement: string }[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === 'eui-progress-circle') {\n collectRenames(node, edits);\n }\n visitNodes(node.children, edits);\n }\n }\n}\n\nfunction collectRenames(element: TmplAstElement, edits: { start: number; end: number; replacement: string }[]): void {\n for (const attr of element.attributes) {\n const newName = INPUT_RENAMES.get(attr.name);\n if (newName) {\n edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n }\n for (const input of element.inputs) {\n const newName = INPUT_RENAMES.get(input.name);\n if (newName) {\n edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n }\n}\n\nfunction applyEdits(source: string, edits: { start: number; end: number; replacement: string }[]): string {\n let result = source;\n for (const edit of edits.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n",
|
|
2861
|
+
"sourceCode": "import { BindingPipe, parseTemplate, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstBoundText, TmplAstElement, TmplAstNode, TmplAstTemplate, TmplAstTextAttribute, AST, ASTWithSource, Interpolation } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Edit { start: number; end: number; replacement: string; }\n\n// --- Table-level input renames (on elements with euiTable attribute) ---\nconst TABLE_INPUT_RENAMES = new Map([\n ['rows', 'data'],\n ['loading', 'isLoading'],\n ['asyncTable', 'isAsync'],\n ['euiTableResponsive', 'isTableResponsive'],\n ['euiTableFixedLayout', 'isTableFixedLayout'],\n ['euiTableCompact', 'isTableCompact'],\n ['hasStickyColumns', 'hasStickyCols'],\n]);\n\n// --- Child element input renames (scoped to euiTable context) ---\nconst TH_TD_INPUT_RENAMES = new Map([\n ['isStickyColumn', 'isStickyCol'],\n ['sortable', 'isSortable'],\n]);\n\nconst TR_INPUT_RENAMES = new Map([\n ['isSelectableHeader', 'isHeaderSelectable'],\n ['isSelectable', 'isDataSelectable'],\n]);\n\n// --- Removed inputs ---\nconst REMOVED_INPUTS = new Set(['euiTableBordered', 'isHoverable', 'defaultMultiOrder', 'paginable']);\n\n// --- Output renames/removals ---\nconst OUTPUT_RENAMES = new Map([['selectedRows', 'rowsSelect']]);\nconst REMOVED_OUTPUTS = new Set(['multiSortChange']);\n\n// --- Pipe rename ---\nconst OLD_PIPE = 'euiTableHighlightFilter';\nconst NEW_PIPE = 'euiTableHighlight';\n\n// --- TS property renames ---\nconst TS_PROPERTY_RENAMES = new Map([['filteredRows', 'getFilteredData']]);\n\nconst PAGINATOR_IMPORT_PATH = '@eui/components/eui-paginator';\nconst PAGINATOR_COMPONENT = 'EuiPaginatorComponent';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nexport function migrateEuiTable(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const paginatorHtmlFiles = new Set<string>();\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes('euiTable') && !original.includes(OLD_PIPE) && !original.includes('filteredRows') && !original.includes('setSort')) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n const { output, hasPaginator } = migrateTemplateWithPaginator(original, path, context);\n result = output;\n if (hasPaginator) paginatorHtmlFiles.add(path);\n } else {\n const { output, hasPaginator } = migrateTypeScript(original, path, context);\n result = output;\n if (hasPaginator) {\n result = addPaginatorImport(result, path);\n }\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-table breaking changes in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n });\n\n // Handle paginator imports for external templates\n if (paginatorHtmlFiles.size > 0) {\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n if (!path.endsWith('.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const source = buffer.toString('utf-8');\n if (!source.includes('templateUrl')) return;\n\n for (const htmlFile of paginatorHtmlFiles) {\n const htmlFileName = htmlFile.split('/').pop()!;\n if (source.includes(htmlFileName)) {\n const updated = addPaginatorImport(source, path);\n if (updated !== source) {\n if (options.dryRun) {\n logDryRun(context, `Would add paginator import in ${path}`);\n } else {\n tree.overwrite(path, updated);\n }\n count++;\n }\n break;\n }\n }\n });\n }\n\n context.logger.info(`Migrated eui-table in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplateWithPaginator(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n let hasPaginator = false;\n\n const paginatorResult = visitNodesForTable(parsed.nodes, source, edits, false, filePath, context);\n if (paginatorResult) hasPaginator = true;\n\n collectPipeRenames(parsed.nodes, source, edits);\n\n return { output: applyEdits(source, edits), hasPaginator };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n return migrateTemplateWithPaginator(source, filePath, context).output;\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n let result = source;\n let hasPaginator = false;\n\n // Migrate inline templates\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = result.slice(start, end);\n if (!rawTemplate.includes('euiTable') && !rawTemplate.includes(OLD_PIPE)) {\n ts.forEachChild(node, visit); return;\n}\n const { output: migrated, hasPaginator: pag } = migrateTemplateWithPaginator(rawTemplate, filePath, context);\n if (pag) hasPaginator = true;\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n result = applyEdits(result, changes);\n\n // Rename TS property accesses\n result = renameTsProperties(result);\n\n // Warn about setSort\n warnSetSort(result, filePath, context);\n\n return { output: result, hasPaginator };\n}\n\nfunction renameTsProperties(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && TS_PROPERTY_RENAMES.has(node.name.text)) {\n edits.push({ start: node.name.getStart(sourceFile), end: node.name.getEnd(), replacement: TS_PROPERTY_RENAMES.get(node.name.text)! });\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, edits);\n}\n\nfunction warnSetSort(source: string, filePath: string, context: SchematicContext): void {\n if (!source.includes('setSort')) return;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) &&\n ts.isIdentifier(node.expression.name) && node.expression.name.text === 'setSort') {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"setSort\" signature changed from setSort(sort: string, order: \"asc\" | \"desc\") to setSort(Sort[]). Update manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\n// --- Template AST visitors ---\n\nfunction visitNodesForTable(\n nodes: TmplAstNode[], source: string, edits: Edit[], insideEuiTable: boolean, filePath: string, context: SchematicContext,\n): boolean {\n let hasPaginator = false;\n\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n const isEuiTable = hasEuiTableAttribute(node);\n\n if (isEuiTable) {\n collectTableInputRenames(node, edits);\n collectInputRemovals(node, source, edits, filePath, context);\n collectOutputChanges(node, source, edits, filePath, context);\n if (collectPaginatorMigration(node, source, edits)) hasPaginator = true;\n }\n\n if (isEuiTable || insideEuiTable) {\n collectChildElementRenames(node, edits);\n collectChildInputRemovals(node, source, edits, filePath, context);\n collectEmptyMessageRename(node, edits);\n }\n\n const childResult = visitNodesForTable(node.children, source, edits, isEuiTable || insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n\n if (node instanceof TmplAstTemplate) {\n if (insideEuiTable) {\n collectTemplateEmptyMessageRename(node, edits);\n }\n const childResult = visitNodesForTable(node.children, source, edits, insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n }\n\n return hasPaginator;\n}\n\nfunction hasEuiTableAttribute(element: TmplAstElement): boolean {\n return element.attributes.some((a) => a.name === 'euiTable') ||\n element.inputs.some((i) => i.name === 'euiTable');\n}\n\nfunction collectTableInputRenames(element: TmplAstElement, edits: Edit[]): void {\n for (const attr of element.attributes) {\n const newName = TABLE_INPUT_RENAMES.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = TABLE_INPUT_RENAMES.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildElementRenames(element: TmplAstElement, edits: Edit[]): void {\n const renames = (element.name === 'th' || element.name === 'td') ? TH_TD_INPUT_RENAMES\n : element.name === 'tr' ? TR_INPUT_RENAMES : null;\n if (!renames) return;\n\n for (const attr of element.attributes) {\n const newName = renames.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = renames.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n const childRemovedInputs = new Set(['defaultMultiOrder']);\n\n for (const attr of element.attributes) {\n if (childRemovedInputs.has(attr.name)) {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (childRemovedInputs.has(input.name)) {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const attr of element.attributes) {\n if (REMOVED_INPUTS.has(attr.name) && attr.name !== 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (REMOVED_INPUTS.has(input.name) && input.name !== 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectOutputChanges(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const output of element.outputs) {\n const newName = OUTPUT_RENAMES.get(output.name);\n if (newName) {\n edits.push({ start: output.keySpan!.start.offset, end: output.keySpan!.end.offset, replacement: newName });\n }\n if (REMOVED_OUTPUTS.has(output.name)) {\n removeAttribute(output.sourceSpan.start.offset, output.sourceSpan.end.offset, source, edits);\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(${output.name})\" removed. Multi-sort is now supported by (sortChange) output.`,\n );\n }\n }\n}\n\nfunction collectPaginatorMigration(element: TmplAstElement, source: string, edits: Edit[]): boolean {\n let found = false;\n\n for (const attr of element.attributes) {\n if (attr.name === 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n for (const input of element.inputs) {\n if (input.name === 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n\n if (found) {\n // Add [paginator]=\"paginator\" before closing > of opening tag\n const insertPos = element.startSourceSpan.end.offset - 1;\n edits.push({ start: insertPos, end: insertPos, replacement: ' [paginator]=\"paginator\"' });\n\n // Add eui-paginator after </table>\n if (element.endSourceSpan) {\n const afterTable = element.endSourceSpan.end.offset;\n edits.push({\n start: afterTable,\n end: afterTable,\n replacement: '\\n<!-- TODO: Configure paginator and implement onPageChange handler -->\\n<eui-paginator #paginator [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\" />',\n });\n }\n }\n\n return found;\n}\n\nfunction collectEmptyMessageRename(element: TmplAstElement, edits: Edit[]): void {\n // Handle direct attribute on elements (unlikely but handle)\n for (const attr of element.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\nfunction collectTemplateEmptyMessageRename(template: TmplAstTemplate, edits: Edit[]): void {\n for (const attr of template.templateAttrs) {\n if (attr instanceof TmplAstTextAttribute && attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n for (const attr of template.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\n// --- Pipe rename via AST ---\n\nfunction collectPipeRenames(nodes: TmplAstNode[], source: string, edits: Edit[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n for (const output of node.outputs) {\n if (output.handler) visitExpressionForPipes(output.handler, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstTemplate) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstBoundText) {\n visitExpressionForPipes(node.value, edits);\n }\n }\n}\n\nfunction visitExpressionForPipes(expr: AST, edits: Edit[]): void {\n if (expr instanceof ASTWithSource && expr.ast) {\n visitAstForPipes(expr.ast, edits);\n } else {\n visitAstForPipes(expr, edits);\n }\n}\n\nfunction visitAstForPipes(ast: AST, edits: Edit[]): void {\n if (ast instanceof BindingPipe) {\n if (ast.name === OLD_PIPE && ast.nameSpan) {\n edits.push({ start: ast.nameSpan.start, end: ast.nameSpan.end, replacement: NEW_PIPE });\n }\n visitAstForPipes(ast.exp, edits);\n for (const arg of ast.args) {\n visitAstForPipes(arg, edits);\n }\n return;\n }\n\n if (ast instanceof Interpolation) {\n for (const expr of ast.expressions) {\n visitAstForPipes(expr, edits);\n }\n return;\n }\n\n // Recursively visit all properties that could contain AST nodes\n for (const key of Object.keys(ast)) {\n // eslint-disable-next-line\n const val = (ast as any)[key];\n if (val instanceof AST) {\n visitAstForPipes(val, edits);\n } else if (Array.isArray(val)) {\n for (const item of val) {\n if (item instanceof AST) visitAstForPipes(item, edits);\n }\n }\n }\n}\n\n// --- Import handling for paginator ---\n\nfunction addPaginatorImport(source: string, filePath: string): string {\n if (source.includes(PAGINATOR_COMPONENT)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Add import statement after last import\n let lastImportEnd = 0;\n for (const stmt of sourceFile.statements) {\n if (ts.isImportDeclaration(stmt)) {\n lastImportEnd = stmt.getEnd();\n }\n }\n\n if (lastImportEnd > 0) {\n edits.push({\n start: lastImportEnd,\n end: lastImportEnd,\n replacement: `\\nimport { ${PAGINATOR_COMPONENT} } from '${PAGINATOR_IMPORT_PATH}';`,\n });\n }\n\n // Add to component imports array\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === 'imports' && isComponentMetadataProperty(node)) {\n if (ts.isArrayLiteralExpression(node.initializer)) {\n const arr = node.initializer;\n const elements = arr.elements;\n if (elements.length > 0) {\n const lastElement = elements[elements.length - 1];\n edits.push({\n start: lastElement.getEnd(),\n end: lastElement.getEnd(),\n replacement: `, ${PAGINATOR_COMPONENT}`,\n });\n } else {\n const insertPos = arr.getStart(sourceFile) + 1;\n edits.push({ start: insertPos, end: insertPos, replacement: PAGINATOR_COMPONENT });\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return applyEdits(source, edits);\n}\n\n// --- Helpers ---\n\nfunction removeAttribute(start: number, end: number, source: string, edits: Edit[]): void {\n let adjustedStart = start;\n while (adjustedStart > 0 && (source[adjustedStart - 1] === ' ' || source[adjustedStart - 1] === '\\t')) {\n adjustedStart--;\n }\n edits.push({ start: adjustedStart, end, replacement: '' });\n}\n\nfunction logRemovalWarning(name: string, filePath: string, element: TmplAstElement, context: SchematicContext): void {\n const { line } = element.startSourceSpan.start;\n if (name === 'defaultMultiOrder') {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed. Use setSort(Sort[]) to initialize sorting.`);\n } else {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed to align to Design System.`);\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n const unique = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n unique.set(key, edit);\n }\n let result = source;\n for (const edit of [...unique.values()].sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
2968
2862
|
"displayName": "Schema",
|
|
2969
2863
|
"properties": [
|
|
2970
2864
|
{
|
|
@@ -2976,7 +2870,7 @@
|
|
|
2976
2870
|
"indexKey": "",
|
|
2977
2871
|
"optional": true,
|
|
2978
2872
|
"description": "",
|
|
2979
|
-
"line":
|
|
2873
|
+
"line": 49,
|
|
2980
2874
|
"rawdescription": "\n"
|
|
2981
2875
|
},
|
|
2982
2876
|
{
|
|
@@ -2988,7 +2882,7 @@
|
|
|
2988
2882
|
"indexKey": "",
|
|
2989
2883
|
"optional": true,
|
|
2990
2884
|
"description": "",
|
|
2991
|
-
"line":
|
|
2885
|
+
"line": 48,
|
|
2992
2886
|
"rawdescription": "\n"
|
|
2993
2887
|
}
|
|
2994
2888
|
],
|
|
@@ -2997,8 +2891,8 @@
|
|
|
2997
2891
|
"methods": [],
|
|
2998
2892
|
"extends": [],
|
|
2999
2893
|
"isDuplicate": true,
|
|
3000
|
-
"duplicateId":
|
|
3001
|
-
"duplicateName": "Schema-
|
|
2894
|
+
"duplicateId": 15,
|
|
2895
|
+
"duplicateName": "Schema-15",
|
|
3002
2896
|
"relationships": {
|
|
3003
2897
|
"incoming": [],
|
|
3004
2898
|
"outgoing": []
|
|
@@ -3006,12 +2900,12 @@
|
|
|
3006
2900
|
},
|
|
3007
2901
|
{
|
|
3008
2902
|
"name": "Schema",
|
|
3009
|
-
"id": "interface-Schema-
|
|
3010
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2903
|
+
"id": "interface-Schema-760dec88d3f709d5b38226e55f7cbfb1e5fabcea6c004fd46e611be1dd563b8b247e9e6c77667e5582fe7b443374ba2c4facd2b2db2985edb46c9a4a37a8a876-16",
|
|
2904
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
3011
2905
|
"deprecated": false,
|
|
3012
2906
|
"deprecationMessage": "",
|
|
3013
2907
|
"type": "interface",
|
|
3014
|
-
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\nconst OLD_TAG = 'eui-toolbar-menu';\nconst NEW_TAG = 'eui-toolbar-mega-menu';\nconst OLD_COMPONENT = 'EuiToolbarMenuComponent';\nconst NEW_COMPONENT = 'EuiToolbarMegaMenuComponent';\nconst OLD_INTERFACE = 'ToolbarItem';\nconst NEW_INTERFACE = 'EuiMenuItem';\nconst NEW_COMPONENT_PATH = '@eui/components/layout';\nconst NEW_INTERFACE_PATH = '@eui/core';\nconst REMOVED_OUTPUT = 'menuItemClick';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\ninterface Edit {\n start: number;\n end: number;\n replacement: string;\n}\n\nexport function migrateEuiToolbarMenu(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let fileCount = 0;\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(OLD_TAG) && !original.includes(OLD_COMPONENT) && !original.includes(OLD_INTERFACE)) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original, path, context);\n } else {\n result = migrateTypeScript(original, path, context);\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-toolbar-menu → eui-toolbar-mega-menu in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n fileCount++;\n }\n });\n\n context.logger.info(`Migrated eui-toolbar-menu → eui-toolbar-mega-menu in ${fileCount} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n\n visitNodes(parsed.nodes, source, edits, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): string {\n let result = migrateInlineTemplates(source, filePath, context);\n result = migrateImportsAndTypes(result, filePath, context);\n return result;\n}\n\nfunction migrateInlineTemplates(source: string, filePath: string, context: SchematicContext): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(OLD_TAG)) {\n ts.forEachChild(node, visit); return; \n}\n const migrated = migrateTemplate(rawTemplate, filePath, context);\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, changes);\n}\n\nfunction migrateImportsAndTypes(source: string, filePath: string, context: SchematicContext): string {\n if (!source.includes(OLD_COMPONENT) && !source.includes(OLD_INTERFACE)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Track if EuiMenuItem is already imported from @eui/core\n let hasEuiMenuItemImport = false;\n\n // First pass: analyze imports\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpec = (stmt.moduleSpecifier as ts.StringLiteral).text;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n for (const specifier of namedBindings.elements) {\n if (specifier.name.text === NEW_INTERFACE && moduleSpec === NEW_INTERFACE_PATH) {\n hasEuiMenuItemImport = true;\n }\n }\n }\n\n // Second pass: collect edits for import declarations\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n const moduleSpec = stmt.moduleSpecifier as ts.StringLiteral;\n const specifiers = namedBindings.elements;\n const hasComponent = specifiers.some((s) => s.name.text === OLD_COMPONENT);\n const hasInterface = specifiers.some((s) => s.name.text === OLD_INTERFACE);\n\n if (hasComponent && hasInterface) {\n // Both are in the same import → must split into two different paths\n const others = specifiers.filter((s) => s.name.text !== OLD_COMPONENT && s.name.text !== OLD_INTERFACE);\n const lines: string[] = [];\n lines.push(`import { ${NEW_COMPONENT} } from '${NEW_COMPONENT_PATH}';`);\n if (!hasEuiMenuItemImport) {\n lines.push(`import { ${NEW_INTERFACE} } from '${NEW_INTERFACE_PATH}';`);\n }\n if (others.length > 0) {\n const otherNames = others.map((s) => s.name.text).join(', ');\n lines.push(`import { ${otherNames} } from '${moduleSpec.text}';`);\n }\n edits.push({\n start: stmt.getStart(sourceFile),\n end: stmt.getEnd(),\n replacement: lines.join('\\n'),\n });\n } else if (hasComponent) {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_COMPONENT_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_COMPONENT) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_COMPONENT,\n });\n }\n }\n } else if (hasInterface) {\n if (hasEuiMenuItemImport) {\n removeImportSpecifier(namedBindings, specifiers.find((s) => s.name.text === OLD_INTERFACE)!, sourceFile, edits);\n } else {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_INTERFACE_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_INTERFACE) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_INTERFACE,\n });\n }\n }\n }\n }\n }\n\n // Third pass: rename identifier references in non-import positions\n const visitRefs = (node: ts.Node): void => {\n if (ts.isImportDeclaration(node)) return; // skip imports (already handled)\n if (ts.isIdentifier(node)) {\n if (node.text === OLD_COMPONENT) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_COMPONENT });\n }\n if (node.text === OLD_INTERFACE) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_INTERFACE });\n }\n }\n ts.forEachChild(node, visitRefs);\n };\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) {\n visitRefs(stmt);\n }\n }\n\n // Warn about ToolbarItem-specific properties\n warnRemovedProperties(sourceFile, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction removeImportSpecifier(\n namedImports: ts.NamedImports,\n specifier: ts.ImportSpecifier,\n sourceFile: ts.SourceFile,\n edits: Edit[],\n): void {\n const elements = namedImports.elements;\n if (elements.length === 1) {\n // Remove the entire import declaration\n const importDecl = namedImports.parent.parent;\n edits.push({\n start: importDecl.getStart(sourceFile),\n end: importDecl.getEnd(),\n replacement: '',\n });\n } else {\n // Remove just this specifier with surrounding comma/whitespace\n const idx = elements.indexOf(specifier);\n let start: number;\n let end: number;\n if (idx < elements.length - 1) {\n start = specifier.getStart(sourceFile);\n end = elements[idx + 1].getStart(sourceFile);\n } else {\n start = elements[idx - 1].getEnd();\n end = specifier.getEnd();\n }\n edits.push({ start, end, replacement: '' });\n }\n}\n\nfunction warnRemovedProperties(sourceFile: ts.SourceFile, filePath: string, context: SchematicContext): void {\n const deprecated = ['isHome', 'isSeparator'];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === OLD_TAG) {\n collectTagRenames(node, source, edits);\n collectOutputRemovals(node, source, edits, filePath, context);\n }\n visitNodes(node.children, source, edits, filePath, context);\n }\n }\n}\n\nfunction collectTagRenames(element: TmplAstElement, source: string, edits: Edit[]): void {\n // Rename opening tag\n const openStart = element.startSourceSpan.start.offset + 1; // skip '<'\n edits.push({ start: openStart, end: openStart + OLD_TAG.length, replacement: NEW_TAG });\n\n // Rename closing tag\n if (element.endSourceSpan) {\n const closeStart = element.endSourceSpan.start.offset + 2; // skip '</'\n edits.push({ start: closeStart, end: closeStart + OLD_TAG.length, replacement: NEW_TAG });\n }\n}\n\nfunction collectOutputRemovals(\n element: TmplAstElement,\n source: string,\n edits: Edit[],\n filePath: string,\n context: SchematicContext,\n): void {\n for (const output of element.outputs) {\n if (output.name === REMOVED_OUTPUT) {\n let start = output.sourceSpan.start.offset;\n // Remove leading whitespace\n while (start > 0 && (source[start - 1] === ' ' || source[start - 1] === '\\t')) {\n start--;\n }\n edits.push({ start, end: output.sourceSpan.end.offset, replacement: '' });\n\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(menuItemClick)\" has been removed. There is no equivalent on eui-toolbar-mega-menu.`,\n );\n }\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n // Deduplicate edits at same position (e.g. module path edits when both Component and ToolbarItem are from same source)\n const unique = deduplicateEdits(edits);\n let result = source;\n for (const edit of unique.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction deduplicateEdits(edits: Edit[]): Edit[] {\n const seen = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n // Last wins for same range\n seen.set(key, edit);\n }\n return Array.from(seen.values());\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
2908
|
+
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface TextChange {\n start: number;\n end: number;\n text: string;\n}\n\ninterface MigrationResult {\n content: string;\n migrated: number;\n skipped: number;\n}\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst OLD_LABEL = 'eui-tab-label';\nconst OLD_SUB_LABEL = 'euiTabSubLabel';\nconst OLD_CONTENT = 'eui-tab-content';\nconst NEW_HEADER = 'eui-tab-header';\nconst NEW_HEADER_LABEL = 'eui-tab-header-label';\nconst NEW_HEADER_SUB_LABEL = 'eui-tab-header-sub-label';\nconst NEW_BODY = 'eui-tab-body';\n\nexport function migrateEuiTabs(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let migrated = 0;\n let skipped = 0;\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) {\n return;\n }\n\n const original = buffer.toString('utf-8');\n const result = path.endsWith('.html')\n ? migrateTemplate(original, path, context)\n : migrateInlineTemplates(original, path, context);\n\n migrated += result.migrated;\n skipped += result.skipped;\n\n if (result.content !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate ${result.migrated} tab block(s) in ${path}`);\n } else {\n tree.overwrite(path, result.content);\n }\n }\n });\n\n context.logger.info(`Migrated ${migrated} EUI tab template block(s).`);\n if (skipped > 0) {\n context.logger.warn(`Skipped ${skipped} malformed EUI tab template block(s).`);\n }\n if (options.dryRun) {\n logDryRunNote(context);\n }\n\n return tree;\n };\n}\n\nfunction migrateInlineTemplates(source: string, filePath: string, context: SchematicContext): MigrationResult {\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: TextChange[] = [];\n let migrated = 0;\n let skipped = 0;\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const initializer = unwrapExpression(node.initializer);\n\n if (ts.isStringLiteral(initializer) || ts.isNoSubstitutionTemplateLiteral(initializer)) {\n const start = initializer.getStart(sourceFile) + 1;\n const end = initializer.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n const result = migrateTemplate(rawTemplate, `${filePath}@inline-template`, context);\n\n migrated += result.migrated;\n skipped += result.skipped;\n\n if (result.content !== rawTemplate) {\n changes.push({ start, end, text: result.content });\n }\n } else if (ts.isTemplateExpression(initializer)) {\n context.logger.warn(`Skipping interpolated inline template in ${filePath}.`);\n skipped++;\n }\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return {\n content: applyChanges(source, changes),\n migrated,\n skipped,\n };\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (\n (ts.isIdentifier(name) && name.text === 'template') ||\n (ts.isStringLiteral(name) && name.text === 'template')\n );\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n\n while (ts.isParenthesizedExpression(current)) {\n current = current.expression;\n }\n\n return current;\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) {\n return false;\n }\n\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) {\n return false;\n }\n\n return (\n ts.isDecorator(callExpression.parent) &&\n ts.isIdentifier(callExpression.expression) &&\n callExpression.expression.text === 'Component'\n );\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): MigrationResult {\n const parsed = parseTemplate(source, filePath, { preserveWhitespaces: true });\n const changes: TextChange[] = [];\n let migrated = 0;\n let skipped = 0;\n\n for (const error of parsed.errors ?? []) {\n context.logger.warn(`Template parse warning in ${filePath}: ${error.msg}`);\n }\n\n for (const tab of findElements(parsed.nodes, 'eui-tab')) {\n const label = findDirectChild(tab, OLD_LABEL);\n const content = findDirectChild(tab, OLD_CONTENT);\n const hasOldMarkup = Boolean(label || content);\n const hasNewMarkup = Boolean(findDirectChild(tab, NEW_HEADER) || findDirectChild(tab, NEW_BODY));\n\n if (!hasOldMarkup || hasNewMarkup) {\n continue;\n }\n\n if (!label || !content) {\n context.logger.warn(`Skipping malformed <eui-tab> in ${filePath}.`);\n skipped++;\n continue;\n }\n\n changes.push({\n start: label.sourceSpan.start.offset,\n end: label.sourceSpan.end.offset,\n text: buildHeaderReplacement(source, label),\n });\n changes.push({\n start: content.sourceSpan.start.offset,\n end: content.sourceSpan.end.offset,\n text: buildBodyReplacement(source, content),\n });\n migrated++;\n }\n\n return {\n content: applyChanges(source, withoutOverlaps(changes)),\n migrated,\n skipped,\n };\n}\n\nfunction findElements(nodes: readonly TmplAstNode[], name: string): TmplAstElement[] {\n const matches: TmplAstElement[] = [];\n\n for (const node of nodes) {\n if (isElement(node)) {\n if (node.name === name) {\n matches.push(node);\n }\n matches.push(...findElements(node.children, name));\n }\n }\n\n return matches;\n}\n\nfunction findDirectChild(element: TmplAstElement, name: string): TmplAstElement | undefined {\n return element.children.find((child): child is TmplAstElement => isElement(child) && child.name === name);\n}\n\nfunction isElement(node: TmplAstNode): node is TmplAstElement {\n return node instanceof TmplAstElement;\n}\n\nfunction buildHeaderReplacement(source: string, label: TmplAstElement): string {\n const indent = getIndent(source, label.sourceSpan.start.offset);\n const labelAttributes = getAttributeText(source, label, OLD_LABEL);\n const subLabels = findElements(label.children, OLD_SUB_LABEL);\n const mainLabelContent = removeElementRanges(getInnerText(source, label), label, subLabels);\n const lines = [\n `<${NEW_HEADER}>`,\n `${indent} <${NEW_HEADER_LABEL}${labelAttributes}>`,\n ...formatInnerLines(mainLabelContent, `${indent} `),\n `${indent} </${NEW_HEADER_LABEL}>`,\n ];\n\n for (const subLabel of subLabels) {\n const subLabelAttributes = getAttributeText(source, subLabel, OLD_SUB_LABEL);\n lines.push(\n `${indent} <${NEW_HEADER_SUB_LABEL}${subLabelAttributes}>`,\n ...formatInnerLines(getInnerText(source, subLabel), `${indent} `),\n `${indent} </${NEW_HEADER_SUB_LABEL}>`,\n );\n }\n\n lines.push(`${indent}</${NEW_HEADER}>`);\n\n return lines.join('\\n');\n}\n\nfunction buildBodyReplacement(source: string, content: TmplAstElement): string {\n const indent = getIndent(source, content.sourceSpan.start.offset);\n const attributes = getAttributeText(source, content, OLD_CONTENT);\n const innerText = getInnerText(source, content);\n const trimmed = innerText.trim();\n\n if (trimmed && !trimmed.includes('\\n')) {\n return `<${NEW_BODY}${attributes}>${trimmed}</${NEW_BODY}>`;\n }\n\n return [\n `<${NEW_BODY}${attributes}>`,\n ...formatInnerLines(innerText, `${indent} `),\n `${indent}</${NEW_BODY}>`,\n ].join('\\n');\n}\n\nfunction getInnerText(source: string, element: TmplAstElement): string {\n if (!element.endSourceSpan) {\n return '';\n }\n\n return source.slice(element.startSourceSpan.end.offset, element.endSourceSpan.start.offset);\n}\n\nfunction removeElementRanges(source: string, parent: TmplAstElement, elements: readonly TmplAstElement[]): string {\n const parentContentStart = parent.startSourceSpan.end.offset;\n let result = source;\n\n for (const element of [...elements].sort((a, b) => b.sourceSpan.start.offset - a.sourceSpan.start.offset)) {\n const start = element.sourceSpan.start.offset - parentContentStart;\n const end = element.sourceSpan.end.offset - parentContentStart;\n result = result.slice(0, start) + result.slice(end);\n }\n\n return result;\n}\n\nfunction getAttributeText(source: string, element: TmplAstElement, tagName: string): string {\n const startTag = source.slice(element.startSourceSpan.start.offset, element.startSourceSpan.end.offset);\n const tagStart = startTag.indexOf(tagName);\n\n if (tagStart === -1) {\n return '';\n }\n\n const contentEnd = startTag.endsWith('/>') ? startTag.length - 2 : startTag.length - 1;\n return startTag.slice(tagStart + tagName.length, contentEnd).trimEnd();\n}\n\nfunction getIndent(source: string, offset: number): string {\n const lineStart = source.lastIndexOf('\\n', offset - 1) + 1;\n const prefix = source.slice(lineStart, offset);\n return prefix.match(/^\\s*/)?.[0] ?? '';\n}\n\nfunction formatInnerLines(source: string, indent: string): string[] {\n const trimmed = source.trim();\n\n if (!trimmed) {\n return [];\n }\n\n return trimmed.split(/\\r?\\n/).map((line) => `${indent}${line.trim()}`);\n}\n\nfunction withoutOverlaps(changes: TextChange[]): TextChange[] {\n const accepted: TextChange[] = [];\n\n for (const change of [...changes].sort((a, b) => a.start - b.start || b.end - a.end)) {\n if (!accepted.some((current) => change.start < current.end && current.start < change.end)) {\n accepted.push(change);\n }\n }\n\n return accepted;\n}\n\nfunction applyChanges(source: string, changes: readonly TextChange[]): string {\n let result = source;\n\n for (const change of [...changes].sort((a, b) => b.start - a.start)) {\n result = result.slice(0, change.start) + change.text + result.slice(change.end);\n }\n\n return result;\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
3015
2909
|
"displayName": "Schema",
|
|
3016
2910
|
"properties": [
|
|
3017
2911
|
{
|
|
@@ -3023,7 +2917,7 @@
|
|
|
3023
2917
|
"indexKey": "",
|
|
3024
2918
|
"optional": true,
|
|
3025
2919
|
"description": "",
|
|
3026
|
-
"line":
|
|
2920
|
+
"line": 20,
|
|
3027
2921
|
"rawdescription": "\n"
|
|
3028
2922
|
},
|
|
3029
2923
|
{
|
|
@@ -3035,7 +2929,7 @@
|
|
|
3035
2929
|
"indexKey": "",
|
|
3036
2930
|
"optional": true,
|
|
3037
2931
|
"description": "",
|
|
3038
|
-
"line":
|
|
2932
|
+
"line": 19,
|
|
3039
2933
|
"rawdescription": "\n"
|
|
3040
2934
|
}
|
|
3041
2935
|
],
|
|
@@ -3044,8 +2938,8 @@
|
|
|
3044
2938
|
"methods": [],
|
|
3045
2939
|
"extends": [],
|
|
3046
2940
|
"isDuplicate": true,
|
|
3047
|
-
"duplicateId":
|
|
3048
|
-
"duplicateName": "Schema-
|
|
2941
|
+
"duplicateId": 16,
|
|
2942
|
+
"duplicateName": "Schema-16",
|
|
3049
2943
|
"relationships": {
|
|
3050
2944
|
"incoming": [],
|
|
3051
2945
|
"outgoing": []
|
|
@@ -3053,12 +2947,12 @@
|
|
|
3053
2947
|
},
|
|
3054
2948
|
{
|
|
3055
2949
|
"name": "Schema",
|
|
3056
|
-
"id": "interface-Schema-
|
|
3057
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2950
|
+
"id": "interface-Schema-e1cd02924eb82a618c71a0b26c081bdd020519d2699aa0e2dc98640c4e0f347c3649b967c5fc87543e41bbbfabd1304835850ccc38f40684d6521c242b2030ed-17",
|
|
2951
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
3058
2952
|
"deprecated": false,
|
|
3059
2953
|
"deprecationMessage": "",
|
|
3060
2954
|
"type": "interface",
|
|
3061
|
-
"sourceCode": "import { BindingPipe, parseTemplate, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstBoundText, TmplAstElement, TmplAstNode, TmplAstTemplate, TmplAstTextAttribute, AST, ASTWithSource, Interpolation } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Edit { start: number; end: number; replacement: string; }\n\n// --- Table-level input renames (on elements with euiTable attribute) ---\nconst TABLE_INPUT_RENAMES = new Map([\n ['rows', 'data'],\n ['loading', 'isLoading'],\n ['asyncTable', 'isAsync'],\n ['euiTableResponsive', 'isTableResponsive'],\n ['euiTableFixedLayout', 'isTableFixedLayout'],\n ['euiTableCompact', 'isTableCompact'],\n ['hasStickyColumns', 'hasStickyCols'],\n]);\n\n// --- Child element input renames (scoped to euiTable context) ---\nconst TH_TD_INPUT_RENAMES = new Map([\n ['isStickyColumn', 'isStickyCol'],\n ['sortable', 'isSortable'],\n]);\n\nconst TR_INPUT_RENAMES = new Map([\n ['isSelectableHeader', 'isHeaderSelectable'],\n ['isSelectable', 'isDataSelectable'],\n]);\n\n// --- Removed inputs ---\nconst REMOVED_INPUTS = new Set(['euiTableBordered', 'isHoverable', 'defaultMultiOrder', 'paginable']);\n\n// --- Output renames/removals ---\nconst OUTPUT_RENAMES = new Map([['selectedRows', 'rowsSelect']]);\nconst REMOVED_OUTPUTS = new Set(['multiSortChange']);\n\n// --- Pipe rename ---\nconst OLD_PIPE = 'euiTableHighlightFilter';\nconst NEW_PIPE = 'euiTableHighlight';\n\n// --- TS property renames ---\nconst TS_PROPERTY_RENAMES = new Map([['filteredRows', 'getFilteredData']]);\n\nconst PAGINATOR_IMPORT_PATH = '@eui/components/eui-paginator';\nconst PAGINATOR_COMPONENT = 'EuiPaginatorComponent';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nexport function migrateEuiTable(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n const paginatorHtmlFiles = new Set<string>();\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes('euiTable') && !original.includes(OLD_PIPE) && !original.includes('filteredRows') && !original.includes('setSort')) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n const { output, hasPaginator } = migrateTemplateWithPaginator(original, path, context);\n result = output;\n if (hasPaginator) paginatorHtmlFiles.add(path);\n } else {\n const { output, hasPaginator } = migrateTypeScript(original, path, context);\n result = output;\n if (hasPaginator) {\n result = addPaginatorImport(result, path);\n }\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-table breaking changes in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n count++;\n }\n });\n\n // Handle paginator imports for external templates\n if (paginatorHtmlFiles.size > 0) {\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n if (!path.endsWith('.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const source = buffer.toString('utf-8');\n if (!source.includes('templateUrl')) return;\n\n for (const htmlFile of paginatorHtmlFiles) {\n const htmlFileName = htmlFile.split('/').pop()!;\n if (source.includes(htmlFileName)) {\n const updated = addPaginatorImport(source, path);\n if (updated !== source) {\n if (options.dryRun) {\n logDryRun(context, `Would add paginator import in ${path}`);\n } else {\n tree.overwrite(path, updated);\n }\n count++;\n }\n break;\n }\n }\n });\n }\n\n context.logger.info(`Migrated eui-table in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplateWithPaginator(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n let hasPaginator = false;\n\n const paginatorResult = visitNodesForTable(parsed.nodes, source, edits, false, filePath, context);\n if (paginatorResult) hasPaginator = true;\n\n collectPipeRenames(parsed.nodes, source, edits);\n\n return { output: applyEdits(source, edits), hasPaginator };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n return migrateTemplateWithPaginator(source, filePath, context).output;\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): { output: string; hasPaginator: boolean } {\n let result = source;\n let hasPaginator = false;\n\n // Migrate inline templates\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = result.slice(start, end);\n if (!rawTemplate.includes('euiTable') && !rawTemplate.includes(OLD_PIPE)) {\n ts.forEachChild(node, visit); return;\n}\n const { output: migrated, hasPaginator: pag } = migrateTemplateWithPaginator(rawTemplate, filePath, context);\n if (pag) hasPaginator = true;\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n result = applyEdits(result, changes);\n\n // Rename TS property accesses\n result = renameTsProperties(result);\n\n // Warn about setSort\n warnSetSort(result, filePath, context);\n\n return { output: result, hasPaginator };\n}\n\nfunction renameTsProperties(source: string): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && TS_PROPERTY_RENAMES.has(node.name.text)) {\n edits.push({ start: node.name.getStart(sourceFile), end: node.name.getEnd(), replacement: TS_PROPERTY_RENAMES.get(node.name.text)! });\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, edits);\n}\n\nfunction warnSetSort(source: string, filePath: string, context: SchematicContext): void {\n if (!source.includes('setSort')) return;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) &&\n ts.isIdentifier(node.expression.name) && node.expression.name.text === 'setSort') {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"setSort\" signature changed from setSort(sort: string, order: \"asc\" | \"desc\") to setSort(Sort[]). Update manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\n// --- Template AST visitors ---\n\nfunction visitNodesForTable(\n nodes: TmplAstNode[], source: string, edits: Edit[], insideEuiTable: boolean, filePath: string, context: SchematicContext,\n): boolean {\n let hasPaginator = false;\n\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n const isEuiTable = hasEuiTableAttribute(node);\n\n if (isEuiTable) {\n collectTableInputRenames(node, edits);\n collectInputRemovals(node, source, edits, filePath, context);\n collectOutputChanges(node, source, edits, filePath, context);\n if (collectPaginatorMigration(node, source, edits)) hasPaginator = true;\n }\n\n if (isEuiTable || insideEuiTable) {\n collectChildElementRenames(node, edits);\n collectChildInputRemovals(node, source, edits, filePath, context);\n collectEmptyMessageRename(node, edits);\n }\n\n const childResult = visitNodesForTable(node.children, source, edits, isEuiTable || insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n\n if (node instanceof TmplAstTemplate) {\n if (insideEuiTable) {\n collectTemplateEmptyMessageRename(node, edits);\n }\n const childResult = visitNodesForTable(node.children, source, edits, insideEuiTable, filePath, context);\n if (childResult) hasPaginator = true;\n }\n }\n\n return hasPaginator;\n}\n\nfunction hasEuiTableAttribute(element: TmplAstElement): boolean {\n return element.attributes.some((a) => a.name === 'euiTable') ||\n element.inputs.some((i) => i.name === 'euiTable');\n}\n\nfunction collectTableInputRenames(element: TmplAstElement, edits: Edit[]): void {\n for (const attr of element.attributes) {\n const newName = TABLE_INPUT_RENAMES.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = TABLE_INPUT_RENAMES.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildElementRenames(element: TmplAstElement, edits: Edit[]): void {\n const renames = (element.name === 'th' || element.name === 'td') ? TH_TD_INPUT_RENAMES\n : element.name === 'tr' ? TR_INPUT_RENAMES : null;\n if (!renames) return;\n\n for (const attr of element.attributes) {\n const newName = renames.get(attr.name);\n if (newName) edits.push({ start: attr.keySpan!.start.offset, end: attr.keySpan!.end.offset, replacement: newName });\n }\n for (const input of element.inputs) {\n const newName = renames.get(input.name);\n if (newName) edits.push({ start: input.keySpan!.start.offset, end: input.keySpan!.end.offset, replacement: newName });\n }\n}\n\nfunction collectChildInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n const childRemovedInputs = new Set(['defaultMultiOrder']);\n\n for (const attr of element.attributes) {\n if (childRemovedInputs.has(attr.name)) {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (childRemovedInputs.has(input.name)) {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectInputRemovals(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const attr of element.attributes) {\n if (REMOVED_INPUTS.has(attr.name) && attr.name !== 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n logRemovalWarning(attr.name, filePath, element, context);\n }\n }\n for (const input of element.inputs) {\n if (REMOVED_INPUTS.has(input.name) && input.name !== 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n logRemovalWarning(input.name, filePath, element, context);\n }\n }\n}\n\nfunction collectOutputChanges(element: TmplAstElement, source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const output of element.outputs) {\n const newName = OUTPUT_RENAMES.get(output.name);\n if (newName) {\n edits.push({ start: output.keySpan!.start.offset, end: output.keySpan!.end.offset, replacement: newName });\n }\n if (REMOVED_OUTPUTS.has(output.name)) {\n removeAttribute(output.sourceSpan.start.offset, output.sourceSpan.end.offset, source, edits);\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(${output.name})\" removed. Multi-sort is now supported by (sortChange) output.`,\n );\n }\n }\n}\n\nfunction collectPaginatorMigration(element: TmplAstElement, source: string, edits: Edit[]): boolean {\n let found = false;\n\n for (const attr of element.attributes) {\n if (attr.name === 'paginable') {\n removeAttribute(attr.sourceSpan.start.offset, attr.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n for (const input of element.inputs) {\n if (input.name === 'paginable') {\n removeAttribute(input.sourceSpan.start.offset, input.sourceSpan.end.offset, source, edits);\n found = true;\n }\n }\n\n if (found) {\n // Add [paginator]=\"paginator\" before closing > of opening tag\n const insertPos = element.startSourceSpan.end.offset - 1;\n edits.push({ start: insertPos, end: insertPos, replacement: ' [paginator]=\"paginator\"' });\n\n // Add eui-paginator after </table>\n if (element.endSourceSpan) {\n const afterTable = element.endSourceSpan.end.offset;\n edits.push({\n start: afterTable,\n end: afterTable,\n replacement: '\\n<!-- TODO: Configure paginator and implement onPageChange handler -->\\n<eui-paginator #paginator [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\" />',\n });\n }\n }\n\n return found;\n}\n\nfunction collectEmptyMessageRename(element: TmplAstElement, edits: Edit[]): void {\n // Handle direct attribute on elements (unlikely but handle)\n for (const attr of element.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\nfunction collectTemplateEmptyMessageRename(template: TmplAstTemplate, edits: Edit[]): void {\n for (const attr of template.templateAttrs) {\n if (attr instanceof TmplAstTextAttribute && attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n for (const attr of template.attributes) {\n if (attr.name === 'euiTemplate' && attr.value === 'emptyMessage' && attr.valueSpan) {\n edits.push({ start: attr.valueSpan.start.offset, end: attr.valueSpan.end.offset, replacement: 'footer' });\n }\n }\n}\n\n// --- Pipe rename via AST ---\n\nfunction collectPipeRenames(nodes: TmplAstNode[], source: string, edits: Edit[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n for (const output of node.outputs) {\n if (output.handler) visitExpressionForPipes(output.handler, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstTemplate) {\n for (const input of node.inputs) {\n visitExpressionForPipes(input.value, edits);\n }\n collectPipeRenames(node.children, source, edits);\n }\n if (node instanceof TmplAstBoundText) {\n visitExpressionForPipes(node.value, edits);\n }\n }\n}\n\nfunction visitExpressionForPipes(expr: AST, edits: Edit[]): void {\n if (expr instanceof ASTWithSource && expr.ast) {\n visitAstForPipes(expr.ast, edits);\n } else {\n visitAstForPipes(expr, edits);\n }\n}\n\nfunction visitAstForPipes(ast: AST, edits: Edit[]): void {\n if (ast instanceof BindingPipe) {\n if (ast.name === OLD_PIPE && ast.nameSpan) {\n edits.push({ start: ast.nameSpan.start, end: ast.nameSpan.end, replacement: NEW_PIPE });\n }\n visitAstForPipes(ast.exp, edits);\n for (const arg of ast.args) {\n visitAstForPipes(arg, edits);\n }\n return;\n }\n\n if (ast instanceof Interpolation) {\n for (const expr of ast.expressions) {\n visitAstForPipes(expr, edits);\n }\n return;\n }\n\n // Recursively visit all properties that could contain AST nodes\n for (const key of Object.keys(ast)) {\n // eslint-disable-next-line\n const val = (ast as any)[key];\n if (val instanceof AST) {\n visitAstForPipes(val, edits);\n } else if (Array.isArray(val)) {\n for (const item of val) {\n if (item instanceof AST) visitAstForPipes(item, edits);\n }\n }\n }\n}\n\n// --- Import handling for paginator ---\n\nfunction addPaginatorImport(source: string, filePath: string): string {\n if (source.includes(PAGINATOR_COMPONENT)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Add import statement after last import\n let lastImportEnd = 0;\n for (const stmt of sourceFile.statements) {\n if (ts.isImportDeclaration(stmt)) {\n lastImportEnd = stmt.getEnd();\n }\n }\n\n if (lastImportEnd > 0) {\n edits.push({\n start: lastImportEnd,\n end: lastImportEnd,\n replacement: `\\nimport { ${PAGINATOR_COMPONENT} } from '${PAGINATOR_IMPORT_PATH}';`,\n });\n }\n\n // Add to component imports array\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === 'imports' && isComponentMetadataProperty(node)) {\n if (ts.isArrayLiteralExpression(node.initializer)) {\n const arr = node.initializer;\n const elements = arr.elements;\n if (elements.length > 0) {\n const lastElement = elements[elements.length - 1];\n edits.push({\n start: lastElement.getEnd(),\n end: lastElement.getEnd(),\n replacement: `, ${PAGINATOR_COMPONENT}`,\n });\n } else {\n const insertPos = arr.getStart(sourceFile) + 1;\n edits.push({ start: insertPos, end: insertPos, replacement: PAGINATOR_COMPONENT });\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n\n return applyEdits(source, edits);\n}\n\n// --- Helpers ---\n\nfunction removeAttribute(start: number, end: number, source: string, edits: Edit[]): void {\n let adjustedStart = start;\n while (adjustedStart > 0 && (source[adjustedStart - 1] === ' ' || source[adjustedStart - 1] === '\\t')) {\n adjustedStart--;\n }\n edits.push({ start: adjustedStart, end, replacement: '' });\n}\n\nfunction logRemovalWarning(name: string, filePath: string, element: TmplAstElement, context: SchematicContext): void {\n const { line } = element.startSourceSpan.start;\n if (name === 'defaultMultiOrder') {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed. Use setSort(Sort[]) to initialize sorting.`);\n } else {\n context.logger.warn(`${filePath}:${line + 1} - \"[${name}]\" removed to align to Design System.`);\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n const unique = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n unique.set(key, edit);\n }\n let result = source;\n for (const edit of [...unique.values()].sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
2955
|
+
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\nconst OLD_TAG = 'eui-toolbar-menu';\nconst NEW_TAG = 'eui-toolbar-mega-menu';\nconst OLD_COMPONENT = 'EuiToolbarMenuComponent';\nconst NEW_COMPONENT = 'EuiToolbarMegaMenuComponent';\nconst OLD_INTERFACE = 'ToolbarItem';\nconst NEW_INTERFACE = 'EuiMenuItem';\nconst NEW_COMPONENT_PATH = '@eui/components/layout';\nconst NEW_INTERFACE_PATH = '@eui/core';\nconst REMOVED_OUTPUT = 'menuItemClick';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\ninterface Edit {\n start: number;\n end: number;\n replacement: string;\n}\n\nexport function migrateEuiToolbarMenu(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let fileCount = 0;\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n const buffer = tree.read(path);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n if (!original.includes(OLD_TAG) && !original.includes(OLD_COMPONENT) && !original.includes(OLD_INTERFACE)) return;\n\n let result: string;\n\n if (path.endsWith('.html')) {\n result = migrateTemplate(original, path, context);\n } else {\n result = migrateTypeScript(original, path, context);\n }\n\n if (result !== original) {\n if (options.dryRun) {\n logDryRun(context, `Would migrate eui-toolbar-menu → eui-toolbar-mega-menu in ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n fileCount++;\n }\n });\n\n context.logger.info(`Migrated eui-toolbar-menu → eui-toolbar-mega-menu in ${fileCount} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction migrateTemplate(source: string, filePath: string, context: SchematicContext): string {\n const parsed = parseTemplate(source, '', { preserveWhitespaces: true });\n const edits: Edit[] = [];\n\n visitNodes(parsed.nodes, source, edits, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction migrateTypeScript(source: string, filePath: string, context: SchematicContext): string {\n let result = migrateInlineTemplates(source, filePath, context);\n result = migrateImportsAndTypes(result, filePath, context);\n return result;\n}\n\nfunction migrateInlineTemplates(source: string, filePath: string, context: SchematicContext): string {\n const sourceFile = ts.createSourceFile('', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const changes: Edit[] = [];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAssignment(node) && isTemplateProperty(node) && isComponentMetadataProperty(node)) {\n const init = unwrapExpression(node.initializer);\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n const start = init.getStart(sourceFile) + 1;\n const end = init.getEnd() - 1;\n const rawTemplate = source.slice(start, end);\n if (!rawTemplate.includes(OLD_TAG)) {\n ts.forEachChild(node, visit); return; \n}\n const migrated = migrateTemplate(rawTemplate, filePath, context);\n if (migrated !== rawTemplate) changes.push({ start, end, replacement: migrated });\n }\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return applyEdits(source, changes);\n}\n\nfunction migrateImportsAndTypes(source: string, filePath: string, context: SchematicContext): string {\n if (!source.includes(OLD_COMPONENT) && !source.includes(OLD_INTERFACE)) return source;\n\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n const edits: Edit[] = [];\n\n // Track if EuiMenuItem is already imported from @eui/core\n let hasEuiMenuItemImport = false;\n\n // First pass: analyze imports\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const moduleSpec = (stmt.moduleSpecifier as ts.StringLiteral).text;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n for (const specifier of namedBindings.elements) {\n if (specifier.name.text === NEW_INTERFACE && moduleSpec === NEW_INTERFACE_PATH) {\n hasEuiMenuItemImport = true;\n }\n }\n }\n\n // Second pass: collect edits for import declarations\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) continue;\n const namedBindings = stmt.importClause?.namedBindings;\n if (!namedBindings || !ts.isNamedImports(namedBindings)) continue;\n\n const moduleSpec = stmt.moduleSpecifier as ts.StringLiteral;\n const specifiers = namedBindings.elements;\n const hasComponent = specifiers.some((s) => s.name.text === OLD_COMPONENT);\n const hasInterface = specifiers.some((s) => s.name.text === OLD_INTERFACE);\n\n if (hasComponent && hasInterface) {\n // Both are in the same import → must split into two different paths\n const others = specifiers.filter((s) => s.name.text !== OLD_COMPONENT && s.name.text !== OLD_INTERFACE);\n const lines: string[] = [];\n lines.push(`import { ${NEW_COMPONENT} } from '${NEW_COMPONENT_PATH}';`);\n if (!hasEuiMenuItemImport) {\n lines.push(`import { ${NEW_INTERFACE} } from '${NEW_INTERFACE_PATH}';`);\n }\n if (others.length > 0) {\n const otherNames = others.map((s) => s.name.text).join(', ');\n lines.push(`import { ${otherNames} } from '${moduleSpec.text}';`);\n }\n edits.push({\n start: stmt.getStart(sourceFile),\n end: stmt.getEnd(),\n replacement: lines.join('\\n'),\n });\n } else if (hasComponent) {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_COMPONENT_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_COMPONENT) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_COMPONENT,\n });\n }\n }\n } else if (hasInterface) {\n if (hasEuiMenuItemImport) {\n removeImportSpecifier(namedBindings, specifiers.find((s) => s.name.text === OLD_INTERFACE)!, sourceFile, edits);\n } else {\n edits.push({\n start: moduleSpec.getStart(sourceFile) + 1,\n end: moduleSpec.getEnd() - 1,\n replacement: NEW_INTERFACE_PATH,\n });\n for (const specifier of specifiers) {\n if (specifier.name.text === OLD_INTERFACE) {\n edits.push({\n start: specifier.name.getStart(sourceFile),\n end: specifier.name.getEnd(),\n replacement: NEW_INTERFACE,\n });\n }\n }\n }\n }\n }\n\n // Third pass: rename identifier references in non-import positions\n const visitRefs = (node: ts.Node): void => {\n if (ts.isImportDeclaration(node)) return; // skip imports (already handled)\n if (ts.isIdentifier(node)) {\n if (node.text === OLD_COMPONENT) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_COMPONENT });\n }\n if (node.text === OLD_INTERFACE) {\n edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement: NEW_INTERFACE });\n }\n }\n ts.forEachChild(node, visitRefs);\n };\n\n for (const stmt of sourceFile.statements) {\n if (!ts.isImportDeclaration(stmt)) {\n visitRefs(stmt);\n }\n }\n\n // Warn about ToolbarItem-specific properties\n warnRemovedProperties(sourceFile, filePath, context);\n\n return applyEdits(source, edits);\n}\n\nfunction removeImportSpecifier(\n namedImports: ts.NamedImports,\n specifier: ts.ImportSpecifier,\n sourceFile: ts.SourceFile,\n edits: Edit[],\n): void {\n const elements = namedImports.elements;\n if (elements.length === 1) {\n // Remove the entire import declaration\n const importDecl = namedImports.parent.parent;\n edits.push({\n start: importDecl.getStart(sourceFile),\n end: importDecl.getEnd(),\n replacement: '',\n });\n } else {\n // Remove just this specifier with surrounding comma/whitespace\n const idx = elements.indexOf(specifier);\n let start: number;\n let end: number;\n if (idx < elements.length - 1) {\n start = specifier.getStart(sourceFile);\n end = elements[idx + 1].getStart(sourceFile);\n } else {\n start = elements[idx - 1].getEnd();\n end = specifier.getEnd();\n }\n edits.push({ start, end, replacement: '' });\n }\n}\n\nfunction warnRemovedProperties(sourceFile: ts.SourceFile, filePath: string, context: SchematicContext): void {\n const deprecated = ['isHome', 'isSeparator'];\n\n const visit = (node: ts.Node): void => {\n if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && deprecated.includes(node.name.text)) {\n const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n context.logger.warn(\n `${filePath}:${line + 1} - \"${node.name.text}\" was part of ToolbarItem but does not exist on EuiMenuItem. Review manually.`,\n );\n }\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n}\n\nfunction visitNodes(nodes: TmplAstNode[], source: string, edits: Edit[], filePath: string, context: SchematicContext): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n if (node.name === OLD_TAG) {\n collectTagRenames(node, source, edits);\n collectOutputRemovals(node, source, edits, filePath, context);\n }\n visitNodes(node.children, source, edits, filePath, context);\n }\n }\n}\n\nfunction collectTagRenames(element: TmplAstElement, source: string, edits: Edit[]): void {\n // Rename opening tag\n const openStart = element.startSourceSpan.start.offset + 1; // skip '<'\n edits.push({ start: openStart, end: openStart + OLD_TAG.length, replacement: NEW_TAG });\n\n // Rename closing tag\n if (element.endSourceSpan) {\n const closeStart = element.endSourceSpan.start.offset + 2; // skip '</'\n edits.push({ start: closeStart, end: closeStart + OLD_TAG.length, replacement: NEW_TAG });\n }\n}\n\nfunction collectOutputRemovals(\n element: TmplAstElement,\n source: string,\n edits: Edit[],\n filePath: string,\n context: SchematicContext,\n): void {\n for (const output of element.outputs) {\n if (output.name === REMOVED_OUTPUT) {\n let start = output.sourceSpan.start.offset;\n // Remove leading whitespace\n while (start > 0 && (source[start - 1] === ' ' || source[start - 1] === '\\t')) {\n start--;\n }\n edits.push({ start, end: output.sourceSpan.end.offset, replacement: '' });\n\n const { line } = element.startSourceSpan.start;\n context.logger.warn(\n `${filePath}:${line + 1} - \"(menuItemClick)\" has been removed. There is no equivalent on eui-toolbar-mega-menu.`,\n );\n }\n }\n}\n\nfunction isTemplateProperty(node: ts.PropertyAssignment): boolean {\n const name = node.name;\n return (ts.isIdentifier(name) && name.text === 'template') || (ts.isStringLiteral(name) && name.text === 'template');\n}\n\nfunction isComponentMetadataProperty(node: ts.PropertyAssignment): boolean {\n const objectLiteral = node.parent;\n if (!ts.isObjectLiteralExpression(objectLiteral)) return false;\n const callExpression = objectLiteral.parent;\n if (!ts.isCallExpression(callExpression) || callExpression.arguments[0] !== objectLiteral) return false;\n return ts.isDecorator(callExpression.parent) && ts.isIdentifier(callExpression.expression) && callExpression.expression.text === 'Component';\n}\n\nfunction unwrapExpression(expression: ts.Expression): ts.Expression {\n let current = expression;\n while (ts.isParenthesizedExpression(current)) current = current.expression;\n return current;\n}\n\nfunction applyEdits(source: string, edits: Edit[]): string {\n // Deduplicate edits at same position (e.g. module path edits when both Component and ToolbarItem are from same source)\n const unique = deduplicateEdits(edits);\n let result = source;\n for (const edit of unique.sort((a, b) => b.start - a.start)) {\n result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);\n }\n return result;\n}\n\nfunction deduplicateEdits(edits: Edit[]): Edit[] {\n const seen = new Map<string, Edit>();\n for (const edit of edits) {\n const key = `${edit.start}:${edit.end}`;\n // Last wins for same range\n seen.set(key, edit);\n }\n return Array.from(seen.values());\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
3062
2956
|
"displayName": "Schema",
|
|
3063
2957
|
"properties": [
|
|
3064
2958
|
{
|
|
@@ -3070,7 +2964,7 @@
|
|
|
3070
2964
|
"indexKey": "",
|
|
3071
2965
|
"optional": true,
|
|
3072
2966
|
"description": "",
|
|
3073
|
-
"line":
|
|
2967
|
+
"line": 18,
|
|
3074
2968
|
"rawdescription": "\n"
|
|
3075
2969
|
},
|
|
3076
2970
|
{
|
|
@@ -3082,7 +2976,7 @@
|
|
|
3082
2976
|
"indexKey": "",
|
|
3083
2977
|
"optional": true,
|
|
3084
2978
|
"description": "",
|
|
3085
|
-
"line":
|
|
2979
|
+
"line": 17,
|
|
3086
2980
|
"rawdescription": "\n"
|
|
3087
2981
|
}
|
|
3088
2982
|
],
|
|
@@ -3091,8 +2985,8 @@
|
|
|
3091
2985
|
"methods": [],
|
|
3092
2986
|
"extends": [],
|
|
3093
2987
|
"isDuplicate": true,
|
|
3094
|
-
"duplicateId":
|
|
3095
|
-
"duplicateName": "Schema-
|
|
2988
|
+
"duplicateId": 17,
|
|
2989
|
+
"duplicateName": "Schema-17",
|
|
3096
2990
|
"relationships": {
|
|
3097
2991
|
"incoming": [],
|
|
3098
2992
|
"outgoing": []
|
|
@@ -3100,7 +2994,7 @@
|
|
|
3100
2994
|
},
|
|
3101
2995
|
{
|
|
3102
2996
|
"name": "Schema",
|
|
3103
|
-
"id": "interface-Schema-d36032102ed30a7ada1e3d36bb9ca41b7234b855760cac9783a25818f7ffe2097e1ebd8e808b574ddec0760f827272f6cd561f45f3eb1578f87f39ee2633730a-
|
|
2997
|
+
"id": "interface-Schema-d36032102ed30a7ada1e3d36bb9ca41b7234b855760cac9783a25818f7ffe2097e1ebd8e808b574ddec0760f827272f6cd561f45f3eb1578f87f39ee2633730a-18",
|
|
3104
2998
|
"file": "packages/core/schematics/migrate-eui-tooltip/index.ts",
|
|
3105
2999
|
"deprecated": false,
|
|
3106
3000
|
"deprecationMessage": "",
|
|
@@ -3138,8 +3032,8 @@
|
|
|
3138
3032
|
"methods": [],
|
|
3139
3033
|
"extends": [],
|
|
3140
3034
|
"isDuplicate": true,
|
|
3141
|
-
"duplicateId":
|
|
3142
|
-
"duplicateName": "Schema-
|
|
3035
|
+
"duplicateId": 18,
|
|
3036
|
+
"duplicateName": "Schema-18",
|
|
3143
3037
|
"relationships": {
|
|
3144
3038
|
"incoming": [],
|
|
3145
3039
|
"outgoing": []
|
|
@@ -3147,7 +3041,7 @@
|
|
|
3147
3041
|
},
|
|
3148
3042
|
{
|
|
3149
3043
|
"name": "Schema",
|
|
3150
|
-
"id": "interface-Schema-cac2ac952d8245647e8a48b450e8f127a36bcffb394cf2cd81fe9c0810ed02c19e5e1629dbf29a68a5c6f675aed99570e9ac04ae470e13315e20c92cc0c6c453-
|
|
3044
|
+
"id": "interface-Schema-cac2ac952d8245647e8a48b450e8f127a36bcffb394cf2cd81fe9c0810ed02c19e5e1629dbf29a68a5c6f675aed99570e9ac04ae470e13315e20c92cc0c6c453-19",
|
|
3151
3045
|
"file": "packages/core/schematics/migrate-to-signals/index.ts",
|
|
3152
3046
|
"deprecated": false,
|
|
3153
3047
|
"deprecationMessage": "",
|
|
@@ -3185,8 +3079,8 @@
|
|
|
3185
3079
|
"methods": [],
|
|
3186
3080
|
"extends": [],
|
|
3187
3081
|
"isDuplicate": true,
|
|
3188
|
-
"duplicateId":
|
|
3189
|
-
"duplicateName": "Schema-
|
|
3082
|
+
"duplicateId": 19,
|
|
3083
|
+
"duplicateName": "Schema-19",
|
|
3190
3084
|
"relationships": {
|
|
3191
3085
|
"incoming": [],
|
|
3192
3086
|
"outgoing": []
|
|
@@ -3194,7 +3088,7 @@
|
|
|
3194
3088
|
},
|
|
3195
3089
|
{
|
|
3196
3090
|
"name": "Schema",
|
|
3197
|
-
"id": "interface-Schema-817c4b549cc3eab9fcf4936acab2e71182d90a4480369f5c003cbbda10792efa587ad99d65acf049f64e7030e32589e4fabc4a6d7a5621e4fe54725ef91dc9e8-
|
|
3091
|
+
"id": "interface-Schema-817c4b549cc3eab9fcf4936acab2e71182d90a4480369f5c003cbbda10792efa587ad99d65acf049f64e7030e32589e4fabc4a6d7a5621e4fe54725ef91dc9e8-20",
|
|
3198
3092
|
"file": "packages/core/schematics/migrate-to-standalone/index.ts",
|
|
3199
3093
|
"deprecated": false,
|
|
3200
3094
|
"deprecationMessage": "",
|
|
@@ -3232,6 +3126,112 @@
|
|
|
3232
3126
|
"methods": [],
|
|
3233
3127
|
"extends": [],
|
|
3234
3128
|
"isDuplicate": true,
|
|
3129
|
+
"duplicateId": 20,
|
|
3130
|
+
"duplicateName": "Schema-20",
|
|
3131
|
+
"relationships": {
|
|
3132
|
+
"incoming": [],
|
|
3133
|
+
"outgoing": []
|
|
3134
|
+
}
|
|
3135
|
+
},
|
|
3136
|
+
{
|
|
3137
|
+
"name": "Schema",
|
|
3138
|
+
"id": "interface-Schema-4fe31ff3e9f1d34845a6b865d605e215f33552094b88c3d0eab0b180187fe64ce4d68d687516cb3d62c57d2678a103969b2dacbb18a49b26060f78096678fcce-21",
|
|
3139
|
+
"file": "packages/core/schematics/fix-no-multiple-empty-lines/index.ts",
|
|
3140
|
+
"deprecated": false,
|
|
3141
|
+
"deprecationMessage": "",
|
|
3142
|
+
"type": "interface",
|
|
3143
|
+
"sourceCode": "import { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n}\n\nconst MULTIPLE_EMPTY_LINES = /\\n{3,}/g;\n\nexport function fixNoMultipleEmptyLines(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n let count = 0;\n\n const dir = tree.getDir(scanPath || '/');\n visitDir(dir, (filePath) => {\n const buffer = tree.read(filePath);\n if (!buffer) return;\n\n const original = buffer.toString('utf-8');\n const result = original.replace(MULTIPLE_EMPTY_LINES, '\\n\\n');\n\n if (result !== original) {\n if (filePath.endsWith('.ts')) {\n const sourceFile = ts.createSourceFile(filePath, result, ts.ScriptTarget.Latest, true);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((sourceFile as any).parseDiagnostics?.length) {\n context.logger.warn(`Skipping ${filePath}: file would not parse after transformation.`);\n return;\n }\n }\n if (options.dryRun) {\n logDryRun(context, `Would collapse multiple empty lines in ${filePath}`);\n } else {\n tree.overwrite(filePath, result);\n }\n count++;\n }\n });\n\n context.logger.info(`Fixed multiple empty lines in ${count} file(s).`);\n if (options.dryRun) {\n logDryRunNote(context);\n }\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.ts') && !file.endsWith('.html') && !file.endsWith('.scss') && !file.endsWith('.css')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n",
|
|
3144
|
+
"displayName": "Schema",
|
|
3145
|
+
"properties": [
|
|
3146
|
+
{
|
|
3147
|
+
"name": "dryRun",
|
|
3148
|
+
"coverageIgnore": false,
|
|
3149
|
+
"deprecated": false,
|
|
3150
|
+
"deprecationMessage": "",
|
|
3151
|
+
"type": "boolean",
|
|
3152
|
+
"indexKey": "",
|
|
3153
|
+
"optional": true,
|
|
3154
|
+
"description": "",
|
|
3155
|
+
"line": 7,
|
|
3156
|
+
"rawdescription": "\n"
|
|
3157
|
+
},
|
|
3158
|
+
{
|
|
3159
|
+
"name": "path",
|
|
3160
|
+
"coverageIgnore": false,
|
|
3161
|
+
"deprecated": false,
|
|
3162
|
+
"deprecationMessage": "",
|
|
3163
|
+
"type": "string",
|
|
3164
|
+
"indexKey": "",
|
|
3165
|
+
"optional": true,
|
|
3166
|
+
"description": "",
|
|
3167
|
+
"line": 6,
|
|
3168
|
+
"rawdescription": "\n"
|
|
3169
|
+
}
|
|
3170
|
+
],
|
|
3171
|
+
"indexSignatures": [],
|
|
3172
|
+
"kind": 172,
|
|
3173
|
+
"methods": [],
|
|
3174
|
+
"extends": [],
|
|
3175
|
+
"isDuplicate": true,
|
|
3176
|
+
"duplicateId": 21,
|
|
3177
|
+
"duplicateName": "Schema-21",
|
|
3178
|
+
"relationships": {
|
|
3179
|
+
"incoming": [],
|
|
3180
|
+
"outgoing": []
|
|
3181
|
+
}
|
|
3182
|
+
},
|
|
3183
|
+
{
|
|
3184
|
+
"name": "Schema",
|
|
3185
|
+
"id": "interface-Schema-9c5e016857e1416ac7bbb881973e644c0f578a53bd432bb951c1676ac3f2a6631bfe3344860346a081b841217278723e0bb0bf2fa35fb869de67cb0cc8d99849-22",
|
|
3186
|
+
"file": "packages/core/schematics/add-eui-imports/index.ts",
|
|
3187
|
+
"deprecated": false,
|
|
3188
|
+
"deprecationMessage": "",
|
|
3189
|
+
"type": "interface",
|
|
3190
|
+
"sourceCode": "import { parseTemplate, TmplAstElement, TmplAstNode, TmplAstTemplate } from '@angular/compiler';\nimport { DirEntry, Rule, SchematicContext, Tree } from '@angular-devkit/schematics';\nimport * as ts from 'typescript';\nimport { logDryRun, logDryRunNote } from '../utils/dry-run';\nimport { SELECTOR_MAP, SelectorEntry, getClassNamesForArray } from './selector-map';\n\ninterface Schema {\n path?: string;\n dryRun?: boolean;\n useClassArray?: boolean;\n}\n\ninterface ImportToAdd {\n /** The symbol to add to imports array (class name or array name for spread) */\n symbol: string;\n /** Whether this should be spread (...EUI_BUTTON) */\n isSpread: boolean;\n /** ES import path */\n importPath: string;\n}\n\nexport function addEuiImports(options: Schema = {}): Rule {\n return (tree: Tree, context: SchematicContext) => {\n const scanPath = options.path ? '/' + options.path.replace(/^\\.?\\//, '').replace(/\\/$/, '') : '';\n const useClassArray = options.useClassArray ?? false;\n let filesUpdated = 0;\n\n // Index NgModules for standalone:false support\n const ngModuleIndex = buildNgModuleIndex(tree, tree.getDir(scanPath || '/'));\n\n visitDir(tree.getDir(scanPath || '/'), (path) => {\n if (!path.endsWith('.ts') || path.endsWith('.spec.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n const source = buffer.toString('utf-8');\n\n const sourceFile = ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true);\n const components = findComponentDecorators(sourceFile);\n if (components.length === 0) return;\n\n let modified = false;\n\n for (const { decorator, className: componentClassName, isNonStandalone } of components) {\n const templateHtml = getTemplateContent(tree, path, decorator, source);\n if (!templateHtml) continue;\n\n const matched = matchSelectorsInTemplate(templateHtml);\n if (matched.length === 0) continue;\n\n const importsToAdd = resolveImports(matched, useClassArray);\n if (importsToAdd.length === 0) continue;\n\n if (isNonStandalone) {\n // Find the NgModule that declares this component and add imports there\n const moduleInfo = findDeclaringModule(ngModuleIndex, componentClassName);\n if (!moduleInfo) {\n context.logger.warn(`⚠ Could not find declaring NgModule for ${componentClassName} in ${path}`);\n continue;\n }\n const moduleBuffer = tree.read(moduleInfo.path);\n if (!moduleBuffer) continue;\n const moduleSource = moduleBuffer.toString('utf-8');\n const result = addImportsToFile(moduleSource, moduleInfo.path, moduleInfo.decoratorPos, importsToAdd, useClassArray);\n if (result !== moduleSource) {\n if (options.dryRun) {\n logDryRun(context, `Would add EUI imports to NgModule in ${moduleInfo.path} for component ${componentClassName}`);\n } else {\n tree.overwrite(moduleInfo.path, result);\n }\n modified = true;\n }\n } else {\n // Standalone component — add imports directly\n const currentSource = tree.read(path)!.toString('utf-8');\n const result = addImportsToFile(currentSource, path, decorator.getStart(), importsToAdd, useClassArray);\n if (result !== currentSource) {\n if (options.dryRun) {\n logDryRun(context, `Would add EUI imports to ${path}`);\n } else {\n tree.overwrite(path, result);\n }\n modified = true;\n }\n }\n }\n\n if (modified) filesUpdated++;\n });\n\n context.logger.info(`add-eui-imports: ${filesUpdated} file(s) updated.`);\n if (options.dryRun) logDryRunNote(context);\n return tree;\n };\n}\n\nfunction visitDir(dir: DirEntry, callback: (path: string) => void): void {\n for (const file of dir.subfiles) {\n if (file.endsWith('.d.ts')) continue;\n if (!file.endsWith('.html') && !file.endsWith('.ts')) continue;\n callback(`${dir.path}/${file}`);\n }\n for (const sub of dir.subdirs) {\n if (sub === 'node_modules' || sub === 'dist') continue;\n visitDir(dir.dir(sub), callback);\n }\n}\n\n// --- Selector Matching ---\n\nfunction matchSelectorsInTemplate(html: string): SelectorEntry[] {\n const parsed = parseTemplate(html, '', { preserveWhitespaces: true });\n if (parsed.errors?.length) return [];\n\n const matched: SelectorEntry[] = [];\n visitTemplateNodes(parsed.nodes, matched);\n return matched;\n}\n\nfunction visitTemplateNodes(nodes: TmplAstNode[], matched: SelectorEntry[]): void {\n for (const node of nodes) {\n if (node instanceof TmplAstElement) {\n matchElement(node, matched);\n visitTemplateNodes(node.children, matched);\n } else if (node instanceof TmplAstTemplate) {\n visitTemplateNodes(node.children, matched);\n }\n }\n}\n\nfunction matchElement(element: TmplAstElement, matched: SelectorEntry[]): void {\n const tagName = element.name;\n const attrNames = new Set([\n ...element.attributes.map(a => a.name),\n ...element.inputs.map(i => i.name),\n ]);\n\n for (const entry of SELECTOR_MAP) {\n if (entry.element && entry.element !== tagName) continue;\n if (!entry.element && entry.attributes.length === 0) continue;\n if (!entry.attributes.every(attr => attrNames.has(attr))) continue;\n // If no element specified, at least one attribute must match on this element\n if (!entry.element && entry.attributes.length > 0 && !entry.attributes.some(attr => attrNames.has(attr))) continue;\n matched.push(entry);\n }\n}\n\n// --- Import Resolution ---\n\nfunction resolveImports(matched: SelectorEntry[], useClassArray: boolean): ImportToAdd[] {\n const seen = new Set<string>();\n const result: ImportToAdd[] = [];\n\n for (const entry of matched) {\n if (useClassArray && entry.classArray) {\n if (seen.has(entry.classArray)) continue;\n seen.add(entry.classArray);\n result.push({ symbol: entry.classArray, isSpread: true, importPath: entry.importPath });\n } else {\n if (seen.has(entry.className)) continue;\n seen.add(entry.className);\n result.push({ symbol: entry.className, isSpread: false, importPath: entry.importPath });\n }\n }\n\n return result;\n}\n\n// --- Template Extraction ---\n\nfunction getTemplateContent(tree: Tree, tsPath: string, decorator: ts.Decorator, source: string): string | null {\n const call = decorator.expression as ts.CallExpression;\n if (!call.arguments[0] || !ts.isObjectLiteralExpression(call.arguments[0])) return null;\n const metadata = call.arguments[0];\n\n for (const prop of metadata.properties) {\n if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) continue;\n if (prop.name.text === 'template') {\n const init = prop.initializer;\n if (ts.isStringLiteral(init) || ts.isNoSubstitutionTemplateLiteral(init)) {\n return init.text;\n }\n }\n if (prop.name.text === 'templateUrl') {\n if (ts.isStringLiteral(prop.initializer)) {\n const dir = tsPath.substring(0, tsPath.lastIndexOf('/'));\n const templateBuffer = tree.read(`${dir}/${prop.initializer.text}`);\n if (templateBuffer) return templateBuffer.toString('utf-8');\n }\n }\n }\n return null;\n}\n\n// --- Component Decorator Detection ---\n\ninterface ComponentInfo {\n decorator: ts.Decorator;\n className: string;\n isNonStandalone: boolean;\n}\n\nfunction findComponentDecorators(sourceFile: ts.SourceFile): ComponentInfo[] {\n const results: ComponentInfo[] = [];\n const visit = (node: ts.Node): void => {\n if (ts.isClassDeclaration(node) && node.name) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const dec of decs) {\n if (ts.isCallExpression(dec.expression) && ts.isIdentifier(dec.expression.expression) && dec.expression.expression.text === 'Component') {\n const isNonStandalone = hasStandaloneFalse(dec);\n results.push({ decorator: dec, className: node.name.text, isNonStandalone });\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sourceFile);\n return results;\n}\n\nfunction hasStandaloneFalse(decorator: ts.Decorator): boolean {\n const call = decorator.expression as ts.CallExpression;\n if (!call.arguments[0] || !ts.isObjectLiteralExpression(call.arguments[0])) return false;\n for (const prop of call.arguments[0].properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === 'standalone') {\n return prop.initializer.kind === ts.SyntaxKind.FalseKeyword;\n }\n }\n return false;\n}\n\n// --- NgModule Index ---\n\ninterface NgModuleInfo {\n path: string;\n declarations: string[];\n decoratorPos: number;\n}\n\nfunction buildNgModuleIndex(tree: Tree, dir: DirEntry): NgModuleInfo[] {\n const modules: NgModuleInfo[] = [];\n\n visitDir(dir, (path) => {\n if (!path.endsWith('.ts') || path.endsWith('.spec.ts')) return;\n\n const buffer = tree.read(path);\n if (!buffer) return;\n const source = buffer.toString('utf-8');\n if (!source.includes('NgModule')) return;\n\n const sf = ts.createSourceFile(path, source, ts.ScriptTarget.Latest, true);\n const visit = (node: ts.Node): void => {\n if (ts.isClassDeclaration(node)) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const dec of decs) {\n if (ts.isCallExpression(dec.expression) && ts.isIdentifier(dec.expression.expression) && dec.expression.expression.text === 'NgModule') {\n const declarations = extractArrayProperty(dec, 'declarations', source);\n modules.push({ path, declarations, decoratorPos: dec.getStart() });\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n });\n\n return modules;\n}\n\nfunction extractArrayProperty(decorator: ts.Decorator, propName: string, source: string): string[] {\n const call = decorator.expression as ts.CallExpression;\n if (!call.arguments[0] || !ts.isObjectLiteralExpression(call.arguments[0])) return [];\n for (const prop of call.arguments[0].properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === propName) {\n if (ts.isArrayLiteralExpression(prop.initializer)) {\n return prop.initializer.elements\n .filter(ts.isIdentifier)\n .map(id => id.text);\n }\n }\n }\n return [];\n}\n\nfunction findDeclaringModule(modules: NgModuleInfo[], componentClassName: string): NgModuleInfo | undefined {\n return modules.find(m => m.declarations.includes(componentClassName));\n}\n\n// --- Import Addition ---\n\nfunction addImportsToFile(source: string, filePath: string, decoratorStartHint: number, imports: ImportToAdd[], useClassArray: boolean): string {\n const sf = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n // Find the imports array in the decorator closest to decoratorStartHint\n const importsArrayInfo = findDecoratorImportsArray(sf, source, decoratorStartHint);\n if (!importsArrayInfo) return source;\n\n const { arrayNode, decoratorType } = importsArrayInfo;\n\n // Determine what's already in the imports array\n const existingSymbols = new Set<string>();\n const existingSpreads = new Set<string>();\n for (const el of arrayNode.elements) {\n if (ts.isSpreadElement(el) && ts.isIdentifier(el.expression)) {\n existingSpreads.add(el.expression.text);\n } else if (ts.isIdentifier(el)) {\n existingSymbols.add(el.text);\n }\n }\n\n // Filter out already-present imports and compute what to add/remove\n const toAdd: ImportToAdd[] = [];\n const toRemoveFromArray: string[] = []; // individual class names to consolidate\n\n for (const imp of imports) {\n if (imp.isSpread) {\n if (existingSpreads.has(imp.symbol)) continue; // Already has ...EUI_X\n toAdd.push(imp);\n // Consolidate: remove individual class names covered by this array\n if (useClassArray) {\n const coveredClasses = getClassNamesForArray(imp.symbol);\n for (const cls of coveredClasses) {\n if (existingSymbols.has(cls)) toRemoveFromArray.push(cls);\n }\n }\n } else {\n if (existingSymbols.has(imp.symbol)) continue;\n // Also skip if a spread already covers this class\n const coveringArray = imports.find(i => i.isSpread && getClassNamesForArray(i.symbol).includes(imp.symbol));\n if (coveringArray && (existingSpreads.has(coveringArray.symbol) || toAdd.some(a => a.symbol === coveringArray.symbol))) continue;\n toAdd.push(imp);\n }\n }\n\n if (toAdd.length === 0 && toRemoveFromArray.length === 0) return source;\n\n // Build new array content\n let result = source;\n result = updateDecoratorImportsArray(result, filePath, arrayNode, toAdd, toRemoveFromArray);\n\n // Add ES imports\n result = addEsImports(result, filePath, toAdd);\n\n // Remove consolidated class names from ES imports\n if (toRemoveFromArray.length > 0) {\n result = removeFromEsImports(result, filePath, toRemoveFromArray);\n }\n\n return result;\n}\n\ninterface ImportsArrayInfo {\n arrayNode: ts.ArrayLiteralExpression;\n decoratorType: 'Component' | 'NgModule';\n}\n\nfunction findDecoratorImportsArray(sf: ts.SourceFile, source: string, decoratorStartHint: number): ImportsArrayInfo | null {\n let found: ImportsArrayInfo | null = null;\n\n const visit = (node: ts.Node): void => {\n if (found) return;\n if (ts.isClassDeclaration(node)) {\n const decs = ts.getDecorators(node);\n if (!decs) return;\n for (const dec of decs) {\n if (!ts.isCallExpression(dec.expression)) continue;\n if (!ts.isIdentifier(dec.expression.expression)) continue;\n const decName = dec.expression.expression.text;\n if (decName !== 'Component' && decName !== 'NgModule') continue;\n if (Math.abs(dec.getStart() - decoratorStartHint) > 5) continue; // Match by position\n\n const metadata = dec.expression.arguments[0];\n if (!ts.isObjectLiteralExpression(metadata)) continue;\n\n for (const prop of metadata.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text === 'imports') {\n if (ts.isArrayLiteralExpression(prop.initializer)) {\n found = { arrayNode: prop.initializer, decoratorType: decName as 'Component' | 'NgModule' };\n return;\n }\n }\n }\n\n // No imports array found — create one\n if (!found && decName === 'Component') {\n // We need to add `imports: []` to the decorator\n // Insert after the last property\n const lastProp = metadata.properties[metadata.properties.length - 1];\n if (lastProp) {\n const insertPos = lastProp.getEnd();\n const indent = detectIndent(source, metadata.getStart());\n const insertion = `,\\n${indent} imports: []`;\n const newSource = source.slice(0, insertPos) + insertion + source.slice(insertPos);\n // Re-parse to get the array node\n const newSf = ts.createSourceFile('', newSource, ts.ScriptTarget.Latest, true);\n const newArray = findImportsArrayInSource(newSf);\n if (newArray) {\n // We can't return a node from a different source file in the general case.\n // Instead, we'll handle the \"no imports array\" case by adding it inline.\n found = null; // Will be handled separately\n }\n }\n }\n }\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\nfunction findImportsArrayInSource(sf: ts.SourceFile): ts.ArrayLiteralExpression | null {\n let found: ts.ArrayLiteralExpression | null = null;\n const visit = (node: ts.Node): void => {\n if (found) return;\n if (ts.isPropertyAssignment(node) && ts.isIdentifier(node.name) && node.name.text === 'imports' && ts.isArrayLiteralExpression(node.initializer)) {\n found = node.initializer;\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n return found;\n}\n\nfunction updateDecoratorImportsArray(source: string, filePath: string, arrayNode: ts.ArrayLiteralExpression, toAdd: ImportToAdd[], toRemove: string[]): string {\n const sf = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n\n // Rebuild the array content\n const existingElements: string[] = [];\n for (const el of arrayNode.elements) {\n const text = source.slice(el.getStart(sf), el.getEnd()).trim();\n // Check if this element should be removed (consolidation)\n if (ts.isIdentifier(el) && toRemove.includes(el.text)) continue;\n existingElements.push(text);\n }\n\n // Add new entries\n for (const imp of toAdd) {\n const entry = imp.isSpread ? `...${imp.symbol}` : imp.symbol;\n if (!existingElements.includes(entry)) {\n existingElements.push(entry);\n }\n }\n\n // Determine formatting\n const arrayStart = arrayNode.getStart(sf);\n const arrayEnd = arrayNode.getEnd();\n const originalText = source.slice(arrayStart, arrayEnd);\n const isMultiline = originalText.includes('\\n');\n\n let newArrayText: string;\n if (isMultiline || existingElements.length > 3) {\n const indent = detectIndent(source, arrayStart);\n const itemIndent = indent + ' ';\n newArrayText = `[\\n${existingElements.map(e => `${itemIndent}${e},`).join('\\n')}\\n${indent}]`;\n } else {\n newArrayText = `[${existingElements.join(', ')}]`;\n }\n\n return source.slice(0, arrayStart) + newArrayText + source.slice(arrayEnd);\n}\n\nfunction addEsImports(source: string, filePath: string, imports: ImportToAdd[]): string {\n let result = source;\n\n // Group by import path\n const byPath = new Map<string, string[]>();\n for (const imp of imports) {\n const existing = byPath.get(imp.importPath) || [];\n existing.push(imp.symbol);\n byPath.set(imp.importPath, existing);\n }\n\n for (const [importPath, symbols] of byPath) {\n const sf = ts.createSourceFile(filePath, result, ts.ScriptTarget.Latest, true);\n\n // Check if there's already an import from this path\n const existingImport = sf.statements.find(\n (s): s is ts.ImportDeclaration =>\n ts.isImportDeclaration(s) && ts.isStringLiteral(s.moduleSpecifier) && s.moduleSpecifier.text === importPath,\n );\n\n if (existingImport?.importClause?.namedBindings && ts.isNamedImports(existingImport.importClause.namedBindings)) {\n // Extend existing import\n const namedBindings = existingImport.importClause.namedBindings;\n const existingNames = namedBindings.elements.map(el => el.name.text);\n const newNames = symbols.filter(s => !existingNames.includes(s));\n if (newNames.length === 0) continue;\n\n const allNames = [...existingNames, ...newNames].sort();\n const newClause = `{ ${allNames.join(', ')} }`;\n result = result.slice(0, namedBindings.getStart(sf)) + newClause + result.slice(namedBindings.getEnd());\n } else {\n // Add new import statement\n const sortedSymbols = [...symbols].sort();\n const newImport = `import { ${sortedSymbols.join(', ')} } from '${importPath}';\\n`;\n\n // Insert after the last existing import\n const lastImport = [...sf.statements].reverse().find(ts.isImportDeclaration);\n if (lastImport) {\n const pos = lastImport.getEnd();\n result = result.slice(0, pos) + '\\n' + newImport.trimEnd() + result.slice(pos);\n } else {\n result = newImport + result;\n }\n }\n }\n\n return result;\n}\n\nfunction detectIndent(source: string, pos: number): string {\n const lineStart = source.lastIndexOf('\\n', pos - 1) + 1;\n const match = source.slice(lineStart, pos).match(/^(\\s*)/);\n return match ? match[1] : '';\n}\n\nfunction removeFromEsImports(source: string, filePath: string, symbolsToRemove: string[]): string {\n let result = source;\n const sf = ts.createSourceFile(filePath, result, ts.ScriptTarget.Latest, true);\n\n for (const stmt of sf.statements) {\n if (!ts.isImportDeclaration(stmt) || !stmt.importClause?.namedBindings || !ts.isNamedImports(stmt.importClause.namedBindings)) continue;\n const namedBindings = stmt.importClause.namedBindings;\n const existingNames = namedBindings.elements.map(el => el.name.text);\n const remaining = existingNames.filter(n => !symbolsToRemove.includes(n));\n\n if (remaining.length === existingNames.length) continue; // Nothing to remove from this import\n\n if (remaining.length === 0) {\n // Remove the entire import statement\n result = result.slice(0, stmt.getStart(sf)) + result.slice(stmt.getEnd()).replace(/^\\r?\\n/, '');\n } else {\n const newClause = `{ ${remaining.join(', ')} }`;\n result = result.slice(0, namedBindings.getStart(sf)) + newClause + result.slice(namedBindings.getEnd());\n }\n break; // Only process the first matching import for the consolidated symbols\n }\n\n return result;\n}\n",
|
|
3191
|
+
"displayName": "Schema",
|
|
3192
|
+
"properties": [
|
|
3193
|
+
{
|
|
3194
|
+
"name": "dryRun",
|
|
3195
|
+
"coverageIgnore": false,
|
|
3196
|
+
"deprecated": false,
|
|
3197
|
+
"deprecationMessage": "",
|
|
3198
|
+
"type": "boolean",
|
|
3199
|
+
"indexKey": "",
|
|
3200
|
+
"optional": true,
|
|
3201
|
+
"description": "",
|
|
3202
|
+
"line": 9,
|
|
3203
|
+
"rawdescription": "\n"
|
|
3204
|
+
},
|
|
3205
|
+
{
|
|
3206
|
+
"name": "path",
|
|
3207
|
+
"coverageIgnore": false,
|
|
3208
|
+
"deprecated": false,
|
|
3209
|
+
"deprecationMessage": "",
|
|
3210
|
+
"type": "string",
|
|
3211
|
+
"indexKey": "",
|
|
3212
|
+
"optional": true,
|
|
3213
|
+
"description": "",
|
|
3214
|
+
"line": 8,
|
|
3215
|
+
"rawdescription": "\n"
|
|
3216
|
+
},
|
|
3217
|
+
{
|
|
3218
|
+
"name": "useClassArray",
|
|
3219
|
+
"coverageIgnore": false,
|
|
3220
|
+
"deprecated": false,
|
|
3221
|
+
"deprecationMessage": "",
|
|
3222
|
+
"type": "boolean",
|
|
3223
|
+
"indexKey": "",
|
|
3224
|
+
"optional": true,
|
|
3225
|
+
"description": "",
|
|
3226
|
+
"line": 10,
|
|
3227
|
+
"rawdescription": "\n"
|
|
3228
|
+
}
|
|
3229
|
+
],
|
|
3230
|
+
"indexSignatures": [],
|
|
3231
|
+
"kind": 172,
|
|
3232
|
+
"methods": [],
|
|
3233
|
+
"extends": [],
|
|
3234
|
+
"isDuplicate": true,
|
|
3235
3235
|
"duplicateId": 22,
|
|
3236
3236
|
"duplicateName": "Schema-22",
|
|
3237
3237
|
"relationships": {
|
|
@@ -22310,23 +22310,23 @@
|
|
|
22310
22310
|
"name": "COMPONENT_TAG",
|
|
22311
22311
|
"ctype": "miscellaneous",
|
|
22312
22312
|
"subtype": "variable",
|
|
22313
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
22313
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
22314
22314
|
"coverageIgnore": false,
|
|
22315
22315
|
"deprecated": false,
|
|
22316
22316
|
"deprecationMessage": "",
|
|
22317
22317
|
"type": "string",
|
|
22318
|
-
"defaultValue": "'eui-
|
|
22318
|
+
"defaultValue": "'eui-fieldset'"
|
|
22319
22319
|
},
|
|
22320
22320
|
{
|
|
22321
22321
|
"name": "COMPONENT_TAG",
|
|
22322
22322
|
"ctype": "miscellaneous",
|
|
22323
22323
|
"subtype": "variable",
|
|
22324
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
22324
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
22325
22325
|
"coverageIgnore": false,
|
|
22326
22326
|
"deprecated": false,
|
|
22327
22327
|
"deprecationMessage": "",
|
|
22328
22328
|
"type": "string",
|
|
22329
|
-
"defaultValue": "'eui-
|
|
22329
|
+
"defaultValue": "'eui-icon-svg'"
|
|
22330
22330
|
},
|
|
22331
22331
|
{
|
|
22332
22332
|
"name": "COMPONENT_TAG",
|
|
@@ -23589,23 +23589,23 @@
|
|
|
23589
23589
|
"name": "REMOVED_INPUTS",
|
|
23590
23590
|
"ctype": "miscellaneous",
|
|
23591
23591
|
"subtype": "variable",
|
|
23592
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
23592
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
23593
23593
|
"coverageIgnore": false,
|
|
23594
23594
|
"deprecated": false,
|
|
23595
23595
|
"deprecationMessage": "",
|
|
23596
23596
|
"type": "unknown",
|
|
23597
|
-
"defaultValue": "new Set(['
|
|
23597
|
+
"defaultValue": "new Set(['isSquared'])"
|
|
23598
23598
|
},
|
|
23599
23599
|
{
|
|
23600
23600
|
"name": "REMOVED_INPUTS",
|
|
23601
23601
|
"ctype": "miscellaneous",
|
|
23602
23602
|
"subtype": "variable",
|
|
23603
|
-
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
23603
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
23604
23604
|
"coverageIgnore": false,
|
|
23605
23605
|
"deprecated": false,
|
|
23606
23606
|
"deprecationMessage": "",
|
|
23607
23607
|
"type": "unknown",
|
|
23608
|
-
"defaultValue": "new Set(['
|
|
23608
|
+
"defaultValue": "new Set(['maxVisibleChipsCount', 'isMaxVisibleChipsOpened', 'toggleLinkMoreLabel', 'toggleLinkLessLabel', 'isChipsSorted', 'chipsSortOrder'])"
|
|
23609
23609
|
},
|
|
23610
23610
|
{
|
|
23611
23611
|
"name": "REMOVED_INPUTS",
|
|
@@ -24559,7 +24559,7 @@
|
|
|
24559
24559
|
},
|
|
24560
24560
|
{
|
|
24561
24561
|
"name": "applyEdits",
|
|
24562
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24562
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
24563
24563
|
"ctype": "miscellaneous",
|
|
24564
24564
|
"subtype": "function",
|
|
24565
24565
|
"coverageIgnore": false,
|
|
@@ -24604,7 +24604,7 @@
|
|
|
24604
24604
|
},
|
|
24605
24605
|
{
|
|
24606
24606
|
"name": "applyEdits",
|
|
24607
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24607
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
24608
24608
|
"ctype": "miscellaneous",
|
|
24609
24609
|
"subtype": "function",
|
|
24610
24610
|
"coverageIgnore": false,
|
|
@@ -24739,7 +24739,7 @@
|
|
|
24739
24739
|
},
|
|
24740
24740
|
{
|
|
24741
24741
|
"name": "applyEdits",
|
|
24742
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24742
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
24743
24743
|
"ctype": "miscellaneous",
|
|
24744
24744
|
"subtype": "function",
|
|
24745
24745
|
"coverageIgnore": false,
|
|
@@ -24784,7 +24784,7 @@
|
|
|
24784
24784
|
},
|
|
24785
24785
|
{
|
|
24786
24786
|
"name": "applyEdits",
|
|
24787
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24787
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
24788
24788
|
"ctype": "miscellaneous",
|
|
24789
24789
|
"subtype": "function",
|
|
24790
24790
|
"coverageIgnore": false,
|
|
@@ -26036,7 +26036,7 @@
|
|
|
26036
26036
|
},
|
|
26037
26037
|
{
|
|
26038
26038
|
"name": "collectRemovals",
|
|
26039
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26039
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
26040
26040
|
"ctype": "miscellaneous",
|
|
26041
26041
|
"subtype": "function",
|
|
26042
26042
|
"coverageIgnore": false,
|
|
@@ -26052,12 +26052,6 @@
|
|
|
26052
26052
|
"deprecated": false,
|
|
26053
26053
|
"deprecationMessage": ""
|
|
26054
26054
|
},
|
|
26055
|
-
{
|
|
26056
|
-
"name": "source",
|
|
26057
|
-
"type": "string",
|
|
26058
|
-
"deprecated": false,
|
|
26059
|
-
"deprecationMessage": ""
|
|
26060
|
-
},
|
|
26061
26055
|
{
|
|
26062
26056
|
"name": "removals",
|
|
26063
26057
|
"deprecated": false,
|
|
@@ -26075,15 +26069,6 @@
|
|
|
26075
26069
|
"text": "param"
|
|
26076
26070
|
}
|
|
26077
26071
|
},
|
|
26078
|
-
{
|
|
26079
|
-
"name": "source",
|
|
26080
|
-
"type": "string",
|
|
26081
|
-
"deprecated": false,
|
|
26082
|
-
"deprecationMessage": "",
|
|
26083
|
-
"tagName": {
|
|
26084
|
-
"text": "param"
|
|
26085
|
-
}
|
|
26086
|
-
},
|
|
26087
26072
|
{
|
|
26088
26073
|
"name": "removals",
|
|
26089
26074
|
"deprecated": false,
|
|
@@ -26096,7 +26081,7 @@
|
|
|
26096
26081
|
},
|
|
26097
26082
|
{
|
|
26098
26083
|
"name": "collectRemovals",
|
|
26099
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26084
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
26100
26085
|
"ctype": "miscellaneous",
|
|
26101
26086
|
"subtype": "function",
|
|
26102
26087
|
"coverageIgnore": false,
|
|
@@ -26112,6 +26097,12 @@
|
|
|
26112
26097
|
"deprecated": false,
|
|
26113
26098
|
"deprecationMessage": ""
|
|
26114
26099
|
},
|
|
26100
|
+
{
|
|
26101
|
+
"name": "source",
|
|
26102
|
+
"type": "string",
|
|
26103
|
+
"deprecated": false,
|
|
26104
|
+
"deprecationMessage": ""
|
|
26105
|
+
},
|
|
26115
26106
|
{
|
|
26116
26107
|
"name": "removals",
|
|
26117
26108
|
"deprecated": false,
|
|
@@ -26129,6 +26120,15 @@
|
|
|
26129
26120
|
"text": "param"
|
|
26130
26121
|
}
|
|
26131
26122
|
},
|
|
26123
|
+
{
|
|
26124
|
+
"name": "source",
|
|
26125
|
+
"type": "string",
|
|
26126
|
+
"deprecated": false,
|
|
26127
|
+
"deprecationMessage": "",
|
|
26128
|
+
"tagName": {
|
|
26129
|
+
"text": "param"
|
|
26130
|
+
}
|
|
26131
|
+
},
|
|
26132
26132
|
{
|
|
26133
26133
|
"name": "removals",
|
|
26134
26134
|
"deprecated": false,
|
|
@@ -26321,7 +26321,7 @@
|
|
|
26321
26321
|
},
|
|
26322
26322
|
{
|
|
26323
26323
|
"name": "collectRenames",
|
|
26324
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26324
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
26325
26325
|
"ctype": "miscellaneous",
|
|
26326
26326
|
"subtype": "function",
|
|
26327
26327
|
"coverageIgnore": false,
|
|
@@ -26366,7 +26366,7 @@
|
|
|
26366
26366
|
},
|
|
26367
26367
|
{
|
|
26368
26368
|
"name": "collectRenames",
|
|
26369
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26369
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
26370
26370
|
"ctype": "miscellaneous",
|
|
26371
26371
|
"subtype": "function",
|
|
26372
26372
|
"coverageIgnore": false,
|
|
@@ -27688,7 +27688,7 @@
|
|
|
27688
27688
|
},
|
|
27689
27689
|
{
|
|
27690
27690
|
"name": "findComponentDecorators",
|
|
27691
|
-
"file": "packages/core/schematics/
|
|
27691
|
+
"file": "packages/core/schematics/migrate-to-standalone/index.ts",
|
|
27692
27692
|
"ctype": "miscellaneous",
|
|
27693
27693
|
"subtype": "function",
|
|
27694
27694
|
"coverageIgnore": false,
|
|
@@ -27704,7 +27704,7 @@
|
|
|
27704
27704
|
"deprecationMessage": ""
|
|
27705
27705
|
}
|
|
27706
27706
|
],
|
|
27707
|
-
"returnType": "
|
|
27707
|
+
"returnType": "ts.Decorator[]",
|
|
27708
27708
|
"jsdoctags": [
|
|
27709
27709
|
{
|
|
27710
27710
|
"name": "sourceFile",
|
|
@@ -27718,7 +27718,7 @@
|
|
|
27718
27718
|
},
|
|
27719
27719
|
{
|
|
27720
27720
|
"name": "findComponentDecorators",
|
|
27721
|
-
"file": "packages/core/schematics/
|
|
27721
|
+
"file": "packages/core/schematics/add-eui-imports/index.ts",
|
|
27722
27722
|
"ctype": "miscellaneous",
|
|
27723
27723
|
"subtype": "function",
|
|
27724
27724
|
"coverageIgnore": false,
|
|
@@ -27734,7 +27734,7 @@
|
|
|
27734
27734
|
"deprecationMessage": ""
|
|
27735
27735
|
}
|
|
27736
27736
|
],
|
|
27737
|
-
"returnType": "
|
|
27737
|
+
"returnType": "ComponentInfo[]",
|
|
27738
27738
|
"jsdoctags": [
|
|
27739
27739
|
{
|
|
27740
27740
|
"name": "sourceFile",
|
|
@@ -29750,7 +29750,7 @@
|
|
|
29750
29750
|
},
|
|
29751
29751
|
{
|
|
29752
29752
|
"name": "isChipElement",
|
|
29753
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
29753
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
29754
29754
|
"ctype": "miscellaneous",
|
|
29755
29755
|
"subtype": "function",
|
|
29756
29756
|
"coverageIgnore": false,
|
|
@@ -29782,7 +29782,7 @@
|
|
|
29782
29782
|
},
|
|
29783
29783
|
{
|
|
29784
29784
|
"name": "isChipElement",
|
|
29785
|
-
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
29785
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
29786
29786
|
"ctype": "miscellaneous",
|
|
29787
29787
|
"subtype": "function",
|
|
29788
29788
|
"coverageIgnore": false,
|
|
@@ -29966,7 +29966,7 @@
|
|
|
29966
29966
|
},
|
|
29967
29967
|
{
|
|
29968
29968
|
"name": "isComponentMetadataProperty",
|
|
29969
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
29969
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
29970
29970
|
"ctype": "miscellaneous",
|
|
29971
29971
|
"subtype": "function",
|
|
29972
29972
|
"coverageIgnore": false,
|
|
@@ -29996,7 +29996,7 @@
|
|
|
29996
29996
|
},
|
|
29997
29997
|
{
|
|
29998
29998
|
"name": "isComponentMetadataProperty",
|
|
29999
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
29999
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
30000
30000
|
"ctype": "miscellaneous",
|
|
30001
30001
|
"subtype": "function",
|
|
30002
30002
|
"coverageIgnore": false,
|
|
@@ -30056,7 +30056,7 @@
|
|
|
30056
30056
|
},
|
|
30057
30057
|
{
|
|
30058
30058
|
"name": "isComponentMetadataProperty",
|
|
30059
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30059
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
30060
30060
|
"ctype": "miscellaneous",
|
|
30061
30061
|
"subtype": "function",
|
|
30062
30062
|
"coverageIgnore": false,
|
|
@@ -30086,7 +30086,7 @@
|
|
|
30086
30086
|
},
|
|
30087
30087
|
{
|
|
30088
30088
|
"name": "isComponentMetadataProperty",
|
|
30089
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30089
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
30090
30090
|
"ctype": "miscellaneous",
|
|
30091
30091
|
"subtype": "function",
|
|
30092
30092
|
"coverageIgnore": false,
|
|
@@ -30116,7 +30116,7 @@
|
|
|
30116
30116
|
},
|
|
30117
30117
|
{
|
|
30118
30118
|
"name": "isComponentMetadataProperty",
|
|
30119
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30119
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
30120
30120
|
"ctype": "miscellaneous",
|
|
30121
30121
|
"subtype": "function",
|
|
30122
30122
|
"coverageIgnore": false,
|
|
@@ -30146,7 +30146,7 @@
|
|
|
30146
30146
|
},
|
|
30147
30147
|
{
|
|
30148
30148
|
"name": "isComponentMetadataProperty",
|
|
30149
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30149
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
30150
30150
|
"ctype": "miscellaneous",
|
|
30151
30151
|
"subtype": "function",
|
|
30152
30152
|
"coverageIgnore": false,
|
|
@@ -30509,36 +30509,6 @@
|
|
|
30509
30509
|
}
|
|
30510
30510
|
]
|
|
30511
30511
|
},
|
|
30512
|
-
{
|
|
30513
|
-
"name": "isTemplateProperty",
|
|
30514
|
-
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
30515
|
-
"ctype": "miscellaneous",
|
|
30516
|
-
"subtype": "function",
|
|
30517
|
-
"coverageIgnore": false,
|
|
30518
|
-
"deprecated": false,
|
|
30519
|
-
"deprecationMessage": "",
|
|
30520
|
-
"rawdescription": "",
|
|
30521
|
-
"description": "",
|
|
30522
|
-
"displayName": "isTemplateProperty",
|
|
30523
|
-
"args": [
|
|
30524
|
-
{
|
|
30525
|
-
"name": "node",
|
|
30526
|
-
"deprecated": false,
|
|
30527
|
-
"deprecationMessage": ""
|
|
30528
|
-
}
|
|
30529
|
-
],
|
|
30530
|
-
"returnType": "boolean",
|
|
30531
|
-
"jsdoctags": [
|
|
30532
|
-
{
|
|
30533
|
-
"name": "node",
|
|
30534
|
-
"deprecated": false,
|
|
30535
|
-
"deprecationMessage": "",
|
|
30536
|
-
"tagName": {
|
|
30537
|
-
"text": "param"
|
|
30538
|
-
}
|
|
30539
|
-
}
|
|
30540
|
-
]
|
|
30541
|
-
},
|
|
30542
30512
|
{
|
|
30543
30513
|
"name": "isTemplateProperty",
|
|
30544
30514
|
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
@@ -30571,7 +30541,7 @@
|
|
|
30571
30541
|
},
|
|
30572
30542
|
{
|
|
30573
30543
|
"name": "isTemplateProperty",
|
|
30574
|
-
"file": "packages/core/schematics/migrate-eui-icon-
|
|
30544
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
30575
30545
|
"ctype": "miscellaneous",
|
|
30576
30546
|
"subtype": "function",
|
|
30577
30547
|
"coverageIgnore": false,
|
|
@@ -30601,7 +30571,7 @@
|
|
|
30601
30571
|
},
|
|
30602
30572
|
{
|
|
30603
30573
|
"name": "isTemplateProperty",
|
|
30604
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30574
|
+
"file": "packages/core/schematics/migrate-eui-icon-toggle/index.ts",
|
|
30605
30575
|
"ctype": "miscellaneous",
|
|
30606
30576
|
"subtype": "function",
|
|
30607
30577
|
"coverageIgnore": false,
|
|
@@ -30659,36 +30629,6 @@
|
|
|
30659
30629
|
}
|
|
30660
30630
|
]
|
|
30661
30631
|
},
|
|
30662
|
-
{
|
|
30663
|
-
"name": "isTemplateProperty",
|
|
30664
|
-
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
30665
|
-
"ctype": "miscellaneous",
|
|
30666
|
-
"subtype": "function",
|
|
30667
|
-
"coverageIgnore": false,
|
|
30668
|
-
"deprecated": false,
|
|
30669
|
-
"deprecationMessage": "",
|
|
30670
|
-
"rawdescription": "",
|
|
30671
|
-
"description": "",
|
|
30672
|
-
"displayName": "isTemplateProperty",
|
|
30673
|
-
"args": [
|
|
30674
|
-
{
|
|
30675
|
-
"name": "node",
|
|
30676
|
-
"deprecated": false,
|
|
30677
|
-
"deprecationMessage": ""
|
|
30678
|
-
}
|
|
30679
|
-
],
|
|
30680
|
-
"returnType": "boolean",
|
|
30681
|
-
"jsdoctags": [
|
|
30682
|
-
{
|
|
30683
|
-
"name": "node",
|
|
30684
|
-
"deprecated": false,
|
|
30685
|
-
"deprecationMessage": "",
|
|
30686
|
-
"tagName": {
|
|
30687
|
-
"text": "param"
|
|
30688
|
-
}
|
|
30689
|
-
}
|
|
30690
|
-
]
|
|
30691
|
-
},
|
|
30692
30632
|
{
|
|
30693
30633
|
"name": "isTemplateProperty",
|
|
30694
30634
|
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
@@ -30719,6 +30659,66 @@
|
|
|
30719
30659
|
}
|
|
30720
30660
|
]
|
|
30721
30661
|
},
|
|
30662
|
+
{
|
|
30663
|
+
"name": "isTemplateProperty",
|
|
30664
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
30665
|
+
"ctype": "miscellaneous",
|
|
30666
|
+
"subtype": "function",
|
|
30667
|
+
"coverageIgnore": false,
|
|
30668
|
+
"deprecated": false,
|
|
30669
|
+
"deprecationMessage": "",
|
|
30670
|
+
"rawdescription": "",
|
|
30671
|
+
"description": "",
|
|
30672
|
+
"displayName": "isTemplateProperty",
|
|
30673
|
+
"args": [
|
|
30674
|
+
{
|
|
30675
|
+
"name": "node",
|
|
30676
|
+
"deprecated": false,
|
|
30677
|
+
"deprecationMessage": ""
|
|
30678
|
+
}
|
|
30679
|
+
],
|
|
30680
|
+
"returnType": "boolean",
|
|
30681
|
+
"jsdoctags": [
|
|
30682
|
+
{
|
|
30683
|
+
"name": "node",
|
|
30684
|
+
"deprecated": false,
|
|
30685
|
+
"deprecationMessage": "",
|
|
30686
|
+
"tagName": {
|
|
30687
|
+
"text": "param"
|
|
30688
|
+
}
|
|
30689
|
+
}
|
|
30690
|
+
]
|
|
30691
|
+
},
|
|
30692
|
+
{
|
|
30693
|
+
"name": "isTemplateProperty",
|
|
30694
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
30695
|
+
"ctype": "miscellaneous",
|
|
30696
|
+
"subtype": "function",
|
|
30697
|
+
"coverageIgnore": false,
|
|
30698
|
+
"deprecated": false,
|
|
30699
|
+
"deprecationMessage": "",
|
|
30700
|
+
"rawdescription": "",
|
|
30701
|
+
"description": "",
|
|
30702
|
+
"displayName": "isTemplateProperty",
|
|
30703
|
+
"args": [
|
|
30704
|
+
{
|
|
30705
|
+
"name": "node",
|
|
30706
|
+
"deprecated": false,
|
|
30707
|
+
"deprecationMessage": ""
|
|
30708
|
+
}
|
|
30709
|
+
],
|
|
30710
|
+
"returnType": "boolean",
|
|
30711
|
+
"jsdoctags": [
|
|
30712
|
+
{
|
|
30713
|
+
"name": "node",
|
|
30714
|
+
"deprecated": false,
|
|
30715
|
+
"deprecationMessage": "",
|
|
30716
|
+
"tagName": {
|
|
30717
|
+
"text": "param"
|
|
30718
|
+
}
|
|
30719
|
+
}
|
|
30720
|
+
]
|
|
30721
|
+
},
|
|
30722
30722
|
{
|
|
30723
30723
|
"name": "loadEuiDynamicEnvironmentConfig",
|
|
30724
30724
|
"file": "packages/core/src/lib/services/app/eui-pre-init-app.ts",
|
|
@@ -32351,7 +32351,7 @@
|
|
|
32351
32351
|
},
|
|
32352
32352
|
{
|
|
32353
32353
|
"name": "migrateInlineTemplates",
|
|
32354
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
32354
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
32355
32355
|
"ctype": "miscellaneous",
|
|
32356
32356
|
"subtype": "function",
|
|
32357
32357
|
"coverageIgnore": false,
|
|
@@ -32383,7 +32383,7 @@
|
|
|
32383
32383
|
},
|
|
32384
32384
|
{
|
|
32385
32385
|
"name": "migrateInlineTemplates",
|
|
32386
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32386
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
32387
32387
|
"ctype": "miscellaneous",
|
|
32388
32388
|
"subtype": "function",
|
|
32389
32389
|
"coverageIgnore": false,
|
|
@@ -32415,7 +32415,7 @@
|
|
|
32415
32415
|
},
|
|
32416
32416
|
{
|
|
32417
32417
|
"name": "migrateInlineTemplates",
|
|
32418
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32418
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
32419
32419
|
"ctype": "miscellaneous",
|
|
32420
32420
|
"subtype": "function",
|
|
32421
32421
|
"coverageIgnore": false,
|
|
@@ -32479,7 +32479,7 @@
|
|
|
32479
32479
|
},
|
|
32480
32480
|
{
|
|
32481
32481
|
"name": "migrateInlineTemplates",
|
|
32482
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32482
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
32483
32483
|
"ctype": "miscellaneous",
|
|
32484
32484
|
"subtype": "function",
|
|
32485
32485
|
"coverageIgnore": false,
|
|
@@ -32511,7 +32511,7 @@
|
|
|
32511
32511
|
},
|
|
32512
32512
|
{
|
|
32513
32513
|
"name": "migrateInlineTemplates",
|
|
32514
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32514
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
32515
32515
|
"ctype": "miscellaneous",
|
|
32516
32516
|
"subtype": "function",
|
|
32517
32517
|
"coverageIgnore": false,
|
|
@@ -32605,6 +32605,38 @@
|
|
|
32605
32605
|
}
|
|
32606
32606
|
]
|
|
32607
32607
|
},
|
|
32608
|
+
{
|
|
32609
|
+
"name": "migrateInlineTemplates",
|
|
32610
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
32611
|
+
"ctype": "miscellaneous",
|
|
32612
|
+
"subtype": "function",
|
|
32613
|
+
"coverageIgnore": false,
|
|
32614
|
+
"deprecated": false,
|
|
32615
|
+
"deprecationMessage": "",
|
|
32616
|
+
"rawdescription": "",
|
|
32617
|
+
"description": "",
|
|
32618
|
+
"displayName": "migrateInlineTemplates",
|
|
32619
|
+
"args": [
|
|
32620
|
+
{
|
|
32621
|
+
"name": "source",
|
|
32622
|
+
"type": "string",
|
|
32623
|
+
"deprecated": false,
|
|
32624
|
+
"deprecationMessage": ""
|
|
32625
|
+
}
|
|
32626
|
+
],
|
|
32627
|
+
"returnType": "string",
|
|
32628
|
+
"jsdoctags": [
|
|
32629
|
+
{
|
|
32630
|
+
"name": "source",
|
|
32631
|
+
"type": "string",
|
|
32632
|
+
"deprecated": false,
|
|
32633
|
+
"deprecationMessage": "",
|
|
32634
|
+
"tagName": {
|
|
32635
|
+
"text": "param"
|
|
32636
|
+
}
|
|
32637
|
+
}
|
|
32638
|
+
]
|
|
32639
|
+
},
|
|
32608
32640
|
{
|
|
32609
32641
|
"name": "migrateInlineTemplates",
|
|
32610
32642
|
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
@@ -32667,38 +32699,6 @@
|
|
|
32667
32699
|
}
|
|
32668
32700
|
]
|
|
32669
32701
|
},
|
|
32670
|
-
{
|
|
32671
|
-
"name": "migrateInlineTemplates",
|
|
32672
|
-
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
32673
|
-
"ctype": "miscellaneous",
|
|
32674
|
-
"subtype": "function",
|
|
32675
|
-
"coverageIgnore": false,
|
|
32676
|
-
"deprecated": false,
|
|
32677
|
-
"deprecationMessage": "",
|
|
32678
|
-
"rawdescription": "",
|
|
32679
|
-
"description": "",
|
|
32680
|
-
"displayName": "migrateInlineTemplates",
|
|
32681
|
-
"args": [
|
|
32682
|
-
{
|
|
32683
|
-
"name": "source",
|
|
32684
|
-
"type": "string",
|
|
32685
|
-
"deprecated": false,
|
|
32686
|
-
"deprecationMessage": ""
|
|
32687
|
-
}
|
|
32688
|
-
],
|
|
32689
|
-
"returnType": "string",
|
|
32690
|
-
"jsdoctags": [
|
|
32691
|
-
{
|
|
32692
|
-
"name": "source",
|
|
32693
|
-
"type": "string",
|
|
32694
|
-
"deprecated": false,
|
|
32695
|
-
"deprecationMessage": "",
|
|
32696
|
-
"tagName": {
|
|
32697
|
-
"text": "param"
|
|
32698
|
-
}
|
|
32699
|
-
}
|
|
32700
|
-
]
|
|
32701
|
-
},
|
|
32702
32702
|
{
|
|
32703
32703
|
"name": "migrateInlineTemplates",
|
|
32704
32704
|
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
@@ -32891,7 +32891,7 @@
|
|
|
32891
32891
|
},
|
|
32892
32892
|
{
|
|
32893
32893
|
"name": "migrateTemplate",
|
|
32894
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
32894
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
32895
32895
|
"ctype": "miscellaneous",
|
|
32896
32896
|
"subtype": "function",
|
|
32897
32897
|
"coverageIgnore": false,
|
|
@@ -32923,7 +32923,7 @@
|
|
|
32923
32923
|
},
|
|
32924
32924
|
{
|
|
32925
32925
|
"name": "migrateTemplate",
|
|
32926
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32926
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
32927
32927
|
"ctype": "miscellaneous",
|
|
32928
32928
|
"subtype": "function",
|
|
32929
32929
|
"coverageIgnore": false,
|
|
@@ -32955,7 +32955,7 @@
|
|
|
32955
32955
|
},
|
|
32956
32956
|
{
|
|
32957
32957
|
"name": "migrateTemplate",
|
|
32958
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32958
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
32959
32959
|
"ctype": "miscellaneous",
|
|
32960
32960
|
"subtype": "function",
|
|
32961
32961
|
"coverageIgnore": false,
|
|
@@ -33019,7 +33019,7 @@
|
|
|
33019
33019
|
},
|
|
33020
33020
|
{
|
|
33021
33021
|
"name": "migrateTemplate",
|
|
33022
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33022
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
33023
33023
|
"ctype": "miscellaneous",
|
|
33024
33024
|
"subtype": "function",
|
|
33025
33025
|
"coverageIgnore": false,
|
|
@@ -33051,7 +33051,7 @@
|
|
|
33051
33051
|
},
|
|
33052
33052
|
{
|
|
33053
33053
|
"name": "migrateTemplate",
|
|
33054
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33054
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
33055
33055
|
"ctype": "miscellaneous",
|
|
33056
33056
|
"subtype": "function",
|
|
33057
33057
|
"coverageIgnore": false,
|
|
@@ -33147,7 +33147,7 @@
|
|
|
33147
33147
|
},
|
|
33148
33148
|
{
|
|
33149
33149
|
"name": "migrateTemplate",
|
|
33150
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33150
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
33151
33151
|
"ctype": "miscellaneous",
|
|
33152
33152
|
"subtype": "function",
|
|
33153
33153
|
"coverageIgnore": false,
|
|
@@ -33162,21 +33162,9 @@
|
|
|
33162
33162
|
"type": "string",
|
|
33163
33163
|
"deprecated": false,
|
|
33164
33164
|
"deprecationMessage": ""
|
|
33165
|
-
},
|
|
33166
|
-
{
|
|
33167
|
-
"name": "filePath",
|
|
33168
|
-
"type": "string",
|
|
33169
|
-
"deprecated": false,
|
|
33170
|
-
"deprecationMessage": ""
|
|
33171
|
-
},
|
|
33172
|
-
{
|
|
33173
|
-
"name": "context",
|
|
33174
|
-
"type": "SchematicContext",
|
|
33175
|
-
"deprecated": false,
|
|
33176
|
-
"deprecationMessage": ""
|
|
33177
33165
|
}
|
|
33178
33166
|
],
|
|
33179
|
-
"returnType": "
|
|
33167
|
+
"returnType": "string",
|
|
33180
33168
|
"jsdoctags": [
|
|
33181
33169
|
{
|
|
33182
33170
|
"name": "source",
|
|
@@ -33186,30 +33174,12 @@
|
|
|
33186
33174
|
"tagName": {
|
|
33187
33175
|
"text": "param"
|
|
33188
33176
|
}
|
|
33189
|
-
},
|
|
33190
|
-
{
|
|
33191
|
-
"name": "filePath",
|
|
33192
|
-
"type": "string",
|
|
33193
|
-
"deprecated": false,
|
|
33194
|
-
"deprecationMessage": "",
|
|
33195
|
-
"tagName": {
|
|
33196
|
-
"text": "param"
|
|
33197
|
-
}
|
|
33198
|
-
},
|
|
33199
|
-
{
|
|
33200
|
-
"name": "context",
|
|
33201
|
-
"type": "SchematicContext",
|
|
33202
|
-
"deprecated": false,
|
|
33203
|
-
"deprecationMessage": "",
|
|
33204
|
-
"tagName": {
|
|
33205
|
-
"text": "param"
|
|
33206
|
-
}
|
|
33207
33177
|
}
|
|
33208
33178
|
]
|
|
33209
33179
|
},
|
|
33210
33180
|
{
|
|
33211
33181
|
"name": "migrateTemplate",
|
|
33212
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33182
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
33213
33183
|
"ctype": "miscellaneous",
|
|
33214
33184
|
"subtype": "function",
|
|
33215
33185
|
"coverageIgnore": false,
|
|
@@ -33224,6 +33194,18 @@
|
|
|
33224
33194
|
"type": "string",
|
|
33225
33195
|
"deprecated": false,
|
|
33226
33196
|
"deprecationMessage": ""
|
|
33197
|
+
},
|
|
33198
|
+
{
|
|
33199
|
+
"name": "filePath",
|
|
33200
|
+
"type": "string",
|
|
33201
|
+
"deprecated": false,
|
|
33202
|
+
"deprecationMessage": ""
|
|
33203
|
+
},
|
|
33204
|
+
{
|
|
33205
|
+
"name": "context",
|
|
33206
|
+
"type": "SchematicContext",
|
|
33207
|
+
"deprecated": false,
|
|
33208
|
+
"deprecationMessage": ""
|
|
33227
33209
|
}
|
|
33228
33210
|
],
|
|
33229
33211
|
"returnType": "string",
|
|
@@ -33236,12 +33218,30 @@
|
|
|
33236
33218
|
"tagName": {
|
|
33237
33219
|
"text": "param"
|
|
33238
33220
|
}
|
|
33221
|
+
},
|
|
33222
|
+
{
|
|
33223
|
+
"name": "filePath",
|
|
33224
|
+
"type": "string",
|
|
33225
|
+
"deprecated": false,
|
|
33226
|
+
"deprecationMessage": "",
|
|
33227
|
+
"tagName": {
|
|
33228
|
+
"text": "param"
|
|
33229
|
+
}
|
|
33230
|
+
},
|
|
33231
|
+
{
|
|
33232
|
+
"name": "context",
|
|
33233
|
+
"type": "SchematicContext",
|
|
33234
|
+
"deprecated": false,
|
|
33235
|
+
"deprecationMessage": "",
|
|
33236
|
+
"tagName": {
|
|
33237
|
+
"text": "param"
|
|
33238
|
+
}
|
|
33239
33239
|
}
|
|
33240
33240
|
]
|
|
33241
33241
|
},
|
|
33242
33242
|
{
|
|
33243
33243
|
"name": "migrateTemplate",
|
|
33244
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33244
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
33245
33245
|
"ctype": "miscellaneous",
|
|
33246
33246
|
"subtype": "function",
|
|
33247
33247
|
"coverageIgnore": false,
|
|
@@ -33270,7 +33270,7 @@
|
|
|
33270
33270
|
"deprecationMessage": ""
|
|
33271
33271
|
}
|
|
33272
33272
|
],
|
|
33273
|
-
"returnType": "
|
|
33273
|
+
"returnType": "MigrationResult",
|
|
33274
33274
|
"jsdoctags": [
|
|
33275
33275
|
{
|
|
33276
33276
|
"name": "source",
|
|
@@ -33303,7 +33303,7 @@
|
|
|
33303
33303
|
},
|
|
33304
33304
|
{
|
|
33305
33305
|
"name": "migrateTemplate",
|
|
33306
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33306
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
33307
33307
|
"ctype": "miscellaneous",
|
|
33308
33308
|
"subtype": "function",
|
|
33309
33309
|
"coverageIgnore": false,
|
|
@@ -33495,7 +33495,7 @@
|
|
|
33495
33495
|
},
|
|
33496
33496
|
{
|
|
33497
33497
|
"name": "migrateTypeScript",
|
|
33498
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33498
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
33499
33499
|
"ctype": "miscellaneous",
|
|
33500
33500
|
"subtype": "function",
|
|
33501
33501
|
"coverageIgnore": false,
|
|
@@ -33524,7 +33524,7 @@
|
|
|
33524
33524
|
"deprecationMessage": ""
|
|
33525
33525
|
}
|
|
33526
33526
|
],
|
|
33527
|
-
"returnType": "string",
|
|
33527
|
+
"returnType": "{ output: string; hasPaginator: boolean }",
|
|
33528
33528
|
"jsdoctags": [
|
|
33529
33529
|
{
|
|
33530
33530
|
"name": "source",
|
|
@@ -33557,7 +33557,7 @@
|
|
|
33557
33557
|
},
|
|
33558
33558
|
{
|
|
33559
33559
|
"name": "migrateTypeScript",
|
|
33560
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33560
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
33561
33561
|
"ctype": "miscellaneous",
|
|
33562
33562
|
"subtype": "function",
|
|
33563
33563
|
"coverageIgnore": false,
|
|
@@ -33586,7 +33586,7 @@
|
|
|
33586
33586
|
"deprecationMessage": ""
|
|
33587
33587
|
}
|
|
33588
33588
|
],
|
|
33589
|
-
"returnType": "
|
|
33589
|
+
"returnType": "string",
|
|
33590
33590
|
"jsdoctags": [
|
|
33591
33591
|
{
|
|
33592
33592
|
"name": "source",
|
|
@@ -35417,7 +35417,7 @@
|
|
|
35417
35417
|
},
|
|
35418
35418
|
{
|
|
35419
35419
|
"name": "unwrapExpression",
|
|
35420
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35420
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
35421
35421
|
"ctype": "miscellaneous",
|
|
35422
35422
|
"subtype": "function",
|
|
35423
35423
|
"coverageIgnore": false,
|
|
@@ -35447,7 +35447,7 @@
|
|
|
35447
35447
|
},
|
|
35448
35448
|
{
|
|
35449
35449
|
"name": "unwrapExpression",
|
|
35450
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35450
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
35451
35451
|
"ctype": "miscellaneous",
|
|
35452
35452
|
"subtype": "function",
|
|
35453
35453
|
"coverageIgnore": false,
|
|
@@ -35507,7 +35507,7 @@
|
|
|
35507
35507
|
},
|
|
35508
35508
|
{
|
|
35509
35509
|
"name": "unwrapExpression",
|
|
35510
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35510
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
35511
35511
|
"ctype": "miscellaneous",
|
|
35512
35512
|
"subtype": "function",
|
|
35513
35513
|
"coverageIgnore": false,
|
|
@@ -35537,7 +35537,7 @@
|
|
|
35537
35537
|
},
|
|
35538
35538
|
{
|
|
35539
35539
|
"name": "unwrapExpression",
|
|
35540
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35540
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
35541
35541
|
"ctype": "miscellaneous",
|
|
35542
35542
|
"subtype": "function",
|
|
35543
35543
|
"coverageIgnore": false,
|
|
@@ -35567,7 +35567,7 @@
|
|
|
35567
35567
|
},
|
|
35568
35568
|
{
|
|
35569
35569
|
"name": "unwrapExpression",
|
|
35570
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35570
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
35571
35571
|
"ctype": "miscellaneous",
|
|
35572
35572
|
"subtype": "function",
|
|
35573
35573
|
"coverageIgnore": false,
|
|
@@ -35597,7 +35597,7 @@
|
|
|
35597
35597
|
},
|
|
35598
35598
|
{
|
|
35599
35599
|
"name": "unwrapExpression",
|
|
35600
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35600
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
35601
35601
|
"ctype": "miscellaneous",
|
|
35602
35602
|
"subtype": "function",
|
|
35603
35603
|
"coverageIgnore": false,
|
|
@@ -35850,7 +35850,7 @@
|
|
|
35850
35850
|
},
|
|
35851
35851
|
{
|
|
35852
35852
|
"name": "visitDir",
|
|
35853
|
-
"file": "packages/core/schematics/
|
|
35853
|
+
"file": "packages/core/schematics/migrate-eui-accent/index.ts",
|
|
35854
35854
|
"ctype": "miscellaneous",
|
|
35855
35855
|
"subtype": "function",
|
|
35856
35856
|
"coverageIgnore": false,
|
|
@@ -35895,7 +35895,7 @@
|
|
|
35895
35895
|
},
|
|
35896
35896
|
{
|
|
35897
35897
|
"name": "visitDir",
|
|
35898
|
-
"file": "packages/core/schematics/
|
|
35898
|
+
"file": "packages/core/schematics/migrate-eui-alert/index.ts",
|
|
35899
35899
|
"ctype": "miscellaneous",
|
|
35900
35900
|
"subtype": "function",
|
|
35901
35901
|
"coverageIgnore": false,
|
|
@@ -35940,7 +35940,7 @@
|
|
|
35940
35940
|
},
|
|
35941
35941
|
{
|
|
35942
35942
|
"name": "visitDir",
|
|
35943
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35943
|
+
"file": "packages/core/schematics/migrate-eui-avatar/index.ts",
|
|
35944
35944
|
"ctype": "miscellaneous",
|
|
35945
35945
|
"subtype": "function",
|
|
35946
35946
|
"coverageIgnore": false,
|
|
@@ -35985,7 +35985,7 @@
|
|
|
35985
35985
|
},
|
|
35986
35986
|
{
|
|
35987
35987
|
"name": "visitDir",
|
|
35988
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35988
|
+
"file": "packages/core/schematics/migrate-eui-button/index.ts",
|
|
35989
35989
|
"ctype": "miscellaneous",
|
|
35990
35990
|
"subtype": "function",
|
|
35991
35991
|
"coverageIgnore": false,
|
|
@@ -36030,7 +36030,7 @@
|
|
|
36030
36030
|
},
|
|
36031
36031
|
{
|
|
36032
36032
|
"name": "visitDir",
|
|
36033
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36033
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
36034
36034
|
"ctype": "miscellaneous",
|
|
36035
36035
|
"subtype": "function",
|
|
36036
36036
|
"coverageIgnore": false,
|
|
@@ -36075,7 +36075,7 @@
|
|
|
36075
36075
|
},
|
|
36076
36076
|
{
|
|
36077
36077
|
"name": "visitDir",
|
|
36078
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36078
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
36079
36079
|
"ctype": "miscellaneous",
|
|
36080
36080
|
"subtype": "function",
|
|
36081
36081
|
"coverageIgnore": false,
|
|
@@ -36120,7 +36120,7 @@
|
|
|
36120
36120
|
},
|
|
36121
36121
|
{
|
|
36122
36122
|
"name": "visitDir",
|
|
36123
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36123
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
36124
36124
|
"ctype": "miscellaneous",
|
|
36125
36125
|
"subtype": "function",
|
|
36126
36126
|
"coverageIgnore": false,
|
|
@@ -36165,7 +36165,7 @@
|
|
|
36165
36165
|
},
|
|
36166
36166
|
{
|
|
36167
36167
|
"name": "visitDir",
|
|
36168
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36168
|
+
"file": "packages/core/schematics/migrate-eui-editor/index.ts",
|
|
36169
36169
|
"ctype": "miscellaneous",
|
|
36170
36170
|
"subtype": "function",
|
|
36171
36171
|
"coverageIgnore": false,
|
|
@@ -36210,7 +36210,7 @@
|
|
|
36210
36210
|
},
|
|
36211
36211
|
{
|
|
36212
36212
|
"name": "visitDir",
|
|
36213
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36213
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
36214
36214
|
"ctype": "miscellaneous",
|
|
36215
36215
|
"subtype": "function",
|
|
36216
36216
|
"coverageIgnore": false,
|
|
@@ -36255,7 +36255,7 @@
|
|
|
36255
36255
|
},
|
|
36256
36256
|
{
|
|
36257
36257
|
"name": "visitDir",
|
|
36258
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36258
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
36259
36259
|
"ctype": "miscellaneous",
|
|
36260
36260
|
"subtype": "function",
|
|
36261
36261
|
"coverageIgnore": false,
|
|
@@ -36300,7 +36300,7 @@
|
|
|
36300
36300
|
},
|
|
36301
36301
|
{
|
|
36302
36302
|
"name": "visitDir",
|
|
36303
|
-
"file": "packages/core/schematics/migrate-eui-icon-
|
|
36303
|
+
"file": "packages/core/schematics/migrate-eui-icon-toggle/index.ts",
|
|
36304
36304
|
"ctype": "miscellaneous",
|
|
36305
36305
|
"subtype": "function",
|
|
36306
36306
|
"coverageIgnore": false,
|
|
@@ -36345,7 +36345,7 @@
|
|
|
36345
36345
|
},
|
|
36346
36346
|
{
|
|
36347
36347
|
"name": "visitDir",
|
|
36348
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36348
|
+
"file": "packages/core/schematics/migrate-eui-popover/index.ts",
|
|
36349
36349
|
"ctype": "miscellaneous",
|
|
36350
36350
|
"subtype": "function",
|
|
36351
36351
|
"coverageIgnore": false,
|
|
@@ -36390,7 +36390,7 @@
|
|
|
36390
36390
|
},
|
|
36391
36391
|
{
|
|
36392
36392
|
"name": "visitDir",
|
|
36393
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36393
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
36394
36394
|
"ctype": "miscellaneous",
|
|
36395
36395
|
"subtype": "function",
|
|
36396
36396
|
"coverageIgnore": false,
|
|
@@ -36435,7 +36435,7 @@
|
|
|
36435
36435
|
},
|
|
36436
36436
|
{
|
|
36437
36437
|
"name": "visitDir",
|
|
36438
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36438
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
36439
36439
|
"ctype": "miscellaneous",
|
|
36440
36440
|
"subtype": "function",
|
|
36441
36441
|
"coverageIgnore": false,
|
|
@@ -36525,7 +36525,7 @@
|
|
|
36525
36525
|
},
|
|
36526
36526
|
{
|
|
36527
36527
|
"name": "visitDir",
|
|
36528
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36528
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
36529
36529
|
"ctype": "miscellaneous",
|
|
36530
36530
|
"subtype": "function",
|
|
36531
36531
|
"coverageIgnore": false,
|
|
@@ -36570,7 +36570,7 @@
|
|
|
36570
36570
|
},
|
|
36571
36571
|
{
|
|
36572
36572
|
"name": "visitDir",
|
|
36573
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36573
|
+
"file": "packages/core/schematics/migrate-eui-tooltip/index.ts",
|
|
36574
36574
|
"ctype": "miscellaneous",
|
|
36575
36575
|
"subtype": "function",
|
|
36576
36576
|
"coverageIgnore": false,
|
|
@@ -36615,7 +36615,7 @@
|
|
|
36615
36615
|
},
|
|
36616
36616
|
{
|
|
36617
36617
|
"name": "visitDir",
|
|
36618
|
-
"file": "packages/core/schematics/migrate-
|
|
36618
|
+
"file": "packages/core/schematics/migrate-to-signals/index.ts",
|
|
36619
36619
|
"ctype": "miscellaneous",
|
|
36620
36620
|
"subtype": "function",
|
|
36621
36621
|
"coverageIgnore": false,
|
|
@@ -36660,7 +36660,7 @@
|
|
|
36660
36660
|
},
|
|
36661
36661
|
{
|
|
36662
36662
|
"name": "visitDir",
|
|
36663
|
-
"file": "packages/core/schematics/migrate-
|
|
36663
|
+
"file": "packages/core/schematics/migrate-to-standalone/index.ts",
|
|
36664
36664
|
"ctype": "miscellaneous",
|
|
36665
36665
|
"subtype": "function",
|
|
36666
36666
|
"coverageIgnore": false,
|
|
@@ -36705,7 +36705,7 @@
|
|
|
36705
36705
|
},
|
|
36706
36706
|
{
|
|
36707
36707
|
"name": "visitDir",
|
|
36708
|
-
"file": "packages/core/schematics/
|
|
36708
|
+
"file": "packages/core/schematics/fix-no-multiple-empty-lines/index.ts",
|
|
36709
36709
|
"ctype": "miscellaneous",
|
|
36710
36710
|
"subtype": "function",
|
|
36711
36711
|
"coverageIgnore": false,
|
|
@@ -36750,7 +36750,7 @@
|
|
|
36750
36750
|
},
|
|
36751
36751
|
{
|
|
36752
36752
|
"name": "visitDir",
|
|
36753
|
-
"file": "packages/core/schematics/
|
|
36753
|
+
"file": "packages/core/schematics/add-eui-imports/index.ts",
|
|
36754
36754
|
"ctype": "miscellaneous",
|
|
36755
36755
|
"subtype": "function",
|
|
36756
36756
|
"coverageIgnore": false,
|
|
@@ -37012,7 +37012,7 @@
|
|
|
37012
37012
|
},
|
|
37013
37013
|
{
|
|
37014
37014
|
"name": "visitNodes",
|
|
37015
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
37015
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
37016
37016
|
"ctype": "miscellaneous",
|
|
37017
37017
|
"subtype": "function",
|
|
37018
37018
|
"coverageIgnore": false,
|
|
@@ -37028,13 +37028,7 @@
|
|
|
37028
37028
|
"deprecationMessage": ""
|
|
37029
37029
|
},
|
|
37030
37030
|
{
|
|
37031
|
-
"name": "
|
|
37032
|
-
"type": "string",
|
|
37033
|
-
"deprecated": false,
|
|
37034
|
-
"deprecationMessage": ""
|
|
37035
|
-
},
|
|
37036
|
-
{
|
|
37037
|
-
"name": "edits",
|
|
37031
|
+
"name": "removals",
|
|
37038
37032
|
"deprecated": false,
|
|
37039
37033
|
"deprecationMessage": ""
|
|
37040
37034
|
}
|
|
@@ -37050,16 +37044,7 @@
|
|
|
37050
37044
|
}
|
|
37051
37045
|
},
|
|
37052
37046
|
{
|
|
37053
|
-
"name": "
|
|
37054
|
-
"type": "string",
|
|
37055
|
-
"deprecated": false,
|
|
37056
|
-
"deprecationMessage": "",
|
|
37057
|
-
"tagName": {
|
|
37058
|
-
"text": "param"
|
|
37059
|
-
}
|
|
37060
|
-
},
|
|
37061
|
-
{
|
|
37062
|
-
"name": "edits",
|
|
37047
|
+
"name": "removals",
|
|
37063
37048
|
"deprecated": false,
|
|
37064
37049
|
"deprecationMessage": "",
|
|
37065
37050
|
"tagName": {
|
|
@@ -37070,7 +37055,7 @@
|
|
|
37070
37055
|
},
|
|
37071
37056
|
{
|
|
37072
37057
|
"name": "visitNodes",
|
|
37073
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37058
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
37074
37059
|
"ctype": "miscellaneous",
|
|
37075
37060
|
"subtype": "function",
|
|
37076
37061
|
"coverageIgnore": false,
|
|
@@ -37092,7 +37077,7 @@
|
|
|
37092
37077
|
"deprecationMessage": ""
|
|
37093
37078
|
},
|
|
37094
37079
|
{
|
|
37095
|
-
"name": "
|
|
37080
|
+
"name": "edits",
|
|
37096
37081
|
"deprecated": false,
|
|
37097
37082
|
"deprecationMessage": ""
|
|
37098
37083
|
}
|
|
@@ -37117,7 +37102,7 @@
|
|
|
37117
37102
|
}
|
|
37118
37103
|
},
|
|
37119
37104
|
{
|
|
37120
|
-
"name": "
|
|
37105
|
+
"name": "edits",
|
|
37121
37106
|
"deprecated": false,
|
|
37122
37107
|
"deprecationMessage": "",
|
|
37123
37108
|
"tagName": {
|
|
@@ -37128,7 +37113,7 @@
|
|
|
37128
37113
|
},
|
|
37129
37114
|
{
|
|
37130
37115
|
"name": "visitNodes",
|
|
37131
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37116
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
37132
37117
|
"ctype": "miscellaneous",
|
|
37133
37118
|
"subtype": "function",
|
|
37134
37119
|
"coverageIgnore": false,
|
|
@@ -37143,6 +37128,12 @@
|
|
|
37143
37128
|
"deprecated": false,
|
|
37144
37129
|
"deprecationMessage": ""
|
|
37145
37130
|
},
|
|
37131
|
+
{
|
|
37132
|
+
"name": "source",
|
|
37133
|
+
"type": "string",
|
|
37134
|
+
"deprecated": false,
|
|
37135
|
+
"deprecationMessage": ""
|
|
37136
|
+
},
|
|
37146
37137
|
{
|
|
37147
37138
|
"name": "removals",
|
|
37148
37139
|
"deprecated": false,
|
|
@@ -37159,6 +37150,15 @@
|
|
|
37159
37150
|
"text": "param"
|
|
37160
37151
|
}
|
|
37161
37152
|
},
|
|
37153
|
+
{
|
|
37154
|
+
"name": "source",
|
|
37155
|
+
"type": "string",
|
|
37156
|
+
"deprecated": false,
|
|
37157
|
+
"deprecationMessage": "",
|
|
37158
|
+
"tagName": {
|
|
37159
|
+
"text": "param"
|
|
37160
|
+
}
|
|
37161
|
+
},
|
|
37162
37162
|
{
|
|
37163
37163
|
"name": "removals",
|
|
37164
37164
|
"deprecated": false,
|
|
@@ -37214,7 +37214,7 @@
|
|
|
37214
37214
|
},
|
|
37215
37215
|
{
|
|
37216
37216
|
"name": "visitNodes",
|
|
37217
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37217
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
37218
37218
|
"ctype": "miscellaneous",
|
|
37219
37219
|
"subtype": "function",
|
|
37220
37220
|
"coverageIgnore": false,
|
|
@@ -37257,7 +37257,7 @@
|
|
|
37257
37257
|
},
|
|
37258
37258
|
{
|
|
37259
37259
|
"name": "visitNodes",
|
|
37260
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37260
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
37261
37261
|
"ctype": "miscellaneous",
|
|
37262
37262
|
"subtype": "function",
|
|
37263
37263
|
"coverageIgnore": false,
|
|
@@ -39120,74 +39120,74 @@
|
|
|
39120
39120
|
"defaultValue": "'onEditorChanged'"
|
|
39121
39121
|
}
|
|
39122
39122
|
],
|
|
39123
|
-
"packages/core/schematics/migrate-eui-
|
|
39123
|
+
"packages/core/schematics/migrate-eui-fieldset/index.ts": [
|
|
39124
39124
|
{
|
|
39125
39125
|
"name": "COMPONENT_TAG",
|
|
39126
39126
|
"ctype": "miscellaneous",
|
|
39127
39127
|
"subtype": "variable",
|
|
39128
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39128
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
39129
39129
|
"coverageIgnore": false,
|
|
39130
39130
|
"deprecated": false,
|
|
39131
39131
|
"deprecationMessage": "",
|
|
39132
39132
|
"type": "string",
|
|
39133
|
-
"defaultValue": "'eui-
|
|
39133
|
+
"defaultValue": "'eui-fieldset'"
|
|
39134
39134
|
},
|
|
39135
39135
|
{
|
|
39136
|
-
"name": "
|
|
39136
|
+
"name": "NEW_NAME",
|
|
39137
39137
|
"ctype": "miscellaneous",
|
|
39138
39138
|
"subtype": "variable",
|
|
39139
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39139
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
39140
39140
|
"coverageIgnore": false,
|
|
39141
39141
|
"deprecated": false,
|
|
39142
39142
|
"deprecationMessage": "",
|
|
39143
|
-
"type": "
|
|
39144
|
-
"defaultValue": "
|
|
39143
|
+
"type": "string",
|
|
39144
|
+
"defaultValue": "'iconSvgName'"
|
|
39145
39145
|
},
|
|
39146
39146
|
{
|
|
39147
|
-
"name": "
|
|
39147
|
+
"name": "OLD_NAME",
|
|
39148
39148
|
"ctype": "miscellaneous",
|
|
39149
39149
|
"subtype": "variable",
|
|
39150
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39150
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
39151
39151
|
"coverageIgnore": false,
|
|
39152
39152
|
"deprecated": false,
|
|
39153
39153
|
"deprecationMessage": "",
|
|
39154
|
-
"type": "
|
|
39155
|
-
"defaultValue": "
|
|
39154
|
+
"type": "string",
|
|
39155
|
+
"defaultValue": "'iconSvgType'"
|
|
39156
39156
|
}
|
|
39157
39157
|
],
|
|
39158
|
-
"packages/core/schematics/migrate-eui-
|
|
39158
|
+
"packages/core/schematics/migrate-eui-icon-svg/index.ts": [
|
|
39159
39159
|
{
|
|
39160
39160
|
"name": "COMPONENT_TAG",
|
|
39161
39161
|
"ctype": "miscellaneous",
|
|
39162
39162
|
"subtype": "variable",
|
|
39163
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39163
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
39164
39164
|
"coverageIgnore": false,
|
|
39165
39165
|
"deprecated": false,
|
|
39166
39166
|
"deprecationMessage": "",
|
|
39167
39167
|
"type": "string",
|
|
39168
|
-
"defaultValue": "'eui-
|
|
39168
|
+
"defaultValue": "'eui-icon-svg'"
|
|
39169
39169
|
},
|
|
39170
39170
|
{
|
|
39171
|
-
"name": "
|
|
39171
|
+
"name": "INPUT_RENAMES",
|
|
39172
39172
|
"ctype": "miscellaneous",
|
|
39173
39173
|
"subtype": "variable",
|
|
39174
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39174
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
39175
39175
|
"coverageIgnore": false,
|
|
39176
39176
|
"deprecated": false,
|
|
39177
39177
|
"deprecationMessage": "",
|
|
39178
|
-
"type": "
|
|
39179
|
-
"defaultValue": "'
|
|
39178
|
+
"type": "unknown",
|
|
39179
|
+
"defaultValue": "new Map([\n ['variant', 'fillColor'],\n ['aria-label', 'ariaLabel'],\n])"
|
|
39180
39180
|
},
|
|
39181
39181
|
{
|
|
39182
|
-
"name": "
|
|
39182
|
+
"name": "TS_PROPERTY_RENAMES",
|
|
39183
39183
|
"ctype": "miscellaneous",
|
|
39184
39184
|
"subtype": "variable",
|
|
39185
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39185
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
39186
39186
|
"coverageIgnore": false,
|
|
39187
39187
|
"deprecated": false,
|
|
39188
39188
|
"deprecationMessage": "",
|
|
39189
|
-
"type": "
|
|
39190
|
-
"defaultValue": "'
|
|
39189
|
+
"type": "unknown",
|
|
39190
|
+
"defaultValue": "new Map([\n ['variant', 'fillColor'],\n])"
|
|
39191
39191
|
}
|
|
39192
39192
|
],
|
|
39193
39193
|
"packages/core/schematics/migrate-eui-icon-toggle/index.ts": [
|
|
@@ -45989,10 +45989,10 @@
|
|
|
45989
45989
|
]
|
|
45990
45990
|
}
|
|
45991
45991
|
],
|
|
45992
|
-
"packages/core/schematics/migrate-eui-
|
|
45992
|
+
"packages/core/schematics/migrate-eui-fieldset/index.ts": [
|
|
45993
45993
|
{
|
|
45994
45994
|
"name": "applyEdits",
|
|
45995
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
45995
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
45996
45996
|
"ctype": "miscellaneous",
|
|
45997
45997
|
"subtype": "function",
|
|
45998
45998
|
"coverageIgnore": false,
|
|
@@ -46037,7 +46037,7 @@
|
|
|
46037
46037
|
},
|
|
46038
46038
|
{
|
|
46039
46039
|
"name": "collectRenames",
|
|
46040
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46040
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46041
46041
|
"ctype": "miscellaneous",
|
|
46042
46042
|
"subtype": "function",
|
|
46043
46043
|
"coverageIgnore": false,
|
|
@@ -46082,7 +46082,7 @@
|
|
|
46082
46082
|
},
|
|
46083
46083
|
{
|
|
46084
46084
|
"name": "isComponentMetadataProperty",
|
|
46085
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46085
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46086
46086
|
"ctype": "miscellaneous",
|
|
46087
46087
|
"subtype": "function",
|
|
46088
46088
|
"coverageIgnore": false,
|
|
@@ -46112,7 +46112,7 @@
|
|
|
46112
46112
|
},
|
|
46113
46113
|
{
|
|
46114
46114
|
"name": "isTemplateProperty",
|
|
46115
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46115
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46116
46116
|
"ctype": "miscellaneous",
|
|
46117
46117
|
"subtype": "function",
|
|
46118
46118
|
"coverageIgnore": false,
|
|
@@ -46141,8 +46141,8 @@
|
|
|
46141
46141
|
]
|
|
46142
46142
|
},
|
|
46143
46143
|
{
|
|
46144
|
-
"name": "
|
|
46145
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46144
|
+
"name": "migrateEuiFieldset",
|
|
46145
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46146
46146
|
"ctype": "miscellaneous",
|
|
46147
46147
|
"subtype": "function",
|
|
46148
46148
|
"coverageIgnore": false,
|
|
@@ -46150,7 +46150,7 @@
|
|
|
46150
46150
|
"deprecationMessage": "",
|
|
46151
46151
|
"rawdescription": "",
|
|
46152
46152
|
"description": "",
|
|
46153
|
-
"displayName": "
|
|
46153
|
+
"displayName": "migrateEuiFieldset",
|
|
46154
46154
|
"args": [
|
|
46155
46155
|
{
|
|
46156
46156
|
"name": "options",
|
|
@@ -46176,7 +46176,7 @@
|
|
|
46176
46176
|
},
|
|
46177
46177
|
{
|
|
46178
46178
|
"name": "migrateInlineTemplates",
|
|
46179
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46179
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46180
46180
|
"ctype": "miscellaneous",
|
|
46181
46181
|
"subtype": "function",
|
|
46182
46182
|
"coverageIgnore": false,
|
|
@@ -46208,7 +46208,7 @@
|
|
|
46208
46208
|
},
|
|
46209
46209
|
{
|
|
46210
46210
|
"name": "migrateTemplate",
|
|
46211
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46211
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46212
46212
|
"ctype": "miscellaneous",
|
|
46213
46213
|
"subtype": "function",
|
|
46214
46214
|
"coverageIgnore": false,
|
|
@@ -46238,41 +46238,9 @@
|
|
|
46238
46238
|
}
|
|
46239
46239
|
]
|
|
46240
46240
|
},
|
|
46241
|
-
{
|
|
46242
|
-
"name": "renameTsPropertyAccesses",
|
|
46243
|
-
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46244
|
-
"ctype": "miscellaneous",
|
|
46245
|
-
"subtype": "function",
|
|
46246
|
-
"coverageIgnore": false,
|
|
46247
|
-
"deprecated": false,
|
|
46248
|
-
"deprecationMessage": "",
|
|
46249
|
-
"rawdescription": "",
|
|
46250
|
-
"description": "",
|
|
46251
|
-
"displayName": "renameTsPropertyAccesses",
|
|
46252
|
-
"args": [
|
|
46253
|
-
{
|
|
46254
|
-
"name": "source",
|
|
46255
|
-
"type": "string",
|
|
46256
|
-
"deprecated": false,
|
|
46257
|
-
"deprecationMessage": ""
|
|
46258
|
-
}
|
|
46259
|
-
],
|
|
46260
|
-
"returnType": "string",
|
|
46261
|
-
"jsdoctags": [
|
|
46262
|
-
{
|
|
46263
|
-
"name": "source",
|
|
46264
|
-
"type": "string",
|
|
46265
|
-
"deprecated": false,
|
|
46266
|
-
"deprecationMessage": "",
|
|
46267
|
-
"tagName": {
|
|
46268
|
-
"text": "param"
|
|
46269
|
-
}
|
|
46270
|
-
}
|
|
46271
|
-
]
|
|
46272
|
-
},
|
|
46273
46241
|
{
|
|
46274
46242
|
"name": "unwrapExpression",
|
|
46275
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46243
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46276
46244
|
"ctype": "miscellaneous",
|
|
46277
46245
|
"subtype": "function",
|
|
46278
46246
|
"coverageIgnore": false,
|
|
@@ -46302,7 +46270,7 @@
|
|
|
46302
46270
|
},
|
|
46303
46271
|
{
|
|
46304
46272
|
"name": "visitDir",
|
|
46305
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46273
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46306
46274
|
"ctype": "miscellaneous",
|
|
46307
46275
|
"subtype": "function",
|
|
46308
46276
|
"coverageIgnore": false,
|
|
@@ -46347,7 +46315,7 @@
|
|
|
46347
46315
|
},
|
|
46348
46316
|
{
|
|
46349
46317
|
"name": "visitNodes",
|
|
46350
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46318
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46351
46319
|
"ctype": "miscellaneous",
|
|
46352
46320
|
"subtype": "function",
|
|
46353
46321
|
"coverageIgnore": false,
|
|
@@ -46389,10 +46357,10 @@
|
|
|
46389
46357
|
]
|
|
46390
46358
|
}
|
|
46391
46359
|
],
|
|
46392
|
-
"packages/core/schematics/migrate-eui-
|
|
46360
|
+
"packages/core/schematics/migrate-eui-icon-svg/index.ts": [
|
|
46393
46361
|
{
|
|
46394
46362
|
"name": "applyEdits",
|
|
46395
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46363
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46396
46364
|
"ctype": "miscellaneous",
|
|
46397
46365
|
"subtype": "function",
|
|
46398
46366
|
"coverageIgnore": false,
|
|
@@ -46437,7 +46405,7 @@
|
|
|
46437
46405
|
},
|
|
46438
46406
|
{
|
|
46439
46407
|
"name": "collectRenames",
|
|
46440
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46408
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46441
46409
|
"ctype": "miscellaneous",
|
|
46442
46410
|
"subtype": "function",
|
|
46443
46411
|
"coverageIgnore": false,
|
|
@@ -46482,7 +46450,7 @@
|
|
|
46482
46450
|
},
|
|
46483
46451
|
{
|
|
46484
46452
|
"name": "isComponentMetadataProperty",
|
|
46485
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46453
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46486
46454
|
"ctype": "miscellaneous",
|
|
46487
46455
|
"subtype": "function",
|
|
46488
46456
|
"coverageIgnore": false,
|
|
@@ -46512,7 +46480,7 @@
|
|
|
46512
46480
|
},
|
|
46513
46481
|
{
|
|
46514
46482
|
"name": "isTemplateProperty",
|
|
46515
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46483
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46516
46484
|
"ctype": "miscellaneous",
|
|
46517
46485
|
"subtype": "function",
|
|
46518
46486
|
"coverageIgnore": false,
|
|
@@ -46541,8 +46509,8 @@
|
|
|
46541
46509
|
]
|
|
46542
46510
|
},
|
|
46543
46511
|
{
|
|
46544
|
-
"name": "
|
|
46545
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46512
|
+
"name": "migrateEuiIconSvg",
|
|
46513
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46546
46514
|
"ctype": "miscellaneous",
|
|
46547
46515
|
"subtype": "function",
|
|
46548
46516
|
"coverageIgnore": false,
|
|
@@ -46550,7 +46518,7 @@
|
|
|
46550
46518
|
"deprecationMessage": "",
|
|
46551
46519
|
"rawdescription": "",
|
|
46552
46520
|
"description": "",
|
|
46553
|
-
"displayName": "
|
|
46521
|
+
"displayName": "migrateEuiIconSvg",
|
|
46554
46522
|
"args": [
|
|
46555
46523
|
{
|
|
46556
46524
|
"name": "options",
|
|
@@ -46576,7 +46544,7 @@
|
|
|
46576
46544
|
},
|
|
46577
46545
|
{
|
|
46578
46546
|
"name": "migrateInlineTemplates",
|
|
46579
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46547
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46580
46548
|
"ctype": "miscellaneous",
|
|
46581
46549
|
"subtype": "function",
|
|
46582
46550
|
"coverageIgnore": false,
|
|
@@ -46608,7 +46576,7 @@
|
|
|
46608
46576
|
},
|
|
46609
46577
|
{
|
|
46610
46578
|
"name": "migrateTemplate",
|
|
46611
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46579
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46612
46580
|
"ctype": "miscellaneous",
|
|
46613
46581
|
"subtype": "function",
|
|
46614
46582
|
"coverageIgnore": false,
|
|
@@ -46638,9 +46606,41 @@
|
|
|
46638
46606
|
}
|
|
46639
46607
|
]
|
|
46640
46608
|
},
|
|
46609
|
+
{
|
|
46610
|
+
"name": "renameTsPropertyAccesses",
|
|
46611
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46612
|
+
"ctype": "miscellaneous",
|
|
46613
|
+
"subtype": "function",
|
|
46614
|
+
"coverageIgnore": false,
|
|
46615
|
+
"deprecated": false,
|
|
46616
|
+
"deprecationMessage": "",
|
|
46617
|
+
"rawdescription": "",
|
|
46618
|
+
"description": "",
|
|
46619
|
+
"displayName": "renameTsPropertyAccesses",
|
|
46620
|
+
"args": [
|
|
46621
|
+
{
|
|
46622
|
+
"name": "source",
|
|
46623
|
+
"type": "string",
|
|
46624
|
+
"deprecated": false,
|
|
46625
|
+
"deprecationMessage": ""
|
|
46626
|
+
}
|
|
46627
|
+
],
|
|
46628
|
+
"returnType": "string",
|
|
46629
|
+
"jsdoctags": [
|
|
46630
|
+
{
|
|
46631
|
+
"name": "source",
|
|
46632
|
+
"type": "string",
|
|
46633
|
+
"deprecated": false,
|
|
46634
|
+
"deprecationMessage": "",
|
|
46635
|
+
"tagName": {
|
|
46636
|
+
"text": "param"
|
|
46637
|
+
}
|
|
46638
|
+
}
|
|
46639
|
+
]
|
|
46640
|
+
},
|
|
46641
46641
|
{
|
|
46642
46642
|
"name": "unwrapExpression",
|
|
46643
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46643
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46644
46644
|
"ctype": "miscellaneous",
|
|
46645
46645
|
"subtype": "function",
|
|
46646
46646
|
"coverageIgnore": false,
|
|
@@ -46670,7 +46670,7 @@
|
|
|
46670
46670
|
},
|
|
46671
46671
|
{
|
|
46672
46672
|
"name": "visitDir",
|
|
46673
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46673
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46674
46674
|
"ctype": "miscellaneous",
|
|
46675
46675
|
"subtype": "function",
|
|
46676
46676
|
"coverageIgnore": false,
|
|
@@ -46715,7 +46715,7 @@
|
|
|
46715
46715
|
},
|
|
46716
46716
|
{
|
|
46717
46717
|
"name": "visitNodes",
|
|
46718
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46718
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46719
46719
|
"ctype": "miscellaneous",
|
|
46720
46720
|
"subtype": "function",
|
|
46721
46721
|
"coverageIgnore": false,
|
|
@@ -50773,10 +50773,10 @@
|
|
|
50773
50773
|
]
|
|
50774
50774
|
}
|
|
50775
50775
|
],
|
|
50776
|
-
"packages/core/schematics/migrate-eui-
|
|
50776
|
+
"packages/core/schematics/migrate-eui-chip/index.ts": [
|
|
50777
50777
|
{
|
|
50778
50778
|
"name": "collectRemovals",
|
|
50779
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50779
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50780
50780
|
"ctype": "miscellaneous",
|
|
50781
50781
|
"subtype": "function",
|
|
50782
50782
|
"coverageIgnore": false,
|
|
@@ -50792,12 +50792,6 @@
|
|
|
50792
50792
|
"deprecated": false,
|
|
50793
50793
|
"deprecationMessage": ""
|
|
50794
50794
|
},
|
|
50795
|
-
{
|
|
50796
|
-
"name": "source",
|
|
50797
|
-
"type": "string",
|
|
50798
|
-
"deprecated": false,
|
|
50799
|
-
"deprecationMessage": ""
|
|
50800
|
-
},
|
|
50801
50795
|
{
|
|
50802
50796
|
"name": "removals",
|
|
50803
50797
|
"deprecated": false,
|
|
@@ -50816,16 +50810,37 @@
|
|
|
50816
50810
|
}
|
|
50817
50811
|
},
|
|
50818
50812
|
{
|
|
50819
|
-
"name": "
|
|
50820
|
-
"type": "string",
|
|
50813
|
+
"name": "removals",
|
|
50821
50814
|
"deprecated": false,
|
|
50822
50815
|
"deprecationMessage": "",
|
|
50823
50816
|
"tagName": {
|
|
50824
50817
|
"text": "param"
|
|
50825
50818
|
}
|
|
50826
|
-
}
|
|
50819
|
+
}
|
|
50820
|
+
]
|
|
50821
|
+
},
|
|
50822
|
+
{
|
|
50823
|
+
"name": "getAttributeSpan",
|
|
50824
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50825
|
+
"ctype": "miscellaneous",
|
|
50826
|
+
"subtype": "function",
|
|
50827
|
+
"coverageIgnore": false,
|
|
50828
|
+
"deprecated": false,
|
|
50829
|
+
"deprecationMessage": "",
|
|
50830
|
+
"rawdescription": "",
|
|
50831
|
+
"description": "",
|
|
50832
|
+
"displayName": "getAttributeSpan",
|
|
50833
|
+
"args": [
|
|
50827
50834
|
{
|
|
50828
|
-
"name": "
|
|
50835
|
+
"name": "attr",
|
|
50836
|
+
"deprecated": false,
|
|
50837
|
+
"deprecationMessage": ""
|
|
50838
|
+
}
|
|
50839
|
+
],
|
|
50840
|
+
"returnType": "{ start: number; end: number }",
|
|
50841
|
+
"jsdoctags": [
|
|
50842
|
+
{
|
|
50843
|
+
"name": "attr",
|
|
50829
50844
|
"deprecated": false,
|
|
50830
50845
|
"deprecationMessage": "",
|
|
50831
50846
|
"tagName": {
|
|
@@ -50835,8 +50850,8 @@
|
|
|
50835
50850
|
]
|
|
50836
50851
|
},
|
|
50837
50852
|
{
|
|
50838
|
-
"name": "
|
|
50839
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50853
|
+
"name": "isChipElement",
|
|
50854
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50840
50855
|
"ctype": "miscellaneous",
|
|
50841
50856
|
"subtype": "function",
|
|
50842
50857
|
"coverageIgnore": false,
|
|
@@ -50844,7 +50859,39 @@
|
|
|
50844
50859
|
"deprecationMessage": "",
|
|
50845
50860
|
"rawdescription": "",
|
|
50846
50861
|
"description": "",
|
|
50847
|
-
"displayName": "
|
|
50862
|
+
"displayName": "isChipElement",
|
|
50863
|
+
"args": [
|
|
50864
|
+
{
|
|
50865
|
+
"name": "element",
|
|
50866
|
+
"type": "TmplAstElement",
|
|
50867
|
+
"deprecated": false,
|
|
50868
|
+
"deprecationMessage": ""
|
|
50869
|
+
}
|
|
50870
|
+
],
|
|
50871
|
+
"returnType": "boolean",
|
|
50872
|
+
"jsdoctags": [
|
|
50873
|
+
{
|
|
50874
|
+
"name": "element",
|
|
50875
|
+
"type": "TmplAstElement",
|
|
50876
|
+
"deprecated": false,
|
|
50877
|
+
"deprecationMessage": "",
|
|
50878
|
+
"tagName": {
|
|
50879
|
+
"text": "param"
|
|
50880
|
+
}
|
|
50881
|
+
}
|
|
50882
|
+
]
|
|
50883
|
+
},
|
|
50884
|
+
{
|
|
50885
|
+
"name": "migrateEuiChip",
|
|
50886
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50887
|
+
"ctype": "miscellaneous",
|
|
50888
|
+
"subtype": "function",
|
|
50889
|
+
"coverageIgnore": false,
|
|
50890
|
+
"deprecated": false,
|
|
50891
|
+
"deprecationMessage": "",
|
|
50892
|
+
"rawdescription": "",
|
|
50893
|
+
"description": "",
|
|
50894
|
+
"displayName": "migrateEuiChip",
|
|
50848
50895
|
"args": [
|
|
50849
50896
|
{
|
|
50850
50897
|
"name": "options",
|
|
@@ -50870,7 +50917,7 @@
|
|
|
50870
50917
|
},
|
|
50871
50918
|
{
|
|
50872
50919
|
"name": "migrateInlineTemplates",
|
|
50873
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50920
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50874
50921
|
"ctype": "miscellaneous",
|
|
50875
50922
|
"subtype": "function",
|
|
50876
50923
|
"coverageIgnore": false,
|
|
@@ -50902,7 +50949,7 @@
|
|
|
50902
50949
|
},
|
|
50903
50950
|
{
|
|
50904
50951
|
"name": "migrateTemplate",
|
|
50905
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50952
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50906
50953
|
"ctype": "miscellaneous",
|
|
50907
50954
|
"subtype": "function",
|
|
50908
50955
|
"coverageIgnore": false,
|
|
@@ -50934,7 +50981,7 @@
|
|
|
50934
50981
|
},
|
|
50935
50982
|
{
|
|
50936
50983
|
"name": "visitDir",
|
|
50937
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50984
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50938
50985
|
"ctype": "miscellaneous",
|
|
50939
50986
|
"subtype": "function",
|
|
50940
50987
|
"coverageIgnore": false,
|
|
@@ -50979,7 +51026,7 @@
|
|
|
50979
51026
|
},
|
|
50980
51027
|
{
|
|
50981
51028
|
"name": "visitNodes",
|
|
50982
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51029
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50983
51030
|
"ctype": "miscellaneous",
|
|
50984
51031
|
"subtype": "function",
|
|
50985
51032
|
"coverageIgnore": false,
|
|
@@ -50994,12 +51041,6 @@
|
|
|
50994
51041
|
"deprecated": false,
|
|
50995
51042
|
"deprecationMessage": ""
|
|
50996
51043
|
},
|
|
50997
|
-
{
|
|
50998
|
-
"name": "source",
|
|
50999
|
-
"type": "string",
|
|
51000
|
-
"deprecated": false,
|
|
51001
|
-
"deprecationMessage": ""
|
|
51002
|
-
},
|
|
51003
51044
|
{
|
|
51004
51045
|
"name": "removals",
|
|
51005
51046
|
"deprecated": false,
|
|
@@ -51016,15 +51057,6 @@
|
|
|
51016
51057
|
"text": "param"
|
|
51017
51058
|
}
|
|
51018
51059
|
},
|
|
51019
|
-
{
|
|
51020
|
-
"name": "source",
|
|
51021
|
-
"type": "string",
|
|
51022
|
-
"deprecated": false,
|
|
51023
|
-
"deprecationMessage": "",
|
|
51024
|
-
"tagName": {
|
|
51025
|
-
"text": "param"
|
|
51026
|
-
}
|
|
51027
|
-
},
|
|
51028
51060
|
{
|
|
51029
51061
|
"name": "removals",
|
|
51030
51062
|
"deprecated": false,
|
|
@@ -51036,10 +51068,10 @@
|
|
|
51036
51068
|
]
|
|
51037
51069
|
}
|
|
51038
51070
|
],
|
|
51039
|
-
"packages/core/schematics/migrate-eui-
|
|
51071
|
+
"packages/core/schematics/migrate-eui-discussion-thread/index.ts": [
|
|
51040
51072
|
{
|
|
51041
51073
|
"name": "collectRemovals",
|
|
51042
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51074
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51043
51075
|
"ctype": "miscellaneous",
|
|
51044
51076
|
"subtype": "function",
|
|
51045
51077
|
"coverageIgnore": false,
|
|
@@ -51055,6 +51087,12 @@
|
|
|
51055
51087
|
"deprecated": false,
|
|
51056
51088
|
"deprecationMessage": ""
|
|
51057
51089
|
},
|
|
51090
|
+
{
|
|
51091
|
+
"name": "source",
|
|
51092
|
+
"type": "string",
|
|
51093
|
+
"deprecated": false,
|
|
51094
|
+
"deprecationMessage": ""
|
|
51095
|
+
},
|
|
51058
51096
|
{
|
|
51059
51097
|
"name": "removals",
|
|
51060
51098
|
"deprecated": false,
|
|
@@ -51073,69 +51111,16 @@
|
|
|
51073
51111
|
}
|
|
51074
51112
|
},
|
|
51075
51113
|
{
|
|
51076
|
-
"name": "
|
|
51077
|
-
"
|
|
51078
|
-
"deprecationMessage": "",
|
|
51079
|
-
"tagName": {
|
|
51080
|
-
"text": "param"
|
|
51081
|
-
}
|
|
51082
|
-
}
|
|
51083
|
-
]
|
|
51084
|
-
},
|
|
51085
|
-
{
|
|
51086
|
-
"name": "getAttributeSpan",
|
|
51087
|
-
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
51088
|
-
"ctype": "miscellaneous",
|
|
51089
|
-
"subtype": "function",
|
|
51090
|
-
"coverageIgnore": false,
|
|
51091
|
-
"deprecated": false,
|
|
51092
|
-
"deprecationMessage": "",
|
|
51093
|
-
"rawdescription": "",
|
|
51094
|
-
"description": "",
|
|
51095
|
-
"displayName": "getAttributeSpan",
|
|
51096
|
-
"args": [
|
|
51097
|
-
{
|
|
51098
|
-
"name": "attr",
|
|
51099
|
-
"deprecated": false,
|
|
51100
|
-
"deprecationMessage": ""
|
|
51101
|
-
}
|
|
51102
|
-
],
|
|
51103
|
-
"returnType": "{ start: number; end: number }",
|
|
51104
|
-
"jsdoctags": [
|
|
51105
|
-
{
|
|
51106
|
-
"name": "attr",
|
|
51114
|
+
"name": "source",
|
|
51115
|
+
"type": "string",
|
|
51107
51116
|
"deprecated": false,
|
|
51108
51117
|
"deprecationMessage": "",
|
|
51109
51118
|
"tagName": {
|
|
51110
51119
|
"text": "param"
|
|
51111
51120
|
}
|
|
51112
|
-
}
|
|
51113
|
-
]
|
|
51114
|
-
},
|
|
51115
|
-
{
|
|
51116
|
-
"name": "isChipElement",
|
|
51117
|
-
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
51118
|
-
"ctype": "miscellaneous",
|
|
51119
|
-
"subtype": "function",
|
|
51120
|
-
"coverageIgnore": false,
|
|
51121
|
-
"deprecated": false,
|
|
51122
|
-
"deprecationMessage": "",
|
|
51123
|
-
"rawdescription": "",
|
|
51124
|
-
"description": "",
|
|
51125
|
-
"displayName": "isChipElement",
|
|
51126
|
-
"args": [
|
|
51127
|
-
{
|
|
51128
|
-
"name": "element",
|
|
51129
|
-
"type": "TmplAstElement",
|
|
51130
|
-
"deprecated": false,
|
|
51131
|
-
"deprecationMessage": ""
|
|
51132
|
-
}
|
|
51133
|
-
],
|
|
51134
|
-
"returnType": "boolean",
|
|
51135
|
-
"jsdoctags": [
|
|
51121
|
+
},
|
|
51136
51122
|
{
|
|
51137
|
-
"name": "
|
|
51138
|
-
"type": "TmplAstElement",
|
|
51123
|
+
"name": "removals",
|
|
51139
51124
|
"deprecated": false,
|
|
51140
51125
|
"deprecationMessage": "",
|
|
51141
51126
|
"tagName": {
|
|
@@ -51145,8 +51130,8 @@
|
|
|
51145
51130
|
]
|
|
51146
51131
|
},
|
|
51147
51132
|
{
|
|
51148
|
-
"name": "
|
|
51149
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51133
|
+
"name": "migrateEuiDiscussionThread",
|
|
51134
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51150
51135
|
"ctype": "miscellaneous",
|
|
51151
51136
|
"subtype": "function",
|
|
51152
51137
|
"coverageIgnore": false,
|
|
@@ -51154,7 +51139,7 @@
|
|
|
51154
51139
|
"deprecationMessage": "",
|
|
51155
51140
|
"rawdescription": "",
|
|
51156
51141
|
"description": "",
|
|
51157
|
-
"displayName": "
|
|
51142
|
+
"displayName": "migrateEuiDiscussionThread",
|
|
51158
51143
|
"args": [
|
|
51159
51144
|
{
|
|
51160
51145
|
"name": "options",
|
|
@@ -51180,7 +51165,7 @@
|
|
|
51180
51165
|
},
|
|
51181
51166
|
{
|
|
51182
51167
|
"name": "migrateInlineTemplates",
|
|
51183
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51168
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51184
51169
|
"ctype": "miscellaneous",
|
|
51185
51170
|
"subtype": "function",
|
|
51186
51171
|
"coverageIgnore": false,
|
|
@@ -51212,7 +51197,7 @@
|
|
|
51212
51197
|
},
|
|
51213
51198
|
{
|
|
51214
51199
|
"name": "migrateTemplate",
|
|
51215
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51200
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51216
51201
|
"ctype": "miscellaneous",
|
|
51217
51202
|
"subtype": "function",
|
|
51218
51203
|
"coverageIgnore": false,
|
|
@@ -51244,7 +51229,7 @@
|
|
|
51244
51229
|
},
|
|
51245
51230
|
{
|
|
51246
51231
|
"name": "visitDir",
|
|
51247
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51232
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51248
51233
|
"ctype": "miscellaneous",
|
|
51249
51234
|
"subtype": "function",
|
|
51250
51235
|
"coverageIgnore": false,
|
|
@@ -51289,7 +51274,7 @@
|
|
|
51289
51274
|
},
|
|
51290
51275
|
{
|
|
51291
51276
|
"name": "visitNodes",
|
|
51292
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51277
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51293
51278
|
"ctype": "miscellaneous",
|
|
51294
51279
|
"subtype": "function",
|
|
51295
51280
|
"coverageIgnore": false,
|
|
@@ -51304,6 +51289,12 @@
|
|
|
51304
51289
|
"deprecated": false,
|
|
51305
51290
|
"deprecationMessage": ""
|
|
51306
51291
|
},
|
|
51292
|
+
{
|
|
51293
|
+
"name": "source",
|
|
51294
|
+
"type": "string",
|
|
51295
|
+
"deprecated": false,
|
|
51296
|
+
"deprecationMessage": ""
|
|
51297
|
+
},
|
|
51307
51298
|
{
|
|
51308
51299
|
"name": "removals",
|
|
51309
51300
|
"deprecated": false,
|
|
@@ -51320,6 +51311,15 @@
|
|
|
51320
51311
|
"text": "param"
|
|
51321
51312
|
}
|
|
51322
51313
|
},
|
|
51314
|
+
{
|
|
51315
|
+
"name": "source",
|
|
51316
|
+
"type": "string",
|
|
51317
|
+
"deprecated": false,
|
|
51318
|
+
"deprecationMessage": "",
|
|
51319
|
+
"tagName": {
|
|
51320
|
+
"text": "param"
|
|
51321
|
+
}
|
|
51322
|
+
},
|
|
51323
51323
|
{
|
|
51324
51324
|
"name": "removals",
|
|
51325
51325
|
"deprecated": false,
|