Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion projects/igniteui-angular/migrations/common/tsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,25 @@ import { Logger } from './tsLogger';
import { TSLanguageService } from './tsPlugin/TSLanguageService';

export const IG_PACKAGE_NAME = 'igniteui-angular';
export const IG_LICENSED_PACKAGE_NAME = '@infragistics/igniteui-angular';
export const NG_LANG_SERVICE_PACKAGE_NAME = '@angular/language-service';
export const NG_CORE_PACKAGE_NAME = '@angular/core';
export const CUSTOM_TS_PLUGIN_PATH = './tsPlugin';
export const CUSTOM_TS_PLUGIN_NAME = 'igx-ts-plugin';

/**
* Checks if the given import path is from igniteui-angular package.
* Handles both OSS (igniteui-angular) and licensed (@infragistics/igniteui-angular) versions,
* as well as subpaths (e.g., igniteui-angular/core, @infragistics/igniteui-angular/grids).
* @param importPath The module specifier text to check
* @returns true if the import path is from igniteui-angular package
*/
export const isIgniteuiImport = (importPath: string): boolean =>
importPath === IG_PACKAGE_NAME ||
importPath === IG_LICENSED_PACKAGE_NAME ||
importPath.startsWith(`${IG_PACKAGE_NAME}/`) ||
importPath.startsWith(`${IG_LICENSED_PACKAGE_NAME}/`);

enum SyntaxTokens {
ClosingParenthesis = ')',
MemberAccess = '.',
Expand Down Expand Up @@ -86,7 +100,7 @@ export const getImportModulePositions = (sourceText: string, startsWith: string)
/** Filters out statements to named imports (e.g. `import {x, y}`) from PACKAGE_IMPORT */
export const namedImportFilter = (statement: ts.Statement) => {
if (statement.kind === ts.SyntaxKind.ImportDeclaration &&
((statement as ts.ImportDeclaration).moduleSpecifier as ts.StringLiteral).text.endsWith(IG_PACKAGE_NAME)) {
isIgniteuiImport(((statement as ts.ImportDeclaration).moduleSpecifier as ts.StringLiteral).text)) {

const clause = (statement as ts.ImportDeclaration).importClause;
return clause && clause.namedBindings && clause.namedBindings.kind === ts.SyntaxKind.NamedImports;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import type {
Tree
} from '@angular-devkit/schematics';
import * as ts from 'typescript';
import { IG_PACKAGE_NAME, IG_LICENSED_PACKAGE_NAME } from '../common/tsUtils';
import { escapeRegExp } from '../common/util';

const version = '21.0.0';

Expand Down Expand Up @@ -709,6 +711,19 @@ const TYPE_RENAMES = new Map<string, { newName: string, entryPoint: string }>([
['IgxColumPatternValidatorDirective', { newName: 'IgxColumnPatternValidatorDirective', entryPoint: 'grids/core' }],
]);

// Pre-compiled regex for quick file content checks - matches base package imports only (not subpaths)
const BASE_IMPORT_PATTERN = new RegExp(
`from\\s+['"](${escapeRegExp(IG_LICENSED_PACKAGE_NAME)}|${escapeRegExp(IG_PACKAGE_NAME)})['"]`
);

/**
* Quick regex-based check if file content has base igniteui-angular imports (without entry point subpaths).
* This is a performance optimization to avoid parsing files that don't need migration.
* Uses regex to check for imports like: from 'igniteui-angular' or from "@infragistics/igniteui-angular"
* but not from 'igniteui-angular/core' etc. which are already using entry points.
*/
const hasBaseIgniteuiImports = (content: string): boolean => BASE_IMPORT_PATTERN.test(content);

function migrateImportDeclaration(node: ts.ImportDeclaration, sourceFile: ts.SourceFile): { start: number, end: number, replacement: string } | null {
const moduleSpecifier = node.moduleSpecifier;
if (!ts.isStringLiteral(moduleSpecifier)) {
Expand All @@ -717,8 +732,8 @@ function migrateImportDeclaration(node: ts.ImportDeclaration, sourceFile: ts.Sou

const importPath = moduleSpecifier.text;

// Only process igniteui-angular imports (not already using entry points)
if (importPath !== 'igniteui-angular' && importPath !== '@infragistics/igniteui-angular') {
// Only process base igniteui-angular imports (not already using entry points)
if (importPath !== IG_PACKAGE_NAME && importPath !== IG_LICENSED_PACKAGE_NAME) {
Comment thread
damyanpetev marked this conversation as resolved.
Outdated
return null;
}

Expand Down Expand Up @@ -799,7 +814,7 @@ function migrateFile(filePath: string, content: string): string {

// Track old type names that were imported
const moduleSpecifier = node.moduleSpecifier;
if (ts.isStringLiteral(moduleSpecifier) && (moduleSpecifier.text === 'igniteui-angular' || moduleSpecifier.text === '@infragistics/igniteui-angular')) {
if (ts.isStringLiteral(moduleSpecifier) && (moduleSpecifier.text === IG_PACKAGE_NAME || moduleSpecifier.text === IG_LICENSED_PACKAGE_NAME)) {
const importClause = node.importClause;
if (importClause?.namedBindings && ts.isNamedImports(importClause.namedBindings)) {
for (const element of importClause.namedBindings.elements) {
Expand Down Expand Up @@ -876,9 +891,8 @@ export default function migrate(): Rule {

const originalContent = content.toString();

// Check if file has igniteui-angular imports
if (!originalContent.includes("from 'igniteui-angular'") && !originalContent.includes('from "igniteui-angular"') &&
!originalContent.includes("from '@infragistics/igniteui-angular'") && !originalContent.includes('from "@infragistics/igniteui-angular"')) {
// Check if file has base igniteui-angular imports (not using entry point subpaths)
if (!hasBaseIgniteuiImports(originalContent)) {
Comment thread
damyanpetev marked this conversation as resolved.
Outdated
return;
}

Expand Down