All files / src/bundle/utils imports.ts

92.3% Statements 48/52
80% Branches 20/25
100% Functions 10/10
92.15% Lines 47/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 1131x               24x                 24x   24x       24x 24x       24x     1x 12x 12x       12x 32x 14x 14x 14x 14x       14x       12x 12x     1x 12x 36x 36x 14x           1x           12x 12x       12x 12x       12x 13x 9x 4x 3x 3x 3x     1x     12x 1x   11x 11x 8x   3x 3x 3x               12x 12x    
import { SourceFile, TypeGuards, SyntaxKind, PropertyAssignment, ObjectLiteralExpression } from 'ts-morph';
 
interface ImportConfig {
  key: string;
  value: string;
}
 
function clearEmptyRows(properties: PropertyAssignment) {
  properties.replaceWithText(
    properties
      .getFullText()
      .replace(/^\s*\n/gm, '')
      .trim(),
  );
}
 
function getImportsProperty(moduleFile: SourceFile, moduleName: string): PropertyAssignment {
  const decoratorArguments = moduleFile.getClassOrThrow(moduleName).getDecoratorOrThrow('NgModule').getArguments()[0];
 
  Iif (!TypeGuards.isObjectLiteralExpression(decoratorArguments)) {
    throw new Error(`Argument to NgModule Decorator on ${moduleName} expected to be an object literal`);
  }
 
  const importsProperty = decoratorArguments.getProperty('imports');
  Iif (!importsProperty || !TypeGuards.isPropertyAssignment(importsProperty)) {
    throw new Error(`Imports in NgModule Decorator of ${moduleName} expected to be propery assignments`);
  }
 
  return importsProperty;
}
 
export function removeModuleImports(moduleFile: SourceFile, moduleName: string, modules: Set<string>): void {
  const importsProperty = getImportsProperty(moduleFile, moduleName);
  const imports = importsProperty
    .getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression)
    .getFirstChildByKindOrThrow(SyntaxKind.SyntaxList);
 
  imports.getChildrenOfKind(SyntaxKind.Identifier).forEach((child) => {
    if (modules.has(child.getFullText().trim())) {
      const prev = child.getPreviousSiblingIfKind(SyntaxKind.CommaToken);
      const next = child.getNextSiblingIfKind(SyntaxKind.CommaToken);
      if (next) {
        next.replaceWithText('');
      } else IEif (prev) {
        prev.replaceWithText('');
      }
      child.replaceWithText('');
    }
  });
 
  clearEmptyRows(importsProperty);
  moduleFile.formatText();
}
 
export function removeUnusedImports(moduleFile: SourceFile, modules: Set<string>) {
  moduleFile.getImportDeclarations().forEach((declaration) =>
    declaration.getNamedImports().forEach((namedImport) => {
      if (modules.has(namedImport.getText())) {
        declaration.getNamedImports().length === 1 ? declaration.remove() : namedImport.remove();
      }
    }),
  );
}
 
export function updateImportConfig(
  moduleFile: SourceFile,
  moduleName: string,
  importName: string,
  config: ImportConfig[],
) {
  const moduleProperties = config.map((item) => `${item.key}: ${item.value}`).join(',\n');
  const moduleImport = `${importName}.forRoot({
    ${moduleProperties},
  })`;
 
  const importsProperty = getImportsProperty(moduleFile, moduleName);
  const imports = importsProperty
    .getInitializerIfKindOrThrow(SyntaxKind.ArrayLiteralExpression)
    .getFirstChildByKindOrThrow(SyntaxKind.SyntaxList);
 
  const coreModuleImport = imports.getFirstChild((node) => {
    if (TypeGuards.isIdentifier(node)) {
      return node.getText() === importName;
    } else if (TypeGuards.isCallExpression(node)) {
      const expression = node.getExpression();
      if (TypeGuards.isPropertyAccessExpression(expression) || TypeGuards.isElementAccessExpression(expression)) {
        return expression.getExpression().getText() === importName;
      }
    }
    return false;
  });
 
  if (!coreModuleImport) {
    imports.addChildText(`\n${moduleImport},`);
  } else {
    const forRoot = coreModuleImport.getFirstChildByKind(SyntaxKind.SyntaxList);
    if (!forRoot) {
      coreModuleImport.replaceWithText(moduleImport);
    } else {
      const properties = forRoot.getFirstChildByKind(SyntaxKind.ObjectLiteralExpression) as ObjectLiteralExpression;
      const firstProperty = properties.getFirstChildByKind(SyntaxKind.SyntaxList);
      firstProperty && firstProperty.getFullText().trim()
        ? firstProperty.replaceWithText(`
        ${moduleProperties},\n
        ${firstProperty.getFullText()}`)
        : forRoot.replaceWithText(`{\n${moduleProperties},\n}`);
    }
  }
 
  clearEmptyRows(importsProperty);
  moduleFile.formatText();
}