@eui/core 22.0.0-alpha.4 → 22.0.0-alpha.6
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 +141 -0
- package/docs/changelog.html +274 -0
- package/docs/directives/TranslateMockDirective.html +0 -6
- package/docs/js/menu-wc.js +6 -6
- package/docs/js/search/search_index.js +2 -2
- package/docs/json/TranslateMockDirective.md +1 -1
- package/docs/json/documentation.json +437 -433
- package/docs/llms.txt +2 -2
- package/docs/properties.html +1 -1
- package/fesm2022/eui-core.mjs +5 -5
- package/fesm2022/eui-core.mjs.map +1 -1
- package/package.json +2 -2
- package/types/eui-core.d.ts +2 -2
- package/types/eui-core.d.ts.map +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"pipes": [
|
|
3
3
|
{
|
|
4
4
|
"name": "TranslateMockPipe",
|
|
5
|
-
"id": "pipe-TranslateMockPipe-
|
|
5
|
+
"id": "pipe-TranslateMockPipe-d42afa990d476989657d92ef3f9c88346ef461191fc8641719f83d538694483a6f785c8618d8ee729faee7c37e723a1fdfcac95badfa6e5259f869ebe95cccad",
|
|
6
6
|
"file": "packages/core/src/lib/mocks/translate.module.mock.ts",
|
|
7
7
|
"type": "pipe",
|
|
8
8
|
"coverageIgnore": false,
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"optional": false,
|
|
29
29
|
"returnType": "string",
|
|
30
30
|
"typeParameters": [],
|
|
31
|
-
"line":
|
|
31
|
+
"line": 74,
|
|
32
32
|
"deprecated": false,
|
|
33
33
|
"deprecationMessage": "",
|
|
34
34
|
"rawdescription": "\n",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
],
|
|
51
51
|
"standalone": false,
|
|
52
52
|
"ngname": "translate",
|
|
53
|
-
"sourceCode": "import {
|
|
53
|
+
"sourceCode": "import {\n AfterViewChecked,\n Directive,\n ElementRef,\n Input,\n NgModule,\n Pipe,\n PipeTransform,\n inject,\n signal,\n input,\n} from '@angular/core';\nimport { LangChangeEvent, TranslateLoader, TranslateService } from '@ngx-translate/core';\nimport { BehaviorSubject, Observable, of, Subject } from 'rxjs';\n\nexport const TRANSLATED_STRING = 'i18n';\nexport const DEFAULT_LANGUAGE = 'en';\n\nexport class TranslateServiceMock {\n onLangChangeSubject: Subject<LangChangeEvent> = new Subject();\n onTranslationChangeSubject: Subject<string> = new Subject();\n onFallbackLangChangeSubject: Subject<string> = new Subject();\n isLoadedSubject: BehaviorSubject<boolean> = new BehaviorSubject(true);\n\n onLangChange: Observable<LangChangeEvent> = this.onLangChangeSubject.asObservable();\n onTranslationChange: Observable<string> = this.onTranslationChangeSubject.asObservable();\n onFallbackLangChange: Observable<string> = this.onFallbackLangChangeSubject.asObservable();\n isLoaded: Observable<boolean> = this.isLoadedSubject.asObservable();\n\n currentLang = signal<string | null>(null);\n\n languages: string[] = [DEFAULT_LANGUAGE];\n\n get(content: string): Observable<string> {\n return of(TRANSLATED_STRING + content);\n }\n\n use(lang: string): void {\n this.currentLang.set(lang);\n this.onLangChangeSubject.next({ lang } as LangChangeEvent);\n }\n\n addLangs(langs: string[]): void {\n this.languages = [...this.languages, ...langs];\n }\n\n getBrowserLang(): string {\n return DEFAULT_LANGUAGE;\n }\n\n getLangs(): string[] {\n return this.languages;\n }\n\n // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getTranslation(): Observable<any> {\n return of({});\n }\n\n instant(key: string | string[]): string {\n return TRANSLATED_STRING + key.toString();\n }\n\n setFallbackLang(lang: string): void {\n this.onFallbackLangChangeSubject.next(lang);\n }\n}\n\n@Pipe({ name: 'translate' })\nexport class TranslateMockPipe implements PipeTransform {\n transform(text: string): string {\n return !text ? TRANSLATED_STRING : `${text}-${TRANSLATED_STRING}`;\n }\n}\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[translate]',\n})\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class TranslateMockDirective implements AfterViewChecked {\n readonly translateParams = input();\n\n private readonly _element = inject(ElementRef);\n\n ngAfterViewChecked(): void {\n this._element.nativeElement.innerText += TRANSLATED_STRING;\n }\n}\n\nexport class TranslateLoaderMock implements TranslateLoader {\n getTranslation(): Observable<Record<string, string>> {\n return of({});\n }\n}\n\n@NgModule({\n imports: [TranslateMockPipe, TranslateMockDirective],\n exports: [TranslateMockPipe, TranslateMockDirective],\n providers: [\n { provide: TranslateService, useClass: TranslateServiceMock },\n { provide: TranslateLoader, useClass: TranslateLoaderMock },\n ],\n})\nexport class TranslateMockModule {}\n",
|
|
54
54
|
"relationships": {
|
|
55
55
|
"incoming": [
|
|
56
56
|
{
|
|
@@ -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
|
],
|
|
@@ -2536,12 +2536,12 @@
|
|
|
2536
2536
|
},
|
|
2537
2537
|
{
|
|
2538
2538
|
"name": "Schema",
|
|
2539
|
-
"id": "interface-Schema-
|
|
2540
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
2539
|
+
"id": "interface-Schema-39d3d52e788050bebc4e0b99ed0756f7e9727556cb090ae8796bd4261a56463fe1f479c322b23028cd4134d71e4d1dc44cd248ac62a9a148b5fc46a665466f7c-8",
|
|
2540
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
2541
2541
|
"deprecated": false,
|
|
2542
2542
|
"deprecationMessage": "",
|
|
2543
2543
|
"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",
|
|
2544
|
+
"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
2545
|
"displayName": "Schema",
|
|
2546
2546
|
"properties": [
|
|
2547
2547
|
{
|
|
@@ -2553,7 +2553,7 @@
|
|
|
2553
2553
|
"indexKey": "",
|
|
2554
2554
|
"optional": true,
|
|
2555
2555
|
"description": "",
|
|
2556
|
-
"line":
|
|
2556
|
+
"line": 8,
|
|
2557
2557
|
"rawdescription": "\n"
|
|
2558
2558
|
},
|
|
2559
2559
|
{
|
|
@@ -2565,7 +2565,7 @@
|
|
|
2565
2565
|
"indexKey": "",
|
|
2566
2566
|
"optional": true,
|
|
2567
2567
|
"description": "",
|
|
2568
|
-
"line":
|
|
2568
|
+
"line": 7,
|
|
2569
2569
|
"rawdescription": "\n"
|
|
2570
2570
|
}
|
|
2571
2571
|
],
|
|
@@ -2583,12 +2583,12 @@
|
|
|
2583
2583
|
},
|
|
2584
2584
|
{
|
|
2585
2585
|
"name": "Schema",
|
|
2586
|
-
"id": "interface-Schema-
|
|
2587
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2586
|
+
"id": "interface-Schema-311bef7d5e4b40b356b0fdb5e35dd89e48a5c5beec29eeb865c22c2ca1c4c4fb1fd0bb4391ed0b33825a6d1d744bc3a2e9822b347fbc686a537e15b170c279dd-9",
|
|
2587
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
2588
2588
|
"deprecated": false,
|
|
2589
2589
|
"deprecationMessage": "",
|
|
2590
2590
|
"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",
|
|
2591
|
+
"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
2592
|
"displayName": "Schema",
|
|
2593
2593
|
"properties": [
|
|
2594
2594
|
{
|
|
@@ -2600,7 +2600,7 @@
|
|
|
2600
2600
|
"indexKey": "",
|
|
2601
2601
|
"optional": true,
|
|
2602
2602
|
"description": "",
|
|
2603
|
-
"line":
|
|
2603
|
+
"line": 28,
|
|
2604
2604
|
"rawdescription": "\n"
|
|
2605
2605
|
},
|
|
2606
2606
|
{
|
|
@@ -2612,7 +2612,7 @@
|
|
|
2612
2612
|
"indexKey": "",
|
|
2613
2613
|
"optional": true,
|
|
2614
2614
|
"description": "",
|
|
2615
|
-
"line":
|
|
2615
|
+
"line": 27,
|
|
2616
2616
|
"rawdescription": "\n"
|
|
2617
2617
|
}
|
|
2618
2618
|
],
|
|
@@ -2630,12 +2630,12 @@
|
|
|
2630
2630
|
},
|
|
2631
2631
|
{
|
|
2632
2632
|
"name": "Schema",
|
|
2633
|
-
"id": "interface-Schema-
|
|
2634
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2633
|
+
"id": "interface-Schema-869dfc324e9111966817cbebb3553eabfe200acfe33bb77efa71a6c46e1cba0ff5852de7b9ade3060f87264035b99591361331a9e0622daaac22b8d59146c761-10",
|
|
2634
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
2635
2635
|
"deprecated": false,
|
|
2636
2636
|
"deprecationMessage": "",
|
|
2637
2637
|
"type": "interface",
|
|
2638
|
-
"sourceCode": "import { parseTemplate, TmplAstBoundAttribute, TmplAstElement, TmplAstNode
|
|
2638
|
+
"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
2639
|
"displayName": "Schema",
|
|
2640
2640
|
"properties": [
|
|
2641
2641
|
{
|
|
@@ -2724,12 +2724,12 @@
|
|
|
2724
2724
|
},
|
|
2725
2725
|
{
|
|
2726
2726
|
"name": "Schema",
|
|
2727
|
-
"id": "interface-Schema-
|
|
2728
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2727
|
+
"id": "interface-Schema-0ee574e11dd651dd971057cb66220845e5b87b2949c69c623c8ddf7355af92a396c58c237a52a05f18c22a5332a2695b717bcfeb8ea840c4e7df8d0084c2b49c-12",
|
|
2728
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
2729
2729
|
"deprecated": false,
|
|
2730
2730
|
"deprecationMessage": "",
|
|
2731
2731
|
"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-
|
|
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-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
2733
|
"displayName": "Schema",
|
|
2734
2734
|
"properties": [
|
|
2735
2735
|
{
|
|
@@ -2771,12 +2771,12 @@
|
|
|
2771
2771
|
},
|
|
2772
2772
|
{
|
|
2773
2773
|
"name": "Schema",
|
|
2774
|
-
"id": "interface-Schema-
|
|
2775
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2774
|
+
"id": "interface-Schema-b3ff4600c4a5ca1888c45e5baf3600fa6dc6477f1e473e5241ff6682e2929dc8950a5dfa8b1048a348dba7ad1f0ce8cc3681471933911b689e04713334ef4811-13",
|
|
2775
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
2776
2776
|
"deprecated": false,
|
|
2777
2777
|
"deprecationMessage": "",
|
|
2778
2778
|
"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-
|
|
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-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
2780
|
"displayName": "Schema",
|
|
2781
2781
|
"properties": [
|
|
2782
2782
|
{
|
|
@@ -2912,12 +2912,12 @@
|
|
|
2912
2912
|
},
|
|
2913
2913
|
{
|
|
2914
2914
|
"name": "Schema",
|
|
2915
|
-
"id": "interface-Schema-
|
|
2916
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2915
|
+
"id": "interface-Schema-90e62c16ce9ada881e8d434336bb633dae9745236106ddf60964afbd11de6aa579255a13d6036b384281860eb6ed2ee329194b519c51fdaf20f79bc511d0f64f-16",
|
|
2916
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
2917
2917
|
"deprecated": false,
|
|
2918
2918
|
"deprecationMessage": "",
|
|
2919
2919
|
"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",
|
|
2920
|
+
"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
2921
|
"displayName": "Schema",
|
|
2922
2922
|
"properties": [
|
|
2923
2923
|
{
|
|
@@ -2929,7 +2929,7 @@
|
|
|
2929
2929
|
"indexKey": "",
|
|
2930
2930
|
"optional": true,
|
|
2931
2931
|
"description": "",
|
|
2932
|
-
"line":
|
|
2932
|
+
"line": 8,
|
|
2933
2933
|
"rawdescription": "\n"
|
|
2934
2934
|
},
|
|
2935
2935
|
{
|
|
@@ -2941,7 +2941,7 @@
|
|
|
2941
2941
|
"indexKey": "",
|
|
2942
2942
|
"optional": true,
|
|
2943
2943
|
"description": "",
|
|
2944
|
-
"line":
|
|
2944
|
+
"line": 7,
|
|
2945
2945
|
"rawdescription": "\n"
|
|
2946
2946
|
}
|
|
2947
2947
|
],
|
|
@@ -2959,12 +2959,12 @@
|
|
|
2959
2959
|
},
|
|
2960
2960
|
{
|
|
2961
2961
|
"name": "Schema",
|
|
2962
|
-
"id": "interface-Schema-
|
|
2963
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
2962
|
+
"id": "interface-Schema-91c9f900bf3ebb82488fb65644938ef486ceaa447cff8bfd9d710df9595d82acb267b26f3c252173bc684353f362473120226426ed7ee5d98b33e30011dd9383-17",
|
|
2963
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
2964
2964
|
"deprecated": false,
|
|
2965
2965
|
"deprecationMessage": "",
|
|
2966
2966
|
"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",
|
|
2967
|
+
"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
2968
|
"displayName": "Schema",
|
|
2969
2969
|
"properties": [
|
|
2970
2970
|
{
|
|
@@ -2976,7 +2976,7 @@
|
|
|
2976
2976
|
"indexKey": "",
|
|
2977
2977
|
"optional": true,
|
|
2978
2978
|
"description": "",
|
|
2979
|
-
"line":
|
|
2979
|
+
"line": 49,
|
|
2980
2980
|
"rawdescription": "\n"
|
|
2981
2981
|
},
|
|
2982
2982
|
{
|
|
@@ -2988,7 +2988,7 @@
|
|
|
2988
2988
|
"indexKey": "",
|
|
2989
2989
|
"optional": true,
|
|
2990
2990
|
"description": "",
|
|
2991
|
-
"line":
|
|
2991
|
+
"line": 48,
|
|
2992
2992
|
"rawdescription": "\n"
|
|
2993
2993
|
}
|
|
2994
2994
|
],
|
|
@@ -3006,12 +3006,12 @@
|
|
|
3006
3006
|
},
|
|
3007
3007
|
{
|
|
3008
3008
|
"name": "Schema",
|
|
3009
|
-
"id": "interface-Schema-
|
|
3010
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
3009
|
+
"id": "interface-Schema-760dec88d3f709d5b38226e55f7cbfb1e5fabcea6c004fd46e611be1dd563b8b247e9e6c77667e5582fe7b443374ba2c4facd2b2db2985edb46c9a4a37a8a876-18",
|
|
3010
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
3011
3011
|
"deprecated": false,
|
|
3012
3012
|
"deprecationMessage": "",
|
|
3013
3013
|
"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",
|
|
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\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
3015
|
"displayName": "Schema",
|
|
3016
3016
|
"properties": [
|
|
3017
3017
|
{
|
|
@@ -3023,7 +3023,7 @@
|
|
|
3023
3023
|
"indexKey": "",
|
|
3024
3024
|
"optional": true,
|
|
3025
3025
|
"description": "",
|
|
3026
|
-
"line":
|
|
3026
|
+
"line": 20,
|
|
3027
3027
|
"rawdescription": "\n"
|
|
3028
3028
|
},
|
|
3029
3029
|
{
|
|
@@ -3035,7 +3035,7 @@
|
|
|
3035
3035
|
"indexKey": "",
|
|
3036
3036
|
"optional": true,
|
|
3037
3037
|
"description": "",
|
|
3038
|
-
"line":
|
|
3038
|
+
"line": 19,
|
|
3039
3039
|
"rawdescription": "\n"
|
|
3040
3040
|
}
|
|
3041
3041
|
],
|
|
@@ -3053,12 +3053,12 @@
|
|
|
3053
3053
|
},
|
|
3054
3054
|
{
|
|
3055
3055
|
"name": "Schema",
|
|
3056
|
-
"id": "interface-Schema-
|
|
3057
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
3056
|
+
"id": "interface-Schema-e1cd02924eb82a618c71a0b26c081bdd020519d2699aa0e2dc98640c4e0f347c3649b967c5fc87543e41bbbfabd1304835850ccc38f40684d6521c242b2030ed-19",
|
|
3057
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
3058
3058
|
"deprecated": false,
|
|
3059
3059
|
"deprecationMessage": "",
|
|
3060
3060
|
"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",
|
|
3061
|
+
"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
3062
|
"displayName": "Schema",
|
|
3063
3063
|
"properties": [
|
|
3064
3064
|
{
|
|
@@ -3070,7 +3070,7 @@
|
|
|
3070
3070
|
"indexKey": "",
|
|
3071
3071
|
"optional": true,
|
|
3072
3072
|
"description": "",
|
|
3073
|
-
"line":
|
|
3073
|
+
"line": 18,
|
|
3074
3074
|
"rawdescription": "\n"
|
|
3075
3075
|
},
|
|
3076
3076
|
{
|
|
@@ -3082,7 +3082,7 @@
|
|
|
3082
3082
|
"indexKey": "",
|
|
3083
3083
|
"optional": true,
|
|
3084
3084
|
"description": "",
|
|
3085
|
-
"line":
|
|
3085
|
+
"line": 17,
|
|
3086
3086
|
"rawdescription": "\n"
|
|
3087
3087
|
}
|
|
3088
3088
|
],
|
|
@@ -19673,13 +19673,13 @@
|
|
|
19673
19673
|
},
|
|
19674
19674
|
{
|
|
19675
19675
|
"name": "TranslateLoaderMock",
|
|
19676
|
-
"id": "class-TranslateLoaderMock-
|
|
19676
|
+
"id": "class-TranslateLoaderMock-d42afa990d476989657d92ef3f9c88346ef461191fc8641719f83d538694483a6f785c8618d8ee729faee7c37e723a1fdfcac95badfa6e5259f869ebe95cccad",
|
|
19677
19677
|
"file": "packages/core/src/lib/mocks/translate.module.mock.ts",
|
|
19678
19678
|
"coverageIgnore": false,
|
|
19679
19679
|
"deprecated": false,
|
|
19680
19680
|
"deprecationMessage": "",
|
|
19681
19681
|
"type": "class",
|
|
19682
|
-
"sourceCode": "import {
|
|
19682
|
+
"sourceCode": "import {\n AfterViewChecked,\n Directive,\n ElementRef,\n Input,\n NgModule,\n Pipe,\n PipeTransform,\n inject,\n signal,\n input,\n} from '@angular/core';\nimport { LangChangeEvent, TranslateLoader, TranslateService } from '@ngx-translate/core';\nimport { BehaviorSubject, Observable, of, Subject } from 'rxjs';\n\nexport const TRANSLATED_STRING = 'i18n';\nexport const DEFAULT_LANGUAGE = 'en';\n\nexport class TranslateServiceMock {\n onLangChangeSubject: Subject<LangChangeEvent> = new Subject();\n onTranslationChangeSubject: Subject<string> = new Subject();\n onFallbackLangChangeSubject: Subject<string> = new Subject();\n isLoadedSubject: BehaviorSubject<boolean> = new BehaviorSubject(true);\n\n onLangChange: Observable<LangChangeEvent> = this.onLangChangeSubject.asObservable();\n onTranslationChange: Observable<string> = this.onTranslationChangeSubject.asObservable();\n onFallbackLangChange: Observable<string> = this.onFallbackLangChangeSubject.asObservable();\n isLoaded: Observable<boolean> = this.isLoadedSubject.asObservable();\n\n currentLang = signal<string | null>(null);\n\n languages: string[] = [DEFAULT_LANGUAGE];\n\n get(content: string): Observable<string> {\n return of(TRANSLATED_STRING + content);\n }\n\n use(lang: string): void {\n this.currentLang.set(lang);\n this.onLangChangeSubject.next({ lang } as LangChangeEvent);\n }\n\n addLangs(langs: string[]): void {\n this.languages = [...this.languages, ...langs];\n }\n\n getBrowserLang(): string {\n return DEFAULT_LANGUAGE;\n }\n\n getLangs(): string[] {\n return this.languages;\n }\n\n // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getTranslation(): Observable<any> {\n return of({});\n }\n\n instant(key: string | string[]): string {\n return TRANSLATED_STRING + key.toString();\n }\n\n setFallbackLang(lang: string): void {\n this.onFallbackLangChangeSubject.next(lang);\n }\n}\n\n@Pipe({ name: 'translate' })\nexport class TranslateMockPipe implements PipeTransform {\n transform(text: string): string {\n return !text ? TRANSLATED_STRING : `${text}-${TRANSLATED_STRING}`;\n }\n}\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[translate]',\n})\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class TranslateMockDirective implements AfterViewChecked {\n readonly translateParams = input();\n\n private readonly _element = inject(ElementRef);\n\n ngAfterViewChecked(): void {\n this._element.nativeElement.innerText += TRANSLATED_STRING;\n }\n}\n\nexport class TranslateLoaderMock implements TranslateLoader {\n getTranslation(): Observable<Record<string, string>> {\n return of({});\n }\n}\n\n@NgModule({\n imports: [TranslateMockPipe, TranslateMockDirective],\n exports: [TranslateMockPipe, TranslateMockDirective],\n providers: [\n { provide: TranslateService, useClass: TranslateServiceMock },\n { provide: TranslateLoader, useClass: TranslateLoaderMock },\n ],\n})\nexport class TranslateMockModule {}\n",
|
|
19683
19683
|
"displayName": "TranslateLoaderMock",
|
|
19684
19684
|
"inputsClass": [],
|
|
19685
19685
|
"outputsClass": [],
|
|
@@ -19692,7 +19692,7 @@
|
|
|
19692
19692
|
"optional": false,
|
|
19693
19693
|
"returnType": "Observable<Record<string, string>>",
|
|
19694
19694
|
"typeParameters": [],
|
|
19695
|
-
"line":
|
|
19695
|
+
"line": 95,
|
|
19696
19696
|
"deprecated": false,
|
|
19697
19697
|
"deprecationMessage": "",
|
|
19698
19698
|
"rawdescription": "\n",
|
|
@@ -19718,13 +19718,13 @@
|
|
|
19718
19718
|
},
|
|
19719
19719
|
{
|
|
19720
19720
|
"name": "TranslateServiceMock",
|
|
19721
|
-
"id": "class-TranslateServiceMock-
|
|
19721
|
+
"id": "class-TranslateServiceMock-d42afa990d476989657d92ef3f9c88346ef461191fc8641719f83d538694483a6f785c8618d8ee729faee7c37e723a1fdfcac95badfa6e5259f869ebe95cccad",
|
|
19722
19722
|
"file": "packages/core/src/lib/mocks/translate.module.mock.ts",
|
|
19723
19723
|
"coverageIgnore": false,
|
|
19724
19724
|
"deprecated": false,
|
|
19725
19725
|
"deprecationMessage": "",
|
|
19726
19726
|
"type": "class",
|
|
19727
|
-
"sourceCode": "import {
|
|
19727
|
+
"sourceCode": "import {\n AfterViewChecked,\n Directive,\n ElementRef,\n Input,\n NgModule,\n Pipe,\n PipeTransform,\n inject,\n signal,\n input,\n} from '@angular/core';\nimport { LangChangeEvent, TranslateLoader, TranslateService } from '@ngx-translate/core';\nimport { BehaviorSubject, Observable, of, Subject } from 'rxjs';\n\nexport const TRANSLATED_STRING = 'i18n';\nexport const DEFAULT_LANGUAGE = 'en';\n\nexport class TranslateServiceMock {\n onLangChangeSubject: Subject<LangChangeEvent> = new Subject();\n onTranslationChangeSubject: Subject<string> = new Subject();\n onFallbackLangChangeSubject: Subject<string> = new Subject();\n isLoadedSubject: BehaviorSubject<boolean> = new BehaviorSubject(true);\n\n onLangChange: Observable<LangChangeEvent> = this.onLangChangeSubject.asObservable();\n onTranslationChange: Observable<string> = this.onTranslationChangeSubject.asObservable();\n onFallbackLangChange: Observable<string> = this.onFallbackLangChangeSubject.asObservable();\n isLoaded: Observable<boolean> = this.isLoadedSubject.asObservable();\n\n currentLang = signal<string | null>(null);\n\n languages: string[] = [DEFAULT_LANGUAGE];\n\n get(content: string): Observable<string> {\n return of(TRANSLATED_STRING + content);\n }\n\n use(lang: string): void {\n this.currentLang.set(lang);\n this.onLangChangeSubject.next({ lang } as LangChangeEvent);\n }\n\n addLangs(langs: string[]): void {\n this.languages = [...this.languages, ...langs];\n }\n\n getBrowserLang(): string {\n return DEFAULT_LANGUAGE;\n }\n\n getLangs(): string[] {\n return this.languages;\n }\n\n // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getTranslation(): Observable<any> {\n return of({});\n }\n\n instant(key: string | string[]): string {\n return TRANSLATED_STRING + key.toString();\n }\n\n setFallbackLang(lang: string): void {\n this.onFallbackLangChangeSubject.next(lang);\n }\n}\n\n@Pipe({ name: 'translate' })\nexport class TranslateMockPipe implements PipeTransform {\n transform(text: string): string {\n return !text ? TRANSLATED_STRING : `${text}-${TRANSLATED_STRING}`;\n }\n}\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[translate]',\n})\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class TranslateMockDirective implements AfterViewChecked {\n readonly translateParams = input();\n\n private readonly _element = inject(ElementRef);\n\n ngAfterViewChecked(): void {\n this._element.nativeElement.innerText += TRANSLATED_STRING;\n }\n}\n\nexport class TranslateLoaderMock implements TranslateLoader {\n getTranslation(): Observable<Record<string, string>> {\n return of({});\n }\n}\n\n@NgModule({\n imports: [TranslateMockPipe, TranslateMockDirective],\n exports: [TranslateMockPipe, TranslateMockDirective],\n providers: [\n { provide: TranslateService, useClass: TranslateServiceMock },\n { provide: TranslateLoader, useClass: TranslateLoaderMock },\n ],\n})\nexport class TranslateMockModule {}\n",
|
|
19728
19728
|
"displayName": "TranslateServiceMock",
|
|
19729
19729
|
"inputsClass": [],
|
|
19730
19730
|
"outputsClass": [],
|
|
@@ -19739,7 +19739,7 @@
|
|
|
19739
19739
|
"indexKey": "",
|
|
19740
19740
|
"optional": false,
|
|
19741
19741
|
"description": "",
|
|
19742
|
-
"line":
|
|
19742
|
+
"line": 32,
|
|
19743
19743
|
"rawdescription": "\n"
|
|
19744
19744
|
},
|
|
19745
19745
|
{
|
|
@@ -19752,7 +19752,7 @@
|
|
|
19752
19752
|
"indexKey": "",
|
|
19753
19753
|
"optional": false,
|
|
19754
19754
|
"description": "",
|
|
19755
|
-
"line":
|
|
19755
|
+
"line": 30,
|
|
19756
19756
|
"rawdescription": "\n"
|
|
19757
19757
|
},
|
|
19758
19758
|
{
|
|
@@ -19765,7 +19765,7 @@
|
|
|
19765
19765
|
"indexKey": "",
|
|
19766
19766
|
"optional": false,
|
|
19767
19767
|
"description": "",
|
|
19768
|
-
"line":
|
|
19768
|
+
"line": 25,
|
|
19769
19769
|
"rawdescription": "\n"
|
|
19770
19770
|
},
|
|
19771
19771
|
{
|
|
@@ -19778,7 +19778,7 @@
|
|
|
19778
19778
|
"indexKey": "",
|
|
19779
19779
|
"optional": false,
|
|
19780
19780
|
"description": "",
|
|
19781
|
-
"line":
|
|
19781
|
+
"line": 34,
|
|
19782
19782
|
"rawdescription": "\n"
|
|
19783
19783
|
},
|
|
19784
19784
|
{
|
|
@@ -19791,7 +19791,7 @@
|
|
|
19791
19791
|
"indexKey": "",
|
|
19792
19792
|
"optional": false,
|
|
19793
19793
|
"description": "",
|
|
19794
|
-
"line":
|
|
19794
|
+
"line": 29,
|
|
19795
19795
|
"rawdescription": "\n"
|
|
19796
19796
|
},
|
|
19797
19797
|
{
|
|
@@ -19804,7 +19804,7 @@
|
|
|
19804
19804
|
"indexKey": "",
|
|
19805
19805
|
"optional": false,
|
|
19806
19806
|
"description": "",
|
|
19807
|
-
"line":
|
|
19807
|
+
"line": 24,
|
|
19808
19808
|
"rawdescription": "\n"
|
|
19809
19809
|
},
|
|
19810
19810
|
{
|
|
@@ -19817,7 +19817,7 @@
|
|
|
19817
19817
|
"indexKey": "",
|
|
19818
19818
|
"optional": false,
|
|
19819
19819
|
"description": "",
|
|
19820
|
-
"line":
|
|
19820
|
+
"line": 27,
|
|
19821
19821
|
"rawdescription": "\n"
|
|
19822
19822
|
},
|
|
19823
19823
|
{
|
|
@@ -19830,7 +19830,7 @@
|
|
|
19830
19830
|
"indexKey": "",
|
|
19831
19831
|
"optional": false,
|
|
19832
19832
|
"description": "",
|
|
19833
|
-
"line":
|
|
19833
|
+
"line": 22,
|
|
19834
19834
|
"rawdescription": "\n"
|
|
19835
19835
|
},
|
|
19836
19836
|
{
|
|
@@ -19843,7 +19843,7 @@
|
|
|
19843
19843
|
"indexKey": "",
|
|
19844
19844
|
"optional": false,
|
|
19845
19845
|
"description": "",
|
|
19846
|
-
"line":
|
|
19846
|
+
"line": 28,
|
|
19847
19847
|
"rawdescription": "\n"
|
|
19848
19848
|
},
|
|
19849
19849
|
{
|
|
@@ -19856,7 +19856,7 @@
|
|
|
19856
19856
|
"indexKey": "",
|
|
19857
19857
|
"optional": false,
|
|
19858
19858
|
"description": "",
|
|
19859
|
-
"line":
|
|
19859
|
+
"line": 23,
|
|
19860
19860
|
"rawdescription": "\n"
|
|
19861
19861
|
}
|
|
19862
19862
|
],
|
|
@@ -19877,7 +19877,7 @@
|
|
|
19877
19877
|
"optional": false,
|
|
19878
19878
|
"returnType": "void",
|
|
19879
19879
|
"typeParameters": [],
|
|
19880
|
-
"line":
|
|
19880
|
+
"line": 45,
|
|
19881
19881
|
"deprecated": false,
|
|
19882
19882
|
"deprecationMessage": "",
|
|
19883
19883
|
"rawdescription": "\n",
|
|
@@ -19912,7 +19912,7 @@
|
|
|
19912
19912
|
"optional": false,
|
|
19913
19913
|
"returnType": "Observable<string>",
|
|
19914
19914
|
"typeParameters": [],
|
|
19915
|
-
"line":
|
|
19915
|
+
"line": 36,
|
|
19916
19916
|
"deprecated": false,
|
|
19917
19917
|
"deprecationMessage": "",
|
|
19918
19918
|
"rawdescription": "\n",
|
|
@@ -19938,7 +19938,7 @@
|
|
|
19938
19938
|
"optional": false,
|
|
19939
19939
|
"returnType": "string",
|
|
19940
19940
|
"typeParameters": [],
|
|
19941
|
-
"line":
|
|
19941
|
+
"line": 49,
|
|
19942
19942
|
"deprecated": false,
|
|
19943
19943
|
"deprecationMessage": "",
|
|
19944
19944
|
"rawdescription": "\n",
|
|
@@ -19951,7 +19951,7 @@
|
|
|
19951
19951
|
"optional": false,
|
|
19952
19952
|
"returnType": "string[]",
|
|
19953
19953
|
"typeParameters": [],
|
|
19954
|
-
"line":
|
|
19954
|
+
"line": 53,
|
|
19955
19955
|
"deprecated": false,
|
|
19956
19956
|
"deprecationMessage": "",
|
|
19957
19957
|
"rawdescription": "\n",
|
|
@@ -19964,7 +19964,7 @@
|
|
|
19964
19964
|
"optional": false,
|
|
19965
19965
|
"returnType": "Observable<any>",
|
|
19966
19966
|
"typeParameters": [],
|
|
19967
|
-
"line":
|
|
19967
|
+
"line": 59,
|
|
19968
19968
|
"deprecated": false,
|
|
19969
19969
|
"deprecationMessage": "",
|
|
19970
19970
|
"rawdescription": "\n",
|
|
@@ -19986,7 +19986,7 @@
|
|
|
19986
19986
|
"optional": false,
|
|
19987
19987
|
"returnType": "string",
|
|
19988
19988
|
"typeParameters": [],
|
|
19989
|
-
"line":
|
|
19989
|
+
"line": 63,
|
|
19990
19990
|
"deprecated": false,
|
|
19991
19991
|
"deprecationMessage": "",
|
|
19992
19992
|
"rawdescription": "\n",
|
|
@@ -20021,7 +20021,7 @@
|
|
|
20021
20021
|
"optional": false,
|
|
20022
20022
|
"returnType": "void",
|
|
20023
20023
|
"typeParameters": [],
|
|
20024
|
-
"line":
|
|
20024
|
+
"line": 67,
|
|
20025
20025
|
"deprecated": false,
|
|
20026
20026
|
"deprecationMessage": "",
|
|
20027
20027
|
"rawdescription": "\n",
|
|
@@ -20056,7 +20056,7 @@
|
|
|
20056
20056
|
"optional": false,
|
|
20057
20057
|
"returnType": "void",
|
|
20058
20058
|
"typeParameters": [],
|
|
20059
|
-
"line":
|
|
20059
|
+
"line": 40,
|
|
20060
20060
|
"deprecated": false,
|
|
20061
20061
|
"deprecationMessage": "",
|
|
20062
20062
|
"rawdescription": "\n",
|
|
@@ -21181,27 +21181,31 @@
|
|
|
21181
21181
|
"directives": [
|
|
21182
21182
|
{
|
|
21183
21183
|
"name": "TranslateMockDirective",
|
|
21184
|
-
"id": "directive-TranslateMockDirective-
|
|
21184
|
+
"id": "directive-TranslateMockDirective-d42afa990d476989657d92ef3f9c88346ef461191fc8641719f83d538694483a6f785c8618d8ee729faee7c37e723a1fdfcac95badfa6e5259f869ebe95cccad",
|
|
21185
21185
|
"file": "packages/core/src/lib/mocks/translate.module.mock.ts",
|
|
21186
21186
|
"type": "directive",
|
|
21187
21187
|
"description": "",
|
|
21188
21188
|
"rawdescription": "\n",
|
|
21189
|
-
"sourceCode": "import {
|
|
21189
|
+
"sourceCode": "import {\n AfterViewChecked,\n Directive,\n ElementRef,\n Input,\n NgModule,\n Pipe,\n PipeTransform,\n inject,\n signal,\n input,\n} from '@angular/core';\nimport { LangChangeEvent, TranslateLoader, TranslateService } from '@ngx-translate/core';\nimport { BehaviorSubject, Observable, of, Subject } from 'rxjs';\n\nexport const TRANSLATED_STRING = 'i18n';\nexport const DEFAULT_LANGUAGE = 'en';\n\nexport class TranslateServiceMock {\n onLangChangeSubject: Subject<LangChangeEvent> = new Subject();\n onTranslationChangeSubject: Subject<string> = new Subject();\n onFallbackLangChangeSubject: Subject<string> = new Subject();\n isLoadedSubject: BehaviorSubject<boolean> = new BehaviorSubject(true);\n\n onLangChange: Observable<LangChangeEvent> = this.onLangChangeSubject.asObservable();\n onTranslationChange: Observable<string> = this.onTranslationChangeSubject.asObservable();\n onFallbackLangChange: Observable<string> = this.onFallbackLangChangeSubject.asObservable();\n isLoaded: Observable<boolean> = this.isLoadedSubject.asObservable();\n\n currentLang = signal<string | null>(null);\n\n languages: string[] = [DEFAULT_LANGUAGE];\n\n get(content: string): Observable<string> {\n return of(TRANSLATED_STRING + content);\n }\n\n use(lang: string): void {\n this.currentLang.set(lang);\n this.onLangChangeSubject.next({ lang } as LangChangeEvent);\n }\n\n addLangs(langs: string[]): void {\n this.languages = [...this.languages, ...langs];\n }\n\n getBrowserLang(): string {\n return DEFAULT_LANGUAGE;\n }\n\n getLangs(): string[] {\n return this.languages;\n }\n\n // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getTranslation(): Observable<any> {\n return of({});\n }\n\n instant(key: string | string[]): string {\n return TRANSLATED_STRING + key.toString();\n }\n\n setFallbackLang(lang: string): void {\n this.onFallbackLangChangeSubject.next(lang);\n }\n}\n\n@Pipe({ name: 'translate' })\nexport class TranslateMockPipe implements PipeTransform {\n transform(text: string): string {\n return !text ? TRANSLATED_STRING : `${text}-${TRANSLATED_STRING}`;\n }\n}\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[translate]',\n})\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class TranslateMockDirective implements AfterViewChecked {\n readonly translateParams = input();\n\n private readonly _element = inject(ElementRef);\n\n ngAfterViewChecked(): void {\n this._element.nativeElement.innerText += TRANSLATED_STRING;\n }\n}\n\nexport class TranslateLoaderMock implements TranslateLoader {\n getTranslation(): Observable<Record<string, string>> {\n return of({});\n }\n}\n\n@NgModule({\n imports: [TranslateMockPipe, TranslateMockDirective],\n exports: [TranslateMockPipe, TranslateMockDirective],\n providers: [\n { provide: TranslateService, useClass: TranslateServiceMock },\n { provide: TranslateLoader, useClass: TranslateLoaderMock },\n ],\n})\nexport class TranslateMockModule {}\n",
|
|
21190
21190
|
"selector": "[translate]",
|
|
21191
21191
|
"providers": [],
|
|
21192
21192
|
"hostDirectives": [],
|
|
21193
21193
|
"standalone": false,
|
|
21194
21194
|
"inputsClass": [
|
|
21195
21195
|
{
|
|
21196
|
-
"coverageIgnore": false,
|
|
21197
21196
|
"name": "translateParams",
|
|
21197
|
+
"coverageIgnore": false,
|
|
21198
21198
|
"deprecated": false,
|
|
21199
21199
|
"deprecationMessage": "",
|
|
21200
|
-
"
|
|
21200
|
+
"indexKey": "",
|
|
21201
|
+
"optional": false,
|
|
21201
21202
|
"description": "",
|
|
21202
|
-
"line":
|
|
21203
|
-
"
|
|
21204
|
-
"
|
|
21203
|
+
"line": 85,
|
|
21204
|
+
"rawdescription": "\n",
|
|
21205
|
+
"modifierKind": [
|
|
21206
|
+
148
|
|
21207
|
+
],
|
|
21208
|
+
"required": false
|
|
21205
21209
|
}
|
|
21206
21210
|
],
|
|
21207
21211
|
"outputsClass": [],
|
|
@@ -21218,7 +21222,7 @@
|
|
|
21218
21222
|
"optional": false,
|
|
21219
21223
|
"returnType": "void",
|
|
21220
21224
|
"typeParameters": [],
|
|
21221
|
-
"line":
|
|
21225
|
+
"line": 89,
|
|
21222
21226
|
"deprecated": false,
|
|
21223
21227
|
"deprecationMessage": "",
|
|
21224
21228
|
"rawdescription": "\n",
|
|
@@ -22068,13 +22072,13 @@
|
|
|
22068
22072
|
},
|
|
22069
22073
|
{
|
|
22070
22074
|
"name": "TranslateMockModule",
|
|
22071
|
-
"id": "module-TranslateMockModule-
|
|
22075
|
+
"id": "module-TranslateMockModule-d42afa990d476989657d92ef3f9c88346ef461191fc8641719f83d538694483a6f785c8618d8ee729faee7c37e723a1fdfcac95badfa6e5259f869ebe95cccad",
|
|
22072
22076
|
"description": "",
|
|
22073
22077
|
"deprecationMessage": "",
|
|
22074
22078
|
"deprecated": false,
|
|
22075
22079
|
"file": "packages/core/src/lib/mocks/translate.module.mock.ts",
|
|
22076
22080
|
"methods": [],
|
|
22077
|
-
"sourceCode": "/* istanbul ignore file */\n\nimport {
|
|
22081
|
+
"sourceCode": "/* istanbul ignore file */\n\nimport {\n AfterViewChecked,\n Directive,\n ElementRef,\n Input,\n NgModule,\n Pipe,\n PipeTransform,\n inject,\n signal,\n input,\n} from '@angular/core';\nimport { LangChangeEvent, TranslateLoader, TranslateService } from '@ngx-translate/core';\nimport { BehaviorSubject, Observable, of, Subject } from 'rxjs';\n\nexport const TRANSLATED_STRING = 'i18n';\nexport const DEFAULT_LANGUAGE = 'en';\n\nexport class TranslateServiceMock {\n onLangChangeSubject: Subject<LangChangeEvent> = new Subject();\n onTranslationChangeSubject: Subject<string> = new Subject();\n onFallbackLangChangeSubject: Subject<string> = new Subject();\n isLoadedSubject: BehaviorSubject<boolean> = new BehaviorSubject(true);\n\n onLangChange: Observable<LangChangeEvent> = this.onLangChangeSubject.asObservable();\n onTranslationChange: Observable<string> = this.onTranslationChangeSubject.asObservable();\n onFallbackLangChange: Observable<string> = this.onFallbackLangChangeSubject.asObservable();\n isLoaded: Observable<boolean> = this.isLoadedSubject.asObservable();\n\n currentLang = signal<string | null>(null);\n\n languages: string[] = [DEFAULT_LANGUAGE];\n\n get(content: string): Observable<string> {\n return of(TRANSLATED_STRING + content);\n }\n\n use(lang: string): void {\n this.currentLang.set(lang);\n this.onLangChangeSubject.next({ lang } as LangChangeEvent);\n }\n\n addLangs(langs: string[]): void {\n this.languages = [...this.languages, ...langs];\n }\n\n getBrowserLang(): string {\n return DEFAULT_LANGUAGE;\n }\n\n getLangs(): string[] {\n return this.languages;\n }\n\n // TODO: find the correct type or turn into a generic, https://www.typescriptlang.org/docs/handbook/2/generics.html\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getTranslation(): Observable<any> {\n return of({});\n }\n\n instant(key: string | string[]): string {\n return TRANSLATED_STRING + key.toString();\n }\n\n setFallbackLang(lang: string): void {\n this.onFallbackLangChangeSubject.next(lang);\n }\n}\n\n@Pipe({ name: 'translate' })\nexport class TranslateMockPipe implements PipeTransform {\n transform(text: string): string {\n return !text ? TRANSLATED_STRING : `${text}-${TRANSLATED_STRING}`;\n }\n}\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[translate]',\n})\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport class TranslateMockDirective implements AfterViewChecked {\n readonly translateParams = input();\n\n private readonly _element = inject(ElementRef);\n\n ngAfterViewChecked(): void {\n this._element.nativeElement.innerText += TRANSLATED_STRING;\n }\n}\n\nexport class TranslateLoaderMock implements TranslateLoader {\n getTranslation(): Observable<Record<string, string>> {\n return of({});\n }\n}\n\n@NgModule({\n imports: [TranslateMockPipe, TranslateMockDirective],\n exports: [TranslateMockPipe, TranslateMockDirective],\n providers: [\n { provide: TranslateService, useClass: TranslateServiceMock },\n { provide: TranslateLoader, useClass: TranslateLoaderMock },\n ],\n})\nexport class TranslateMockModule {}\n",
|
|
22078
22082
|
"children": [
|
|
22079
22083
|
{
|
|
22080
22084
|
"type": "providers",
|
|
@@ -22310,23 +22314,23 @@
|
|
|
22310
22314
|
"name": "COMPONENT_TAG",
|
|
22311
22315
|
"ctype": "miscellaneous",
|
|
22312
22316
|
"subtype": "variable",
|
|
22313
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
22317
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
22314
22318
|
"coverageIgnore": false,
|
|
22315
22319
|
"deprecated": false,
|
|
22316
22320
|
"deprecationMessage": "",
|
|
22317
22321
|
"type": "string",
|
|
22318
|
-
"defaultValue": "'eui-
|
|
22322
|
+
"defaultValue": "'eui-fieldset'"
|
|
22319
22323
|
},
|
|
22320
22324
|
{
|
|
22321
22325
|
"name": "COMPONENT_TAG",
|
|
22322
22326
|
"ctype": "miscellaneous",
|
|
22323
22327
|
"subtype": "variable",
|
|
22324
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
22328
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
22325
22329
|
"coverageIgnore": false,
|
|
22326
22330
|
"deprecated": false,
|
|
22327
22331
|
"deprecationMessage": "",
|
|
22328
22332
|
"type": "string",
|
|
22329
|
-
"defaultValue": "'eui-
|
|
22333
|
+
"defaultValue": "'eui-icon-svg'"
|
|
22330
22334
|
},
|
|
22331
22335
|
{
|
|
22332
22336
|
"name": "COMPONENT_TAG",
|
|
@@ -23589,23 +23593,23 @@
|
|
|
23589
23593
|
"name": "REMOVED_INPUTS",
|
|
23590
23594
|
"ctype": "miscellaneous",
|
|
23591
23595
|
"subtype": "variable",
|
|
23592
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
23596
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
23593
23597
|
"coverageIgnore": false,
|
|
23594
23598
|
"deprecated": false,
|
|
23595
23599
|
"deprecationMessage": "",
|
|
23596
23600
|
"type": "unknown",
|
|
23597
|
-
"defaultValue": "new Set(['
|
|
23601
|
+
"defaultValue": "new Set(['isSquared'])"
|
|
23598
23602
|
},
|
|
23599
23603
|
{
|
|
23600
23604
|
"name": "REMOVED_INPUTS",
|
|
23601
23605
|
"ctype": "miscellaneous",
|
|
23602
23606
|
"subtype": "variable",
|
|
23603
|
-
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
23607
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
23604
23608
|
"coverageIgnore": false,
|
|
23605
23609
|
"deprecated": false,
|
|
23606
23610
|
"deprecationMessage": "",
|
|
23607
23611
|
"type": "unknown",
|
|
23608
|
-
"defaultValue": "new Set(['
|
|
23612
|
+
"defaultValue": "new Set(['maxVisibleChipsCount', 'isMaxVisibleChipsOpened', 'toggleLinkMoreLabel', 'toggleLinkLessLabel', 'isChipsSorted', 'chipsSortOrder'])"
|
|
23609
23613
|
},
|
|
23610
23614
|
{
|
|
23611
23615
|
"name": "REMOVED_INPUTS",
|
|
@@ -24559,7 +24563,7 @@
|
|
|
24559
24563
|
},
|
|
24560
24564
|
{
|
|
24561
24565
|
"name": "applyEdits",
|
|
24562
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24566
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
24563
24567
|
"ctype": "miscellaneous",
|
|
24564
24568
|
"subtype": "function",
|
|
24565
24569
|
"coverageIgnore": false,
|
|
@@ -24604,7 +24608,7 @@
|
|
|
24604
24608
|
},
|
|
24605
24609
|
{
|
|
24606
24610
|
"name": "applyEdits",
|
|
24607
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24611
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
24608
24612
|
"ctype": "miscellaneous",
|
|
24609
24613
|
"subtype": "function",
|
|
24610
24614
|
"coverageIgnore": false,
|
|
@@ -24739,7 +24743,7 @@
|
|
|
24739
24743
|
},
|
|
24740
24744
|
{
|
|
24741
24745
|
"name": "applyEdits",
|
|
24742
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24746
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
24743
24747
|
"ctype": "miscellaneous",
|
|
24744
24748
|
"subtype": "function",
|
|
24745
24749
|
"coverageIgnore": false,
|
|
@@ -24784,7 +24788,7 @@
|
|
|
24784
24788
|
},
|
|
24785
24789
|
{
|
|
24786
24790
|
"name": "applyEdits",
|
|
24787
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
24791
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
24788
24792
|
"ctype": "miscellaneous",
|
|
24789
24793
|
"subtype": "function",
|
|
24790
24794
|
"coverageIgnore": false,
|
|
@@ -26036,7 +26040,7 @@
|
|
|
26036
26040
|
},
|
|
26037
26041
|
{
|
|
26038
26042
|
"name": "collectRemovals",
|
|
26039
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26043
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
26040
26044
|
"ctype": "miscellaneous",
|
|
26041
26045
|
"subtype": "function",
|
|
26042
26046
|
"coverageIgnore": false,
|
|
@@ -26052,12 +26056,6 @@
|
|
|
26052
26056
|
"deprecated": false,
|
|
26053
26057
|
"deprecationMessage": ""
|
|
26054
26058
|
},
|
|
26055
|
-
{
|
|
26056
|
-
"name": "source",
|
|
26057
|
-
"type": "string",
|
|
26058
|
-
"deprecated": false,
|
|
26059
|
-
"deprecationMessage": ""
|
|
26060
|
-
},
|
|
26061
26059
|
{
|
|
26062
26060
|
"name": "removals",
|
|
26063
26061
|
"deprecated": false,
|
|
@@ -26075,15 +26073,6 @@
|
|
|
26075
26073
|
"text": "param"
|
|
26076
26074
|
}
|
|
26077
26075
|
},
|
|
26078
|
-
{
|
|
26079
|
-
"name": "source",
|
|
26080
|
-
"type": "string",
|
|
26081
|
-
"deprecated": false,
|
|
26082
|
-
"deprecationMessage": "",
|
|
26083
|
-
"tagName": {
|
|
26084
|
-
"text": "param"
|
|
26085
|
-
}
|
|
26086
|
-
},
|
|
26087
26076
|
{
|
|
26088
26077
|
"name": "removals",
|
|
26089
26078
|
"deprecated": false,
|
|
@@ -26096,7 +26085,7 @@
|
|
|
26096
26085
|
},
|
|
26097
26086
|
{
|
|
26098
26087
|
"name": "collectRemovals",
|
|
26099
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26088
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
26100
26089
|
"ctype": "miscellaneous",
|
|
26101
26090
|
"subtype": "function",
|
|
26102
26091
|
"coverageIgnore": false,
|
|
@@ -26112,6 +26101,12 @@
|
|
|
26112
26101
|
"deprecated": false,
|
|
26113
26102
|
"deprecationMessage": ""
|
|
26114
26103
|
},
|
|
26104
|
+
{
|
|
26105
|
+
"name": "source",
|
|
26106
|
+
"type": "string",
|
|
26107
|
+
"deprecated": false,
|
|
26108
|
+
"deprecationMessage": ""
|
|
26109
|
+
},
|
|
26115
26110
|
{
|
|
26116
26111
|
"name": "removals",
|
|
26117
26112
|
"deprecated": false,
|
|
@@ -26129,6 +26124,15 @@
|
|
|
26129
26124
|
"text": "param"
|
|
26130
26125
|
}
|
|
26131
26126
|
},
|
|
26127
|
+
{
|
|
26128
|
+
"name": "source",
|
|
26129
|
+
"type": "string",
|
|
26130
|
+
"deprecated": false,
|
|
26131
|
+
"deprecationMessage": "",
|
|
26132
|
+
"tagName": {
|
|
26133
|
+
"text": "param"
|
|
26134
|
+
}
|
|
26135
|
+
},
|
|
26132
26136
|
{
|
|
26133
26137
|
"name": "removals",
|
|
26134
26138
|
"deprecated": false,
|
|
@@ -26321,7 +26325,7 @@
|
|
|
26321
26325
|
},
|
|
26322
26326
|
{
|
|
26323
26327
|
"name": "collectRenames",
|
|
26324
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26328
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
26325
26329
|
"ctype": "miscellaneous",
|
|
26326
26330
|
"subtype": "function",
|
|
26327
26331
|
"coverageIgnore": false,
|
|
@@ -26366,7 +26370,7 @@
|
|
|
26366
26370
|
},
|
|
26367
26371
|
{
|
|
26368
26372
|
"name": "collectRenames",
|
|
26369
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
26373
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
26370
26374
|
"ctype": "miscellaneous",
|
|
26371
26375
|
"subtype": "function",
|
|
26372
26376
|
"coverageIgnore": false,
|
|
@@ -29750,7 +29754,7 @@
|
|
|
29750
29754
|
},
|
|
29751
29755
|
{
|
|
29752
29756
|
"name": "isChipElement",
|
|
29753
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
29757
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
29754
29758
|
"ctype": "miscellaneous",
|
|
29755
29759
|
"subtype": "function",
|
|
29756
29760
|
"coverageIgnore": false,
|
|
@@ -29782,7 +29786,7 @@
|
|
|
29782
29786
|
},
|
|
29783
29787
|
{
|
|
29784
29788
|
"name": "isChipElement",
|
|
29785
|
-
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
29789
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
29786
29790
|
"ctype": "miscellaneous",
|
|
29787
29791
|
"subtype": "function",
|
|
29788
29792
|
"coverageIgnore": false,
|
|
@@ -29966,7 +29970,7 @@
|
|
|
29966
29970
|
},
|
|
29967
29971
|
{
|
|
29968
29972
|
"name": "isComponentMetadataProperty",
|
|
29969
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
29973
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
29970
29974
|
"ctype": "miscellaneous",
|
|
29971
29975
|
"subtype": "function",
|
|
29972
29976
|
"coverageIgnore": false,
|
|
@@ -29996,7 +30000,7 @@
|
|
|
29996
30000
|
},
|
|
29997
30001
|
{
|
|
29998
30002
|
"name": "isComponentMetadataProperty",
|
|
29999
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30003
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
30000
30004
|
"ctype": "miscellaneous",
|
|
30001
30005
|
"subtype": "function",
|
|
30002
30006
|
"coverageIgnore": false,
|
|
@@ -30056,7 +30060,7 @@
|
|
|
30056
30060
|
},
|
|
30057
30061
|
{
|
|
30058
30062
|
"name": "isComponentMetadataProperty",
|
|
30059
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30063
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
30060
30064
|
"ctype": "miscellaneous",
|
|
30061
30065
|
"subtype": "function",
|
|
30062
30066
|
"coverageIgnore": false,
|
|
@@ -30086,7 +30090,7 @@
|
|
|
30086
30090
|
},
|
|
30087
30091
|
{
|
|
30088
30092
|
"name": "isComponentMetadataProperty",
|
|
30089
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30093
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
30090
30094
|
"ctype": "miscellaneous",
|
|
30091
30095
|
"subtype": "function",
|
|
30092
30096
|
"coverageIgnore": false,
|
|
@@ -30116,7 +30120,7 @@
|
|
|
30116
30120
|
},
|
|
30117
30121
|
{
|
|
30118
30122
|
"name": "isComponentMetadataProperty",
|
|
30119
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30123
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
30120
30124
|
"ctype": "miscellaneous",
|
|
30121
30125
|
"subtype": "function",
|
|
30122
30126
|
"coverageIgnore": false,
|
|
@@ -30146,7 +30150,7 @@
|
|
|
30146
30150
|
},
|
|
30147
30151
|
{
|
|
30148
30152
|
"name": "isComponentMetadataProperty",
|
|
30149
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30153
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
30150
30154
|
"ctype": "miscellaneous",
|
|
30151
30155
|
"subtype": "function",
|
|
30152
30156
|
"coverageIgnore": false,
|
|
@@ -30511,7 +30515,7 @@
|
|
|
30511
30515
|
},
|
|
30512
30516
|
{
|
|
30513
30517
|
"name": "isTemplateProperty",
|
|
30514
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30518
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
30515
30519
|
"ctype": "miscellaneous",
|
|
30516
30520
|
"subtype": "function",
|
|
30517
30521
|
"coverageIgnore": false,
|
|
@@ -30541,7 +30545,7 @@
|
|
|
30541
30545
|
},
|
|
30542
30546
|
{
|
|
30543
30547
|
"name": "isTemplateProperty",
|
|
30544
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30548
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
30545
30549
|
"ctype": "miscellaneous",
|
|
30546
30550
|
"subtype": "function",
|
|
30547
30551
|
"coverageIgnore": false,
|
|
@@ -30601,7 +30605,7 @@
|
|
|
30601
30605
|
},
|
|
30602
30606
|
{
|
|
30603
30607
|
"name": "isTemplateProperty",
|
|
30604
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30608
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
30605
30609
|
"ctype": "miscellaneous",
|
|
30606
30610
|
"subtype": "function",
|
|
30607
30611
|
"coverageIgnore": false,
|
|
@@ -30631,7 +30635,7 @@
|
|
|
30631
30635
|
},
|
|
30632
30636
|
{
|
|
30633
30637
|
"name": "isTemplateProperty",
|
|
30634
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30638
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
30635
30639
|
"ctype": "miscellaneous",
|
|
30636
30640
|
"subtype": "function",
|
|
30637
30641
|
"coverageIgnore": false,
|
|
@@ -30661,7 +30665,7 @@
|
|
|
30661
30665
|
},
|
|
30662
30666
|
{
|
|
30663
30667
|
"name": "isTemplateProperty",
|
|
30664
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30668
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
30665
30669
|
"ctype": "miscellaneous",
|
|
30666
30670
|
"subtype": "function",
|
|
30667
30671
|
"coverageIgnore": false,
|
|
@@ -30691,7 +30695,7 @@
|
|
|
30691
30695
|
},
|
|
30692
30696
|
{
|
|
30693
30697
|
"name": "isTemplateProperty",
|
|
30694
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
30698
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
30695
30699
|
"ctype": "miscellaneous",
|
|
30696
30700
|
"subtype": "function",
|
|
30697
30701
|
"coverageIgnore": false,
|
|
@@ -32349,6 +32353,38 @@
|
|
|
32349
32353
|
}
|
|
32350
32354
|
]
|
|
32351
32355
|
},
|
|
32356
|
+
{
|
|
32357
|
+
"name": "migrateInlineTemplates",
|
|
32358
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
32359
|
+
"ctype": "miscellaneous",
|
|
32360
|
+
"subtype": "function",
|
|
32361
|
+
"coverageIgnore": false,
|
|
32362
|
+
"deprecated": false,
|
|
32363
|
+
"deprecationMessage": "",
|
|
32364
|
+
"rawdescription": "",
|
|
32365
|
+
"description": "",
|
|
32366
|
+
"displayName": "migrateInlineTemplates",
|
|
32367
|
+
"args": [
|
|
32368
|
+
{
|
|
32369
|
+
"name": "source",
|
|
32370
|
+
"type": "string",
|
|
32371
|
+
"deprecated": false,
|
|
32372
|
+
"deprecationMessage": ""
|
|
32373
|
+
}
|
|
32374
|
+
],
|
|
32375
|
+
"returnType": "string",
|
|
32376
|
+
"jsdoctags": [
|
|
32377
|
+
{
|
|
32378
|
+
"name": "source",
|
|
32379
|
+
"type": "string",
|
|
32380
|
+
"deprecated": false,
|
|
32381
|
+
"deprecationMessage": "",
|
|
32382
|
+
"tagName": {
|
|
32383
|
+
"text": "param"
|
|
32384
|
+
}
|
|
32385
|
+
}
|
|
32386
|
+
]
|
|
32387
|
+
},
|
|
32352
32388
|
{
|
|
32353
32389
|
"name": "migrateInlineTemplates",
|
|
32354
32390
|
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
@@ -32415,7 +32451,7 @@
|
|
|
32415
32451
|
},
|
|
32416
32452
|
{
|
|
32417
32453
|
"name": "migrateInlineTemplates",
|
|
32418
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32454
|
+
"file": "packages/core/schematics/migrate-eui-editor/index.ts",
|
|
32419
32455
|
"ctype": "miscellaneous",
|
|
32420
32456
|
"subtype": "function",
|
|
32421
32457
|
"coverageIgnore": false,
|
|
@@ -32447,7 +32483,7 @@
|
|
|
32447
32483
|
},
|
|
32448
32484
|
{
|
|
32449
32485
|
"name": "migrateInlineTemplates",
|
|
32450
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32486
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
32451
32487
|
"ctype": "miscellaneous",
|
|
32452
32488
|
"subtype": "function",
|
|
32453
32489
|
"coverageIgnore": false,
|
|
@@ -32511,7 +32547,7 @@
|
|
|
32511
32547
|
},
|
|
32512
32548
|
{
|
|
32513
32549
|
"name": "migrateInlineTemplates",
|
|
32514
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32550
|
+
"file": "packages/core/schematics/migrate-eui-icon-toggle/index.ts",
|
|
32515
32551
|
"ctype": "miscellaneous",
|
|
32516
32552
|
"subtype": "function",
|
|
32517
32553
|
"coverageIgnore": false,
|
|
@@ -32543,7 +32579,7 @@
|
|
|
32543
32579
|
},
|
|
32544
32580
|
{
|
|
32545
32581
|
"name": "migrateInlineTemplates",
|
|
32546
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32582
|
+
"file": "packages/core/schematics/migrate-eui-popover/index.ts",
|
|
32547
32583
|
"ctype": "miscellaneous",
|
|
32548
32584
|
"subtype": "function",
|
|
32549
32585
|
"coverageIgnore": false,
|
|
@@ -32575,7 +32611,7 @@
|
|
|
32575
32611
|
},
|
|
32576
32612
|
{
|
|
32577
32613
|
"name": "migrateInlineTemplates",
|
|
32578
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32614
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
32579
32615
|
"ctype": "miscellaneous",
|
|
32580
32616
|
"subtype": "function",
|
|
32581
32617
|
"coverageIgnore": false,
|
|
@@ -32667,38 +32703,6 @@
|
|
|
32667
32703
|
}
|
|
32668
32704
|
]
|
|
32669
32705
|
},
|
|
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
32706
|
{
|
|
32703
32707
|
"name": "migrateInlineTemplates",
|
|
32704
32708
|
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
@@ -32891,7 +32895,7 @@
|
|
|
32891
32895
|
},
|
|
32892
32896
|
{
|
|
32893
32897
|
"name": "migrateTemplate",
|
|
32894
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
32898
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
32895
32899
|
"ctype": "miscellaneous",
|
|
32896
32900
|
"subtype": "function",
|
|
32897
32901
|
"coverageIgnore": false,
|
|
@@ -32923,7 +32927,7 @@
|
|
|
32923
32927
|
},
|
|
32924
32928
|
{
|
|
32925
32929
|
"name": "migrateTemplate",
|
|
32926
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32930
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
32927
32931
|
"ctype": "miscellaneous",
|
|
32928
32932
|
"subtype": "function",
|
|
32929
32933
|
"coverageIgnore": false,
|
|
@@ -32955,7 +32959,7 @@
|
|
|
32955
32959
|
},
|
|
32956
32960
|
{
|
|
32957
32961
|
"name": "migrateTemplate",
|
|
32958
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
32962
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
32959
32963
|
"ctype": "miscellaneous",
|
|
32960
32964
|
"subtype": "function",
|
|
32961
32965
|
"coverageIgnore": false,
|
|
@@ -33019,7 +33023,7 @@
|
|
|
33019
33023
|
},
|
|
33020
33024
|
{
|
|
33021
33025
|
"name": "migrateTemplate",
|
|
33022
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33026
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
33023
33027
|
"ctype": "miscellaneous",
|
|
33024
33028
|
"subtype": "function",
|
|
33025
33029
|
"coverageIgnore": false,
|
|
@@ -33051,7 +33055,7 @@
|
|
|
33051
33055
|
},
|
|
33052
33056
|
{
|
|
33053
33057
|
"name": "migrateTemplate",
|
|
33054
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33058
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
33055
33059
|
"ctype": "miscellaneous",
|
|
33056
33060
|
"subtype": "function",
|
|
33057
33061
|
"coverageIgnore": false,
|
|
@@ -33147,7 +33151,7 @@
|
|
|
33147
33151
|
},
|
|
33148
33152
|
{
|
|
33149
33153
|
"name": "migrateTemplate",
|
|
33150
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33154
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
33151
33155
|
"ctype": "miscellaneous",
|
|
33152
33156
|
"subtype": "function",
|
|
33153
33157
|
"coverageIgnore": false,
|
|
@@ -33162,21 +33166,9 @@
|
|
|
33162
33166
|
"type": "string",
|
|
33163
33167
|
"deprecated": false,
|
|
33164
33168
|
"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
33169
|
}
|
|
33178
33170
|
],
|
|
33179
|
-
"returnType": "
|
|
33171
|
+
"returnType": "string",
|
|
33180
33172
|
"jsdoctags": [
|
|
33181
33173
|
{
|
|
33182
33174
|
"name": "source",
|
|
@@ -33186,30 +33178,12 @@
|
|
|
33186
33178
|
"tagName": {
|
|
33187
33179
|
"text": "param"
|
|
33188
33180
|
}
|
|
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
33181
|
}
|
|
33208
33182
|
]
|
|
33209
33183
|
},
|
|
33210
33184
|
{
|
|
33211
33185
|
"name": "migrateTemplate",
|
|
33212
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33186
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
33213
33187
|
"ctype": "miscellaneous",
|
|
33214
33188
|
"subtype": "function",
|
|
33215
33189
|
"coverageIgnore": false,
|
|
@@ -33224,6 +33198,18 @@
|
|
|
33224
33198
|
"type": "string",
|
|
33225
33199
|
"deprecated": false,
|
|
33226
33200
|
"deprecationMessage": ""
|
|
33201
|
+
},
|
|
33202
|
+
{
|
|
33203
|
+
"name": "filePath",
|
|
33204
|
+
"type": "string",
|
|
33205
|
+
"deprecated": false,
|
|
33206
|
+
"deprecationMessage": ""
|
|
33207
|
+
},
|
|
33208
|
+
{
|
|
33209
|
+
"name": "context",
|
|
33210
|
+
"type": "SchematicContext",
|
|
33211
|
+
"deprecated": false,
|
|
33212
|
+
"deprecationMessage": ""
|
|
33227
33213
|
}
|
|
33228
33214
|
],
|
|
33229
33215
|
"returnType": "string",
|
|
@@ -33236,12 +33222,30 @@
|
|
|
33236
33222
|
"tagName": {
|
|
33237
33223
|
"text": "param"
|
|
33238
33224
|
}
|
|
33225
|
+
},
|
|
33226
|
+
{
|
|
33227
|
+
"name": "filePath",
|
|
33228
|
+
"type": "string",
|
|
33229
|
+
"deprecated": false,
|
|
33230
|
+
"deprecationMessage": "",
|
|
33231
|
+
"tagName": {
|
|
33232
|
+
"text": "param"
|
|
33233
|
+
}
|
|
33234
|
+
},
|
|
33235
|
+
{
|
|
33236
|
+
"name": "context",
|
|
33237
|
+
"type": "SchematicContext",
|
|
33238
|
+
"deprecated": false,
|
|
33239
|
+
"deprecationMessage": "",
|
|
33240
|
+
"tagName": {
|
|
33241
|
+
"text": "param"
|
|
33242
|
+
}
|
|
33239
33243
|
}
|
|
33240
33244
|
]
|
|
33241
33245
|
},
|
|
33242
33246
|
{
|
|
33243
33247
|
"name": "migrateTemplate",
|
|
33244
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33248
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
33245
33249
|
"ctype": "miscellaneous",
|
|
33246
33250
|
"subtype": "function",
|
|
33247
33251
|
"coverageIgnore": false,
|
|
@@ -33270,7 +33274,7 @@
|
|
|
33270
33274
|
"deprecationMessage": ""
|
|
33271
33275
|
}
|
|
33272
33276
|
],
|
|
33273
|
-
"returnType": "
|
|
33277
|
+
"returnType": "MigrationResult",
|
|
33274
33278
|
"jsdoctags": [
|
|
33275
33279
|
{
|
|
33276
33280
|
"name": "source",
|
|
@@ -33303,7 +33307,7 @@
|
|
|
33303
33307
|
},
|
|
33304
33308
|
{
|
|
33305
33309
|
"name": "migrateTemplate",
|
|
33306
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33310
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
33307
33311
|
"ctype": "miscellaneous",
|
|
33308
33312
|
"subtype": "function",
|
|
33309
33313
|
"coverageIgnore": false,
|
|
@@ -33495,7 +33499,7 @@
|
|
|
33495
33499
|
},
|
|
33496
33500
|
{
|
|
33497
33501
|
"name": "migrateTypeScript",
|
|
33498
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33502
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
33499
33503
|
"ctype": "miscellaneous",
|
|
33500
33504
|
"subtype": "function",
|
|
33501
33505
|
"coverageIgnore": false,
|
|
@@ -33524,7 +33528,7 @@
|
|
|
33524
33528
|
"deprecationMessage": ""
|
|
33525
33529
|
}
|
|
33526
33530
|
],
|
|
33527
|
-
"returnType": "string",
|
|
33531
|
+
"returnType": "{ output: string; hasPaginator: boolean }",
|
|
33528
33532
|
"jsdoctags": [
|
|
33529
33533
|
{
|
|
33530
33534
|
"name": "source",
|
|
@@ -33557,7 +33561,7 @@
|
|
|
33557
33561
|
},
|
|
33558
33562
|
{
|
|
33559
33563
|
"name": "migrateTypeScript",
|
|
33560
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
33564
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
33561
33565
|
"ctype": "miscellaneous",
|
|
33562
33566
|
"subtype": "function",
|
|
33563
33567
|
"coverageIgnore": false,
|
|
@@ -33586,7 +33590,7 @@
|
|
|
33586
33590
|
"deprecationMessage": ""
|
|
33587
33591
|
}
|
|
33588
33592
|
],
|
|
33589
|
-
"returnType": "
|
|
33593
|
+
"returnType": "string",
|
|
33590
33594
|
"jsdoctags": [
|
|
33591
33595
|
{
|
|
33592
33596
|
"name": "source",
|
|
@@ -35417,7 +35421,7 @@
|
|
|
35417
35421
|
},
|
|
35418
35422
|
{
|
|
35419
35423
|
"name": "unwrapExpression",
|
|
35420
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35424
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
35421
35425
|
"ctype": "miscellaneous",
|
|
35422
35426
|
"subtype": "function",
|
|
35423
35427
|
"coverageIgnore": false,
|
|
@@ -35447,7 +35451,7 @@
|
|
|
35447
35451
|
},
|
|
35448
35452
|
{
|
|
35449
35453
|
"name": "unwrapExpression",
|
|
35450
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35454
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
35451
35455
|
"ctype": "miscellaneous",
|
|
35452
35456
|
"subtype": "function",
|
|
35453
35457
|
"coverageIgnore": false,
|
|
@@ -35507,7 +35511,7 @@
|
|
|
35507
35511
|
},
|
|
35508
35512
|
{
|
|
35509
35513
|
"name": "unwrapExpression",
|
|
35510
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35514
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
35511
35515
|
"ctype": "miscellaneous",
|
|
35512
35516
|
"subtype": "function",
|
|
35513
35517
|
"coverageIgnore": false,
|
|
@@ -35537,7 +35541,7 @@
|
|
|
35537
35541
|
},
|
|
35538
35542
|
{
|
|
35539
35543
|
"name": "unwrapExpression",
|
|
35540
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35544
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
35541
35545
|
"ctype": "miscellaneous",
|
|
35542
35546
|
"subtype": "function",
|
|
35543
35547
|
"coverageIgnore": false,
|
|
@@ -35567,7 +35571,7 @@
|
|
|
35567
35571
|
},
|
|
35568
35572
|
{
|
|
35569
35573
|
"name": "unwrapExpression",
|
|
35570
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35574
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
35571
35575
|
"ctype": "miscellaneous",
|
|
35572
35576
|
"subtype": "function",
|
|
35573
35577
|
"coverageIgnore": false,
|
|
@@ -35597,7 +35601,7 @@
|
|
|
35597
35601
|
},
|
|
35598
35602
|
{
|
|
35599
35603
|
"name": "unwrapExpression",
|
|
35600
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
35604
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
35601
35605
|
"ctype": "miscellaneous",
|
|
35602
35606
|
"subtype": "function",
|
|
35603
35607
|
"coverageIgnore": false,
|
|
@@ -36120,7 +36124,7 @@
|
|
|
36120
36124
|
},
|
|
36121
36125
|
{
|
|
36122
36126
|
"name": "visitDir",
|
|
36123
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
36127
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
36124
36128
|
"ctype": "miscellaneous",
|
|
36125
36129
|
"subtype": "function",
|
|
36126
36130
|
"coverageIgnore": false,
|
|
@@ -36165,7 +36169,7 @@
|
|
|
36165
36169
|
},
|
|
36166
36170
|
{
|
|
36167
36171
|
"name": "visitDir",
|
|
36168
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36172
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
36169
36173
|
"ctype": "miscellaneous",
|
|
36170
36174
|
"subtype": "function",
|
|
36171
36175
|
"coverageIgnore": false,
|
|
@@ -36210,7 +36214,7 @@
|
|
|
36210
36214
|
},
|
|
36211
36215
|
{
|
|
36212
36216
|
"name": "visitDir",
|
|
36213
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36217
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
36214
36218
|
"ctype": "miscellaneous",
|
|
36215
36219
|
"subtype": "function",
|
|
36216
36220
|
"coverageIgnore": false,
|
|
@@ -36300,7 +36304,7 @@
|
|
|
36300
36304
|
},
|
|
36301
36305
|
{
|
|
36302
36306
|
"name": "visitDir",
|
|
36303
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36307
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
36304
36308
|
"ctype": "miscellaneous",
|
|
36305
36309
|
"subtype": "function",
|
|
36306
36310
|
"coverageIgnore": false,
|
|
@@ -36345,7 +36349,7 @@
|
|
|
36345
36349
|
},
|
|
36346
36350
|
{
|
|
36347
36351
|
"name": "visitDir",
|
|
36348
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36352
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
36349
36353
|
"ctype": "miscellaneous",
|
|
36350
36354
|
"subtype": "function",
|
|
36351
36355
|
"coverageIgnore": false,
|
|
@@ -36480,7 +36484,7 @@
|
|
|
36480
36484
|
},
|
|
36481
36485
|
{
|
|
36482
36486
|
"name": "visitDir",
|
|
36483
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36487
|
+
"file": "packages/core/schematics/migrate-eui-progress-circle/index.ts",
|
|
36484
36488
|
"ctype": "miscellaneous",
|
|
36485
36489
|
"subtype": "function",
|
|
36486
36490
|
"coverageIgnore": false,
|
|
@@ -36525,7 +36529,7 @@
|
|
|
36525
36529
|
},
|
|
36526
36530
|
{
|
|
36527
36531
|
"name": "visitDir",
|
|
36528
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36532
|
+
"file": "packages/core/schematics/migrate-eui-table/index.ts",
|
|
36529
36533
|
"ctype": "miscellaneous",
|
|
36530
36534
|
"subtype": "function",
|
|
36531
36535
|
"coverageIgnore": false,
|
|
@@ -36570,7 +36574,7 @@
|
|
|
36570
36574
|
},
|
|
36571
36575
|
{
|
|
36572
36576
|
"name": "visitDir",
|
|
36573
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36577
|
+
"file": "packages/core/schematics/migrate-eui-tabs/index.ts",
|
|
36574
36578
|
"ctype": "miscellaneous",
|
|
36575
36579
|
"subtype": "function",
|
|
36576
36580
|
"coverageIgnore": false,
|
|
@@ -36615,7 +36619,7 @@
|
|
|
36615
36619
|
},
|
|
36616
36620
|
{
|
|
36617
36621
|
"name": "visitDir",
|
|
36618
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
36622
|
+
"file": "packages/core/schematics/migrate-eui-toolbar-menu/index.ts",
|
|
36619
36623
|
"ctype": "miscellaneous",
|
|
36620
36624
|
"subtype": "function",
|
|
36621
36625
|
"coverageIgnore": false,
|
|
@@ -37012,7 +37016,7 @@
|
|
|
37012
37016
|
},
|
|
37013
37017
|
{
|
|
37014
37018
|
"name": "visitNodes",
|
|
37015
|
-
"file": "packages/core/schematics/migrate-eui-chip
|
|
37019
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
37016
37020
|
"ctype": "miscellaneous",
|
|
37017
37021
|
"subtype": "function",
|
|
37018
37022
|
"coverageIgnore": false,
|
|
@@ -37028,13 +37032,7 @@
|
|
|
37028
37032
|
"deprecationMessage": ""
|
|
37029
37033
|
},
|
|
37030
37034
|
{
|
|
37031
|
-
"name": "
|
|
37032
|
-
"type": "string",
|
|
37033
|
-
"deprecated": false,
|
|
37034
|
-
"deprecationMessage": ""
|
|
37035
|
-
},
|
|
37036
|
-
{
|
|
37037
|
-
"name": "edits",
|
|
37035
|
+
"name": "removals",
|
|
37038
37036
|
"deprecated": false,
|
|
37039
37037
|
"deprecationMessage": ""
|
|
37040
37038
|
}
|
|
@@ -37050,16 +37048,7 @@
|
|
|
37050
37048
|
}
|
|
37051
37049
|
},
|
|
37052
37050
|
{
|
|
37053
|
-
"name": "
|
|
37054
|
-
"type": "string",
|
|
37055
|
-
"deprecated": false,
|
|
37056
|
-
"deprecationMessage": "",
|
|
37057
|
-
"tagName": {
|
|
37058
|
-
"text": "param"
|
|
37059
|
-
}
|
|
37060
|
-
},
|
|
37061
|
-
{
|
|
37062
|
-
"name": "edits",
|
|
37051
|
+
"name": "removals",
|
|
37063
37052
|
"deprecated": false,
|
|
37064
37053
|
"deprecationMessage": "",
|
|
37065
37054
|
"tagName": {
|
|
@@ -37070,7 +37059,7 @@
|
|
|
37070
37059
|
},
|
|
37071
37060
|
{
|
|
37072
37061
|
"name": "visitNodes",
|
|
37073
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37062
|
+
"file": "packages/core/schematics/migrate-eui-chip-list/index.ts",
|
|
37074
37063
|
"ctype": "miscellaneous",
|
|
37075
37064
|
"subtype": "function",
|
|
37076
37065
|
"coverageIgnore": false,
|
|
@@ -37092,7 +37081,7 @@
|
|
|
37092
37081
|
"deprecationMessage": ""
|
|
37093
37082
|
},
|
|
37094
37083
|
{
|
|
37095
|
-
"name": "
|
|
37084
|
+
"name": "edits",
|
|
37096
37085
|
"deprecated": false,
|
|
37097
37086
|
"deprecationMessage": ""
|
|
37098
37087
|
}
|
|
@@ -37117,7 +37106,7 @@
|
|
|
37117
37106
|
}
|
|
37118
37107
|
},
|
|
37119
37108
|
{
|
|
37120
|
-
"name": "
|
|
37109
|
+
"name": "edits",
|
|
37121
37110
|
"deprecated": false,
|
|
37122
37111
|
"deprecationMessage": "",
|
|
37123
37112
|
"tagName": {
|
|
@@ -37128,7 +37117,7 @@
|
|
|
37128
37117
|
},
|
|
37129
37118
|
{
|
|
37130
37119
|
"name": "visitNodes",
|
|
37131
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37120
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
37132
37121
|
"ctype": "miscellaneous",
|
|
37133
37122
|
"subtype": "function",
|
|
37134
37123
|
"coverageIgnore": false,
|
|
@@ -37143,6 +37132,12 @@
|
|
|
37143
37132
|
"deprecated": false,
|
|
37144
37133
|
"deprecationMessage": ""
|
|
37145
37134
|
},
|
|
37135
|
+
{
|
|
37136
|
+
"name": "source",
|
|
37137
|
+
"type": "string",
|
|
37138
|
+
"deprecated": false,
|
|
37139
|
+
"deprecationMessage": ""
|
|
37140
|
+
},
|
|
37146
37141
|
{
|
|
37147
37142
|
"name": "removals",
|
|
37148
37143
|
"deprecated": false,
|
|
@@ -37159,6 +37154,15 @@
|
|
|
37159
37154
|
"text": "param"
|
|
37160
37155
|
}
|
|
37161
37156
|
},
|
|
37157
|
+
{
|
|
37158
|
+
"name": "source",
|
|
37159
|
+
"type": "string",
|
|
37160
|
+
"deprecated": false,
|
|
37161
|
+
"deprecationMessage": "",
|
|
37162
|
+
"tagName": {
|
|
37163
|
+
"text": "param"
|
|
37164
|
+
}
|
|
37165
|
+
},
|
|
37162
37166
|
{
|
|
37163
37167
|
"name": "removals",
|
|
37164
37168
|
"deprecated": false,
|
|
@@ -37214,7 +37218,7 @@
|
|
|
37214
37218
|
},
|
|
37215
37219
|
{
|
|
37216
37220
|
"name": "visitNodes",
|
|
37217
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37221
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
37218
37222
|
"ctype": "miscellaneous",
|
|
37219
37223
|
"subtype": "function",
|
|
37220
37224
|
"coverageIgnore": false,
|
|
@@ -37257,7 +37261,7 @@
|
|
|
37257
37261
|
},
|
|
37258
37262
|
{
|
|
37259
37263
|
"name": "visitNodes",
|
|
37260
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
37264
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
37261
37265
|
"ctype": "miscellaneous",
|
|
37262
37266
|
"subtype": "function",
|
|
37263
37267
|
"coverageIgnore": false,
|
|
@@ -39120,74 +39124,74 @@
|
|
|
39120
39124
|
"defaultValue": "'onEditorChanged'"
|
|
39121
39125
|
}
|
|
39122
39126
|
],
|
|
39123
|
-
"packages/core/schematics/migrate-eui-
|
|
39127
|
+
"packages/core/schematics/migrate-eui-fieldset/index.ts": [
|
|
39124
39128
|
{
|
|
39125
39129
|
"name": "COMPONENT_TAG",
|
|
39126
39130
|
"ctype": "miscellaneous",
|
|
39127
39131
|
"subtype": "variable",
|
|
39128
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39132
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
39129
39133
|
"coverageIgnore": false,
|
|
39130
39134
|
"deprecated": false,
|
|
39131
39135
|
"deprecationMessage": "",
|
|
39132
39136
|
"type": "string",
|
|
39133
|
-
"defaultValue": "'eui-
|
|
39137
|
+
"defaultValue": "'eui-fieldset'"
|
|
39134
39138
|
},
|
|
39135
39139
|
{
|
|
39136
|
-
"name": "
|
|
39140
|
+
"name": "NEW_NAME",
|
|
39137
39141
|
"ctype": "miscellaneous",
|
|
39138
39142
|
"subtype": "variable",
|
|
39139
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39143
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
39140
39144
|
"coverageIgnore": false,
|
|
39141
39145
|
"deprecated": false,
|
|
39142
39146
|
"deprecationMessage": "",
|
|
39143
|
-
"type": "
|
|
39144
|
-
"defaultValue": "
|
|
39147
|
+
"type": "string",
|
|
39148
|
+
"defaultValue": "'iconSvgName'"
|
|
39145
39149
|
},
|
|
39146
39150
|
{
|
|
39147
|
-
"name": "
|
|
39151
|
+
"name": "OLD_NAME",
|
|
39148
39152
|
"ctype": "miscellaneous",
|
|
39149
39153
|
"subtype": "variable",
|
|
39150
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39154
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
39151
39155
|
"coverageIgnore": false,
|
|
39152
39156
|
"deprecated": false,
|
|
39153
39157
|
"deprecationMessage": "",
|
|
39154
|
-
"type": "
|
|
39155
|
-
"defaultValue": "
|
|
39158
|
+
"type": "string",
|
|
39159
|
+
"defaultValue": "'iconSvgType'"
|
|
39156
39160
|
}
|
|
39157
39161
|
],
|
|
39158
|
-
"packages/core/schematics/migrate-eui-
|
|
39162
|
+
"packages/core/schematics/migrate-eui-icon-svg/index.ts": [
|
|
39159
39163
|
{
|
|
39160
39164
|
"name": "COMPONENT_TAG",
|
|
39161
39165
|
"ctype": "miscellaneous",
|
|
39162
39166
|
"subtype": "variable",
|
|
39163
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39167
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
39164
39168
|
"coverageIgnore": false,
|
|
39165
39169
|
"deprecated": false,
|
|
39166
39170
|
"deprecationMessage": "",
|
|
39167
39171
|
"type": "string",
|
|
39168
|
-
"defaultValue": "'eui-
|
|
39172
|
+
"defaultValue": "'eui-icon-svg'"
|
|
39169
39173
|
},
|
|
39170
39174
|
{
|
|
39171
|
-
"name": "
|
|
39175
|
+
"name": "INPUT_RENAMES",
|
|
39172
39176
|
"ctype": "miscellaneous",
|
|
39173
39177
|
"subtype": "variable",
|
|
39174
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39178
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
39175
39179
|
"coverageIgnore": false,
|
|
39176
39180
|
"deprecated": false,
|
|
39177
39181
|
"deprecationMessage": "",
|
|
39178
|
-
"type": "
|
|
39179
|
-
"defaultValue": "'
|
|
39182
|
+
"type": "unknown",
|
|
39183
|
+
"defaultValue": "new Map([\n ['variant', 'fillColor'],\n ['aria-label', 'ariaLabel'],\n])"
|
|
39180
39184
|
},
|
|
39181
39185
|
{
|
|
39182
|
-
"name": "
|
|
39186
|
+
"name": "TS_PROPERTY_RENAMES",
|
|
39183
39187
|
"ctype": "miscellaneous",
|
|
39184
39188
|
"subtype": "variable",
|
|
39185
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
39189
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
39186
39190
|
"coverageIgnore": false,
|
|
39187
39191
|
"deprecated": false,
|
|
39188
39192
|
"deprecationMessage": "",
|
|
39189
|
-
"type": "
|
|
39190
|
-
"defaultValue": "'
|
|
39193
|
+
"type": "unknown",
|
|
39194
|
+
"defaultValue": "new Map([\n ['variant', 'fillColor'],\n])"
|
|
39191
39195
|
}
|
|
39192
39196
|
],
|
|
39193
39197
|
"packages/core/schematics/migrate-eui-icon-toggle/index.ts": [
|
|
@@ -45989,10 +45993,10 @@
|
|
|
45989
45993
|
]
|
|
45990
45994
|
}
|
|
45991
45995
|
],
|
|
45992
|
-
"packages/core/schematics/migrate-eui-
|
|
45996
|
+
"packages/core/schematics/migrate-eui-fieldset/index.ts": [
|
|
45993
45997
|
{
|
|
45994
45998
|
"name": "applyEdits",
|
|
45995
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
45999
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
45996
46000
|
"ctype": "miscellaneous",
|
|
45997
46001
|
"subtype": "function",
|
|
45998
46002
|
"coverageIgnore": false,
|
|
@@ -46037,7 +46041,7 @@
|
|
|
46037
46041
|
},
|
|
46038
46042
|
{
|
|
46039
46043
|
"name": "collectRenames",
|
|
46040
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46044
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46041
46045
|
"ctype": "miscellaneous",
|
|
46042
46046
|
"subtype": "function",
|
|
46043
46047
|
"coverageIgnore": false,
|
|
@@ -46082,7 +46086,7 @@
|
|
|
46082
46086
|
},
|
|
46083
46087
|
{
|
|
46084
46088
|
"name": "isComponentMetadataProperty",
|
|
46085
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46089
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46086
46090
|
"ctype": "miscellaneous",
|
|
46087
46091
|
"subtype": "function",
|
|
46088
46092
|
"coverageIgnore": false,
|
|
@@ -46112,7 +46116,7 @@
|
|
|
46112
46116
|
},
|
|
46113
46117
|
{
|
|
46114
46118
|
"name": "isTemplateProperty",
|
|
46115
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46119
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46116
46120
|
"ctype": "miscellaneous",
|
|
46117
46121
|
"subtype": "function",
|
|
46118
46122
|
"coverageIgnore": false,
|
|
@@ -46141,8 +46145,8 @@
|
|
|
46141
46145
|
]
|
|
46142
46146
|
},
|
|
46143
46147
|
{
|
|
46144
|
-
"name": "
|
|
46145
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46148
|
+
"name": "migrateEuiFieldset",
|
|
46149
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46146
46150
|
"ctype": "miscellaneous",
|
|
46147
46151
|
"subtype": "function",
|
|
46148
46152
|
"coverageIgnore": false,
|
|
@@ -46150,7 +46154,7 @@
|
|
|
46150
46154
|
"deprecationMessage": "",
|
|
46151
46155
|
"rawdescription": "",
|
|
46152
46156
|
"description": "",
|
|
46153
|
-
"displayName": "
|
|
46157
|
+
"displayName": "migrateEuiFieldset",
|
|
46154
46158
|
"args": [
|
|
46155
46159
|
{
|
|
46156
46160
|
"name": "options",
|
|
@@ -46176,7 +46180,7 @@
|
|
|
46176
46180
|
},
|
|
46177
46181
|
{
|
|
46178
46182
|
"name": "migrateInlineTemplates",
|
|
46179
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46183
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46180
46184
|
"ctype": "miscellaneous",
|
|
46181
46185
|
"subtype": "function",
|
|
46182
46186
|
"coverageIgnore": false,
|
|
@@ -46208,7 +46212,7 @@
|
|
|
46208
46212
|
},
|
|
46209
46213
|
{
|
|
46210
46214
|
"name": "migrateTemplate",
|
|
46211
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46215
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46212
46216
|
"ctype": "miscellaneous",
|
|
46213
46217
|
"subtype": "function",
|
|
46214
46218
|
"coverageIgnore": false,
|
|
@@ -46238,41 +46242,9 @@
|
|
|
46238
46242
|
}
|
|
46239
46243
|
]
|
|
46240
46244
|
},
|
|
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
46245
|
{
|
|
46274
46246
|
"name": "unwrapExpression",
|
|
46275
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46247
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46276
46248
|
"ctype": "miscellaneous",
|
|
46277
46249
|
"subtype": "function",
|
|
46278
46250
|
"coverageIgnore": false,
|
|
@@ -46302,7 +46274,7 @@
|
|
|
46302
46274
|
},
|
|
46303
46275
|
{
|
|
46304
46276
|
"name": "visitDir",
|
|
46305
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46277
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46306
46278
|
"ctype": "miscellaneous",
|
|
46307
46279
|
"subtype": "function",
|
|
46308
46280
|
"coverageIgnore": false,
|
|
@@ -46347,7 +46319,7 @@
|
|
|
46347
46319
|
},
|
|
46348
46320
|
{
|
|
46349
46321
|
"name": "visitNodes",
|
|
46350
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46322
|
+
"file": "packages/core/schematics/migrate-eui-fieldset/index.ts",
|
|
46351
46323
|
"ctype": "miscellaneous",
|
|
46352
46324
|
"subtype": "function",
|
|
46353
46325
|
"coverageIgnore": false,
|
|
@@ -46389,10 +46361,10 @@
|
|
|
46389
46361
|
]
|
|
46390
46362
|
}
|
|
46391
46363
|
],
|
|
46392
|
-
"packages/core/schematics/migrate-eui-
|
|
46364
|
+
"packages/core/schematics/migrate-eui-icon-svg/index.ts": [
|
|
46393
46365
|
{
|
|
46394
46366
|
"name": "applyEdits",
|
|
46395
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46367
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46396
46368
|
"ctype": "miscellaneous",
|
|
46397
46369
|
"subtype": "function",
|
|
46398
46370
|
"coverageIgnore": false,
|
|
@@ -46437,7 +46409,7 @@
|
|
|
46437
46409
|
},
|
|
46438
46410
|
{
|
|
46439
46411
|
"name": "collectRenames",
|
|
46440
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46412
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46441
46413
|
"ctype": "miscellaneous",
|
|
46442
46414
|
"subtype": "function",
|
|
46443
46415
|
"coverageIgnore": false,
|
|
@@ -46482,7 +46454,7 @@
|
|
|
46482
46454
|
},
|
|
46483
46455
|
{
|
|
46484
46456
|
"name": "isComponentMetadataProperty",
|
|
46485
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46457
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46486
46458
|
"ctype": "miscellaneous",
|
|
46487
46459
|
"subtype": "function",
|
|
46488
46460
|
"coverageIgnore": false,
|
|
@@ -46512,7 +46484,7 @@
|
|
|
46512
46484
|
},
|
|
46513
46485
|
{
|
|
46514
46486
|
"name": "isTemplateProperty",
|
|
46515
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46487
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46516
46488
|
"ctype": "miscellaneous",
|
|
46517
46489
|
"subtype": "function",
|
|
46518
46490
|
"coverageIgnore": false,
|
|
@@ -46541,8 +46513,8 @@
|
|
|
46541
46513
|
]
|
|
46542
46514
|
},
|
|
46543
46515
|
{
|
|
46544
|
-
"name": "
|
|
46545
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46516
|
+
"name": "migrateEuiIconSvg",
|
|
46517
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46546
46518
|
"ctype": "miscellaneous",
|
|
46547
46519
|
"subtype": "function",
|
|
46548
46520
|
"coverageIgnore": false,
|
|
@@ -46550,7 +46522,7 @@
|
|
|
46550
46522
|
"deprecationMessage": "",
|
|
46551
46523
|
"rawdescription": "",
|
|
46552
46524
|
"description": "",
|
|
46553
|
-
"displayName": "
|
|
46525
|
+
"displayName": "migrateEuiIconSvg",
|
|
46554
46526
|
"args": [
|
|
46555
46527
|
{
|
|
46556
46528
|
"name": "options",
|
|
@@ -46576,7 +46548,7 @@
|
|
|
46576
46548
|
},
|
|
46577
46549
|
{
|
|
46578
46550
|
"name": "migrateInlineTemplates",
|
|
46579
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46551
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46580
46552
|
"ctype": "miscellaneous",
|
|
46581
46553
|
"subtype": "function",
|
|
46582
46554
|
"coverageIgnore": false,
|
|
@@ -46608,7 +46580,7 @@
|
|
|
46608
46580
|
},
|
|
46609
46581
|
{
|
|
46610
46582
|
"name": "migrateTemplate",
|
|
46611
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46583
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46612
46584
|
"ctype": "miscellaneous",
|
|
46613
46585
|
"subtype": "function",
|
|
46614
46586
|
"coverageIgnore": false,
|
|
@@ -46638,9 +46610,41 @@
|
|
|
46638
46610
|
}
|
|
46639
46611
|
]
|
|
46640
46612
|
},
|
|
46613
|
+
{
|
|
46614
|
+
"name": "renameTsPropertyAccesses",
|
|
46615
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46616
|
+
"ctype": "miscellaneous",
|
|
46617
|
+
"subtype": "function",
|
|
46618
|
+
"coverageIgnore": false,
|
|
46619
|
+
"deprecated": false,
|
|
46620
|
+
"deprecationMessage": "",
|
|
46621
|
+
"rawdescription": "",
|
|
46622
|
+
"description": "",
|
|
46623
|
+
"displayName": "renameTsPropertyAccesses",
|
|
46624
|
+
"args": [
|
|
46625
|
+
{
|
|
46626
|
+
"name": "source",
|
|
46627
|
+
"type": "string",
|
|
46628
|
+
"deprecated": false,
|
|
46629
|
+
"deprecationMessage": ""
|
|
46630
|
+
}
|
|
46631
|
+
],
|
|
46632
|
+
"returnType": "string",
|
|
46633
|
+
"jsdoctags": [
|
|
46634
|
+
{
|
|
46635
|
+
"name": "source",
|
|
46636
|
+
"type": "string",
|
|
46637
|
+
"deprecated": false,
|
|
46638
|
+
"deprecationMessage": "",
|
|
46639
|
+
"tagName": {
|
|
46640
|
+
"text": "param"
|
|
46641
|
+
}
|
|
46642
|
+
}
|
|
46643
|
+
]
|
|
46644
|
+
},
|
|
46641
46645
|
{
|
|
46642
46646
|
"name": "unwrapExpression",
|
|
46643
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46647
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46644
46648
|
"ctype": "miscellaneous",
|
|
46645
46649
|
"subtype": "function",
|
|
46646
46650
|
"coverageIgnore": false,
|
|
@@ -46670,7 +46674,7 @@
|
|
|
46670
46674
|
},
|
|
46671
46675
|
{
|
|
46672
46676
|
"name": "visitDir",
|
|
46673
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46677
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46674
46678
|
"ctype": "miscellaneous",
|
|
46675
46679
|
"subtype": "function",
|
|
46676
46680
|
"coverageIgnore": false,
|
|
@@ -46715,7 +46719,7 @@
|
|
|
46715
46719
|
},
|
|
46716
46720
|
{
|
|
46717
46721
|
"name": "visitNodes",
|
|
46718
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
46722
|
+
"file": "packages/core/schematics/migrate-eui-icon-svg/index.ts",
|
|
46719
46723
|
"ctype": "miscellaneous",
|
|
46720
46724
|
"subtype": "function",
|
|
46721
46725
|
"coverageIgnore": false,
|
|
@@ -50773,10 +50777,10 @@
|
|
|
50773
50777
|
]
|
|
50774
50778
|
}
|
|
50775
50779
|
],
|
|
50776
|
-
"packages/core/schematics/migrate-eui-
|
|
50780
|
+
"packages/core/schematics/migrate-eui-chip/index.ts": [
|
|
50777
50781
|
{
|
|
50778
50782
|
"name": "collectRemovals",
|
|
50779
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50783
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50780
50784
|
"ctype": "miscellaneous",
|
|
50781
50785
|
"subtype": "function",
|
|
50782
50786
|
"coverageIgnore": false,
|
|
@@ -50792,12 +50796,6 @@
|
|
|
50792
50796
|
"deprecated": false,
|
|
50793
50797
|
"deprecationMessage": ""
|
|
50794
50798
|
},
|
|
50795
|
-
{
|
|
50796
|
-
"name": "source",
|
|
50797
|
-
"type": "string",
|
|
50798
|
-
"deprecated": false,
|
|
50799
|
-
"deprecationMessage": ""
|
|
50800
|
-
},
|
|
50801
50799
|
{
|
|
50802
50800
|
"name": "removals",
|
|
50803
50801
|
"deprecated": false,
|
|
@@ -50816,16 +50814,37 @@
|
|
|
50816
50814
|
}
|
|
50817
50815
|
},
|
|
50818
50816
|
{
|
|
50819
|
-
"name": "
|
|
50820
|
-
"type": "string",
|
|
50817
|
+
"name": "removals",
|
|
50821
50818
|
"deprecated": false,
|
|
50822
50819
|
"deprecationMessage": "",
|
|
50823
50820
|
"tagName": {
|
|
50824
50821
|
"text": "param"
|
|
50825
50822
|
}
|
|
50826
|
-
}
|
|
50823
|
+
}
|
|
50824
|
+
]
|
|
50825
|
+
},
|
|
50826
|
+
{
|
|
50827
|
+
"name": "getAttributeSpan",
|
|
50828
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50829
|
+
"ctype": "miscellaneous",
|
|
50830
|
+
"subtype": "function",
|
|
50831
|
+
"coverageIgnore": false,
|
|
50832
|
+
"deprecated": false,
|
|
50833
|
+
"deprecationMessage": "",
|
|
50834
|
+
"rawdescription": "",
|
|
50835
|
+
"description": "",
|
|
50836
|
+
"displayName": "getAttributeSpan",
|
|
50837
|
+
"args": [
|
|
50827
50838
|
{
|
|
50828
|
-
"name": "
|
|
50839
|
+
"name": "attr",
|
|
50840
|
+
"deprecated": false,
|
|
50841
|
+
"deprecationMessage": ""
|
|
50842
|
+
}
|
|
50843
|
+
],
|
|
50844
|
+
"returnType": "{ start: number; end: number }",
|
|
50845
|
+
"jsdoctags": [
|
|
50846
|
+
{
|
|
50847
|
+
"name": "attr",
|
|
50829
50848
|
"deprecated": false,
|
|
50830
50849
|
"deprecationMessage": "",
|
|
50831
50850
|
"tagName": {
|
|
@@ -50835,8 +50854,8 @@
|
|
|
50835
50854
|
]
|
|
50836
50855
|
},
|
|
50837
50856
|
{
|
|
50838
|
-
"name": "
|
|
50839
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50857
|
+
"name": "isChipElement",
|
|
50858
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50840
50859
|
"ctype": "miscellaneous",
|
|
50841
50860
|
"subtype": "function",
|
|
50842
50861
|
"coverageIgnore": false,
|
|
@@ -50844,7 +50863,39 @@
|
|
|
50844
50863
|
"deprecationMessage": "",
|
|
50845
50864
|
"rawdescription": "",
|
|
50846
50865
|
"description": "",
|
|
50847
|
-
"displayName": "
|
|
50866
|
+
"displayName": "isChipElement",
|
|
50867
|
+
"args": [
|
|
50868
|
+
{
|
|
50869
|
+
"name": "element",
|
|
50870
|
+
"type": "TmplAstElement",
|
|
50871
|
+
"deprecated": false,
|
|
50872
|
+
"deprecationMessage": ""
|
|
50873
|
+
}
|
|
50874
|
+
],
|
|
50875
|
+
"returnType": "boolean",
|
|
50876
|
+
"jsdoctags": [
|
|
50877
|
+
{
|
|
50878
|
+
"name": "element",
|
|
50879
|
+
"type": "TmplAstElement",
|
|
50880
|
+
"deprecated": false,
|
|
50881
|
+
"deprecationMessage": "",
|
|
50882
|
+
"tagName": {
|
|
50883
|
+
"text": "param"
|
|
50884
|
+
}
|
|
50885
|
+
}
|
|
50886
|
+
]
|
|
50887
|
+
},
|
|
50888
|
+
{
|
|
50889
|
+
"name": "migrateEuiChip",
|
|
50890
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50891
|
+
"ctype": "miscellaneous",
|
|
50892
|
+
"subtype": "function",
|
|
50893
|
+
"coverageIgnore": false,
|
|
50894
|
+
"deprecated": false,
|
|
50895
|
+
"deprecationMessage": "",
|
|
50896
|
+
"rawdescription": "",
|
|
50897
|
+
"description": "",
|
|
50898
|
+
"displayName": "migrateEuiChip",
|
|
50848
50899
|
"args": [
|
|
50849
50900
|
{
|
|
50850
50901
|
"name": "options",
|
|
@@ -50870,7 +50921,7 @@
|
|
|
50870
50921
|
},
|
|
50871
50922
|
{
|
|
50872
50923
|
"name": "migrateInlineTemplates",
|
|
50873
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50924
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50874
50925
|
"ctype": "miscellaneous",
|
|
50875
50926
|
"subtype": "function",
|
|
50876
50927
|
"coverageIgnore": false,
|
|
@@ -50902,7 +50953,7 @@
|
|
|
50902
50953
|
},
|
|
50903
50954
|
{
|
|
50904
50955
|
"name": "migrateTemplate",
|
|
50905
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50956
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50906
50957
|
"ctype": "miscellaneous",
|
|
50907
50958
|
"subtype": "function",
|
|
50908
50959
|
"coverageIgnore": false,
|
|
@@ -50934,7 +50985,7 @@
|
|
|
50934
50985
|
},
|
|
50935
50986
|
{
|
|
50936
50987
|
"name": "visitDir",
|
|
50937
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
50988
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50938
50989
|
"ctype": "miscellaneous",
|
|
50939
50990
|
"subtype": "function",
|
|
50940
50991
|
"coverageIgnore": false,
|
|
@@ -50979,7 +51030,7 @@
|
|
|
50979
51030
|
},
|
|
50980
51031
|
{
|
|
50981
51032
|
"name": "visitNodes",
|
|
50982
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51033
|
+
"file": "packages/core/schematics/migrate-eui-chip/index.ts",
|
|
50983
51034
|
"ctype": "miscellaneous",
|
|
50984
51035
|
"subtype": "function",
|
|
50985
51036
|
"coverageIgnore": false,
|
|
@@ -50994,12 +51045,6 @@
|
|
|
50994
51045
|
"deprecated": false,
|
|
50995
51046
|
"deprecationMessage": ""
|
|
50996
51047
|
},
|
|
50997
|
-
{
|
|
50998
|
-
"name": "source",
|
|
50999
|
-
"type": "string",
|
|
51000
|
-
"deprecated": false,
|
|
51001
|
-
"deprecationMessage": ""
|
|
51002
|
-
},
|
|
51003
51048
|
{
|
|
51004
51049
|
"name": "removals",
|
|
51005
51050
|
"deprecated": false,
|
|
@@ -51016,15 +51061,6 @@
|
|
|
51016
51061
|
"text": "param"
|
|
51017
51062
|
}
|
|
51018
51063
|
},
|
|
51019
|
-
{
|
|
51020
|
-
"name": "source",
|
|
51021
|
-
"type": "string",
|
|
51022
|
-
"deprecated": false,
|
|
51023
|
-
"deprecationMessage": "",
|
|
51024
|
-
"tagName": {
|
|
51025
|
-
"text": "param"
|
|
51026
|
-
}
|
|
51027
|
-
},
|
|
51028
51064
|
{
|
|
51029
51065
|
"name": "removals",
|
|
51030
51066
|
"deprecated": false,
|
|
@@ -51036,10 +51072,10 @@
|
|
|
51036
51072
|
]
|
|
51037
51073
|
}
|
|
51038
51074
|
],
|
|
51039
|
-
"packages/core/schematics/migrate-eui-
|
|
51075
|
+
"packages/core/schematics/migrate-eui-discussion-thread/index.ts": [
|
|
51040
51076
|
{
|
|
51041
51077
|
"name": "collectRemovals",
|
|
51042
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51078
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51043
51079
|
"ctype": "miscellaneous",
|
|
51044
51080
|
"subtype": "function",
|
|
51045
51081
|
"coverageIgnore": false,
|
|
@@ -51055,6 +51091,12 @@
|
|
|
51055
51091
|
"deprecated": false,
|
|
51056
51092
|
"deprecationMessage": ""
|
|
51057
51093
|
},
|
|
51094
|
+
{
|
|
51095
|
+
"name": "source",
|
|
51096
|
+
"type": "string",
|
|
51097
|
+
"deprecated": false,
|
|
51098
|
+
"deprecationMessage": ""
|
|
51099
|
+
},
|
|
51058
51100
|
{
|
|
51059
51101
|
"name": "removals",
|
|
51060
51102
|
"deprecated": false,
|
|
@@ -51073,69 +51115,16 @@
|
|
|
51073
51115
|
}
|
|
51074
51116
|
},
|
|
51075
51117
|
{
|
|
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",
|
|
51118
|
+
"name": "source",
|
|
51119
|
+
"type": "string",
|
|
51107
51120
|
"deprecated": false,
|
|
51108
51121
|
"deprecationMessage": "",
|
|
51109
51122
|
"tagName": {
|
|
51110
51123
|
"text": "param"
|
|
51111
51124
|
}
|
|
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": [
|
|
51125
|
+
},
|
|
51136
51126
|
{
|
|
51137
|
-
"name": "
|
|
51138
|
-
"type": "TmplAstElement",
|
|
51127
|
+
"name": "removals",
|
|
51139
51128
|
"deprecated": false,
|
|
51140
51129
|
"deprecationMessage": "",
|
|
51141
51130
|
"tagName": {
|
|
@@ -51145,8 +51134,8 @@
|
|
|
51145
51134
|
]
|
|
51146
51135
|
},
|
|
51147
51136
|
{
|
|
51148
|
-
"name": "
|
|
51149
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51137
|
+
"name": "migrateEuiDiscussionThread",
|
|
51138
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51150
51139
|
"ctype": "miscellaneous",
|
|
51151
51140
|
"subtype": "function",
|
|
51152
51141
|
"coverageIgnore": false,
|
|
@@ -51154,7 +51143,7 @@
|
|
|
51154
51143
|
"deprecationMessage": "",
|
|
51155
51144
|
"rawdescription": "",
|
|
51156
51145
|
"description": "",
|
|
51157
|
-
"displayName": "
|
|
51146
|
+
"displayName": "migrateEuiDiscussionThread",
|
|
51158
51147
|
"args": [
|
|
51159
51148
|
{
|
|
51160
51149
|
"name": "options",
|
|
@@ -51180,7 +51169,7 @@
|
|
|
51180
51169
|
},
|
|
51181
51170
|
{
|
|
51182
51171
|
"name": "migrateInlineTemplates",
|
|
51183
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51172
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51184
51173
|
"ctype": "miscellaneous",
|
|
51185
51174
|
"subtype": "function",
|
|
51186
51175
|
"coverageIgnore": false,
|
|
@@ -51212,7 +51201,7 @@
|
|
|
51212
51201
|
},
|
|
51213
51202
|
{
|
|
51214
51203
|
"name": "migrateTemplate",
|
|
51215
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51204
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51216
51205
|
"ctype": "miscellaneous",
|
|
51217
51206
|
"subtype": "function",
|
|
51218
51207
|
"coverageIgnore": false,
|
|
@@ -51244,7 +51233,7 @@
|
|
|
51244
51233
|
},
|
|
51245
51234
|
{
|
|
51246
51235
|
"name": "visitDir",
|
|
51247
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51236
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51248
51237
|
"ctype": "miscellaneous",
|
|
51249
51238
|
"subtype": "function",
|
|
51250
51239
|
"coverageIgnore": false,
|
|
@@ -51289,7 +51278,7 @@
|
|
|
51289
51278
|
},
|
|
51290
51279
|
{
|
|
51291
51280
|
"name": "visitNodes",
|
|
51292
|
-
"file": "packages/core/schematics/migrate-eui-
|
|
51281
|
+
"file": "packages/core/schematics/migrate-eui-discussion-thread/index.ts",
|
|
51293
51282
|
"ctype": "miscellaneous",
|
|
51294
51283
|
"subtype": "function",
|
|
51295
51284
|
"coverageIgnore": false,
|
|
@@ -51304,6 +51293,12 @@
|
|
|
51304
51293
|
"deprecated": false,
|
|
51305
51294
|
"deprecationMessage": ""
|
|
51306
51295
|
},
|
|
51296
|
+
{
|
|
51297
|
+
"name": "source",
|
|
51298
|
+
"type": "string",
|
|
51299
|
+
"deprecated": false,
|
|
51300
|
+
"deprecationMessage": ""
|
|
51301
|
+
},
|
|
51307
51302
|
{
|
|
51308
51303
|
"name": "removals",
|
|
51309
51304
|
"deprecated": false,
|
|
@@ -51320,6 +51315,15 @@
|
|
|
51320
51315
|
"text": "param"
|
|
51321
51316
|
}
|
|
51322
51317
|
},
|
|
51318
|
+
{
|
|
51319
|
+
"name": "source",
|
|
51320
|
+
"type": "string",
|
|
51321
|
+
"deprecated": false,
|
|
51322
|
+
"deprecationMessage": "",
|
|
51323
|
+
"tagName": {
|
|
51324
|
+
"text": "param"
|
|
51325
|
+
}
|
|
51326
|
+
},
|
|
51323
51327
|
{
|
|
51324
51328
|
"name": "removals",
|
|
51325
51329
|
"deprecated": false,
|