function createFile(remoteFiles: Tree, { path, file }: { path: string, file: FileEntry }) {
    if (!file) {
        console.log(`missing: ${path}`)
    }

    remoteFiles.create(path, file.content);
}
Example #2
0
export function hasNgModuleImport(tree: Tree, modulePath: string, className: string): boolean {
  const moduleFileContent = tree.read(modulePath);

  if (!moduleFileContent) {
    throw new SchematicsException(`Could not read Angular module file: ${modulePath}`);
  }

  const parsedFile = ts.createSourceFile(modulePath, moduleFileContent.toString(),
      ts.ScriptTarget.Latest, true);
  const ngModuleMetadata = findNgModuleMetadata(parsedFile);

  if (!ngModuleMetadata) {
    throw new SchematicsException(`Could not find NgModule declaration inside: "${modulePath}"`);
  }

  for (let property of ngModuleMetadata!.properties) {
    if (!ts.isPropertyAssignment(property) || property.name.getText() !== 'imports' ||
        !ts.isArrayLiteralExpression(property.initializer)) {
      continue;
    }

    if (property.initializer.elements.some(element => element.getText() === className)) {
      return true;
    }
  }

  return false;
}
Example #3
0
export function createAppModuleWithEffects(
  tree: Tree,
  path: string,
  effects?: string
): Tree {
  tree.create(
    path || '/src/app/app.module.ts',
    `
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    import { EffectsModule } from '@ngrx/effects';

    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        ${effects}
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
  `
  );

  return tree;
}
Example #4
0
export function createReducers(tree: Tree, path?: string) {
  tree.create(
    path || '/src/app/reducers/index.ts',
    `
    import {
      ActionReducer,
      ActionReducerMap,
      createFeatureSelector,
      createSelector,
      MetaReducer
    } from '@ngrx/store';
    import { environment } from '../../environments/environment';
    
    export interface State {
    
    }
    
    export const reducers: ActionReducerMap<State> = {
    
    };
    
    
    export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];
  `
  );

  return tree;
}
Example #5
0
  it('works', () => {
    const runner = new SchematicTestRunner('schematics', collectionPath);
    const tree = runner.runSchematic('my-full-schematic', { name: 'str' }, Tree.empty());

    // Listing files
    expect(tree.files.sort()).toEqual(['/allo', '/hola', '/test1', '/test2']);
  });
Example #6
0
    return new Observable<Tree>(obs => {
      const input = new Readable({
        encoding: 'utf8',
        read(): void {
          this.push(buffer);
          this.push(null);
        },
      });

      const chunks: Array<Buffer> = [];
      const output = new Writable({
        write(chunk: string | Buffer, encoding: string, callback: Function): void {
          chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, encoding) : chunk);
          callback();
        },
        final(callback: (error?: Error) => void): void {
          const full = Buffer.concat(chunks);
          host.overwrite(path, full.toString());
          callback();
          obs.next(host);
          obs.complete();
        },
      });

      input.pipe(rewriter).pipe(output);
    });
Example #7
0
 it('should import the state path if provided', () => {
   const options = { ...defaultOptions, state: 'reducers' };
   appTree.create('/src/app/reducers', '');
   const tree = schematicRunner.runSchematic('container', options, appTree);
   const content = getFileContent(tree, '/src/app/foo/foo.component.ts');
   expect(content).toMatch(/import \* as fromStore from '..\/reducers';/);
 });
Example #8
0
    it('should not overwrite existing custom theme files', () => {
      appTree.create('/projects/material/custom-theme.scss', 'custom-theme');
      const tree = runner.runSchematic('ng-add-setup-project', {theme: 'custom'}, appTree);

      expect(tree.readContent('/projects/material/custom-theme.scss')).toBe('custom-theme',
          'Expected the old custom theme content to be unchanged.');
    });
  return (tree: Tree, _context: SchematicContext) => {

    const localFiles = url("./files")(_context) as Tree;
    const updateFiles = getUpdateFiles(localFiles);
    const createFiles = getCreateFiles(localFiles);

    if (updateFiles.length > 0) {
        updateFiles.forEach(f => updateFile(tree, f));
    }

    if (createFiles.length > 0) {
        createFiles.forEach(f => createFile(tree, f));
    }

    const config = tree.read(".angular-cli.json");
    if (config) {
        const asJson = JSON.parse(config.toString());
        asJson.apps[0].assets.push("config.json");
        tree.overwrite(".angular-cli.json", JSON.stringify(asJson, null, 2));
    }

    // angular 6
    const configA6 = tree.read("angular.json");
    if (configA6) {
        const asJson = JSON.parse(configA6.toString());

        Object.entries(asJson.projects).forEach(([,value] : any) => {
            const options = value.architect &&
                value.architect.build &&
                value.architect.build.options;

            const assets = options && options.assets;
            if (assets) {
                assets.push("src/config.json");
            }
            const styles = options && options.styles;
            if (styles) {
                styles.push("src/theme.css");
            }
        });

        tree.overwrite("angular.json", JSON.stringify(asJson, null, 2));
    }

    return tree;
  };
Example #10
0
export function addPackageToPackageJson(host: Tree, type: string, pkg: string, version: string) {
  if (host.exists('package.json')) {
    const sourceText = host.read('package.json')!.toString('utf-8');
    const json = JSON.parse(sourceText);
    if (!json[type]) {
      json[type] = {};
    }

    if (!json[type][pkg]) {
      json[type][pkg] = version;
    }

    host.overwrite('package.json', JSON.stringify(json, null, 2));
  }

  return host;
}
Example #11
0
// Looks up and finds the path to the app module (or other module if specified)
function findModuleFromOptions(host: Tree, options: ComponentOptions): Path | undefined {
    const modulePath = normalize(
      '/' + options.sourceDir + '/' + (options.appRoot) + '/' + options.module);
    const moduleBaseName = normalize(modulePath).split('/').pop();

    if (host.exists(modulePath)) {
      return normalize(modulePath);
    } else if (host.exists(modulePath + '.ts')) {
      return normalize(modulePath + '.ts');
    } else if (host.exists(modulePath + '.module.ts')) {
      return normalize(modulePath + '.module.ts');
    } else if (host.exists(modulePath + '/' + moduleBaseName + '.module.ts')) {
      return normalize(modulePath + '/' + moduleBaseName + '.module.ts');
    } else {
      throw new Error('Specified module does not exist');
    }
}
Example #12
0
  it('works', () => {
    const runner = new SchematicTestRunner('schematics', collectionPath);
    const tree = runner.runSchematic('add', {
      module: 'app'
    }, Tree.empty());

    expect(tree.files).toEqual(['/hello']);
  });
Example #13
0
 it('should find a module in a sub dir (2)', () => {
   tree.create('/projects/my-proj/src/admin/foo.module.ts', '');
   options.name = 'admin/hello';
   options.module = 'foo';
   options.path = '/projects/my-proj/src';
   const modPath = findModuleFromOptions(tree, options);
   expect(modPath).toEqual('/projects/my-proj/src/admin/foo.module.ts' as Path);
 });
Example #14
0
export function getSourceFile(host: Tree, path: string): ts.SourceFile {
  const buffer = host.read(path);
  if (!buffer) {
    throw new SchematicsException(`Could not find file for path: ${path}`);
  }
  const content = buffer.toString();
  return ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
}
Example #15
0
File: alain.ts Project: wexz/delon
function addImportToModule(
  host: Tree,
  path: string,
  symbolName: string,
  fileName: string,
) {
  const source = getTsSource(host, path);
  const change = insertImport(
    source,
    path,
    symbolName,
    fileName,
  ) as InsertChange;
  const declarationRecorder = host.beginUpdate(path);
  declarationRecorder.insertLeft(change.pos, change.toAdd);
  host.commitUpdate(declarationRecorder);
}
Example #16
0
 it('should find a module if flat is true', () => {
   tree.create('/projects/my-proj/src/module/app_test.module.ts', '');
   options.path = '/projects/my-proj/src';
   options.flat = true;
   options.name = '/module/directive';
   const modPath = findModuleFromOptions(tree, options);
   expect(modPath).toEqual('/projects/my-proj/src/module/app_test.module.ts' as Path);
 });
Example #17
0
 return (tree: Tree, context: SchematicContext) => {
   debugger;
   // We pass information back to the test.
   tree.create(
     (context.schematic.description as any).extra,  // tslint:disable-line:no-any
     (context.schematic.collection.description as any).extra,  // tslint:disable-line:no-any
   );
 };
Example #18
0
File: alain.ts Project: wexz/delon
function getTsSource(host: Tree, path: string): ts.SourceFile {
  const text = host.read(path);
  if (text === null) {
    throw new SchematicsException(`File ${path} does not exist.`);
  }
  const sourceText = text.toString('utf-8');
  return ts.createSourceFile(path, sourceText, ts.ScriptTarget.Latest, true);
}
Example #19
0
 return (host: Tree) => {
   const gitignore = '/.gitignore';
   if (!host.exists(gitignore)) {
     return host;
   }
   const gitIgnoreContent = host.read(gitignore).toString();
   if (gitIgnoreContent.includes('\n/bazel-out\n')) {
     return host;
   }
   const compiledOutput = '# compiled output\n';
   const index = gitIgnoreContent.indexOf(compiledOutput);
   const insertionIndex = index >= 0 ? index + compiledOutput.length : gitIgnoreContent.length;
   const recorder = host.beginUpdate(gitignore);
   recorder.insertRight(insertionIndex, '/bazel-out\n');
   host.commitUpdate(recorder);
   return host;
 };
Example #20
0
 /** Overwrites a target builder for the workspace in the given tree */
 function overwriteTargetBuilder(tree: Tree, targetName: string, newBuilder: string) {
   const workspace = getWorkspace(tree);
   const project = getProjectFromWorkspace(workspace);
   const targetConfig = project.architect && project.architect[targetName] ||
                        project.targets && project.targets[targetName];
   targetConfig['builder'] = newBuilder;
   tree.overwrite('/angular.json', JSON.stringify(workspace, null, 2));
 }
Example #21
0
export function findRoutingModule(tree: Tree, path: Path): Path | undefined {
  if (isOutsidePlayground(path)) {
    return;
  }

  const moduleFile = tree.getDir(path).subfiles.find(isRoutingModule);
  return moduleFile ? join(path, moduleFile) : findRoutingModule(tree, dirname(path));
}
Example #22
0
export function getWorkspace(host: Tree): Workspace {
  const configBuffer = host.read(ANGULAR_CLI_WORKSPACE_PATH);
  if (configBuffer === null) {
    throw new SchematicsException('Could not find angular.json');
  }

  return JSON.parse(configBuffer.toString());
}
Example #23
0
File: index.ts Project: iwe7/devkit
  return (host: Tree, context: SchematicContext) => {
    const packageName = '@angular/service-worker';
    context.logger.debug(`adding dependency (${packageName})`);
    const buffer = host.read(packageJsonPath);
    if (buffer === null) {
      throw new SchematicsException('Could not find package.json');
    }

    const packageObject = JSON.parse(buffer.toString());

    const ngCoreVersion = packageObject.dependencies['@angular/core'];
    packageObject.dependencies[packageName] = ngCoreVersion;

    host.overwrite(packageJsonPath, JSON.stringify(packageObject, null, 2));

    return host;
  };
Example #24
0
  return (host: Tree) => {
    const workspace = getWorkspace(host);
    const project = getProjectFromWorkspace(workspace, options.project);

    const stylesPath = getStylesPath(host, project);

    const buffer = host.read(stylesPath);
    if (buffer) {
      const src = buffer.toString();
      const insertion = new InsertChange(stylesPath, src.length, `\nbody { margin: 0; }\n`);
      const recorder = host.beginUpdate(stylesPath);
      recorder.insertLeft(insertion.pos, insertion.toAdd);
      host.commitUpdate(recorder);
    } else {
      console.warn(`Skipped body reset; could not find file: ${stylesPath}`);
    }
  };
Example #25
0
function readIntoSourceFile(host: Tree, modulePath: string) {
  const text = host.read(modulePath);
  if (text === null) {
    throw new SchematicsException(`File ${modulePath} does not exist.`);
  }

  return ts.createSourceFile(modulePath, text.toString('utf-8'), ts.ScriptTarget.Latest, true);
}
Example #26
0
export function removePackageJsonDependency(tree: Tree, name: string): void {
  const packageJson = _readPackageJson(tree);
  const recorder = tree.beginUpdate(pkgJsonPath);
  [
    NodeDependencyType.Default,
    NodeDependencyType.Dev,
    NodeDependencyType.Optional,
    NodeDependencyType.Peer,
  ].forEach(depType => {
    const depsNode = findPropertyInAstObject(packageJson, depType);
    if (depsNode !== null && depsNode.kind === 'object') {
      removePropertyInAstObject(recorder, depsNode, name);
    }
  });

  tree.commitUpdate(recorder);
}
Example #27
0
  return (host: Tree) => {
    const packageJson = 'package.json';
    if (!host.exists(packageJson)) {
      throw new Error(`Could not find ${packageJson}`);
    }
    const packageJsonContent = host.read(packageJson);
    if (!packageJsonContent) {
      throw new Error('Failed to read package.json content');
    }
    const jsonAst = parseJsonAst(packageJsonContent.toString()) as JsonAstObject;
    const deps = findPropertyInAstObject(jsonAst, 'dependencies') as JsonAstObject;
    const devDeps = findPropertyInAstObject(jsonAst, 'devDependencies') as JsonAstObject;

    const angularCoreNode = findPropertyInAstObject(deps, '@angular/core');
    if (!angularCoreNode) {
      throw new Error('@angular/core dependency not found in package.json');
    }
    const angularCoreVersion = angularCoreNode.value as string;

    const devDependencies: {[k: string]: string} = {
      '@angular/bazel': angularCoreVersion,
      '@bazel/bazel': '^0.24.0',
      '@bazel/ibazel': '^0.10.1',
      '@bazel/karma': '0.27.12',
      '@bazel/typescript': '0.27.12',
    };

    const recorder = host.beginUpdate(packageJson);
    for (const packageName of Object.keys(devDependencies)) {
      const existingDep = findPropertyInAstObject(deps, packageName);
      if (existingDep) {
        const content = packageJsonContent.toString();
        removeKeyValueInAstObject(recorder, content, deps, packageName);
      }
      const version = devDependencies[packageName];
      const indent = 4;
      if (findPropertyInAstObject(devDeps, packageName)) {
        replacePropertyInAstObject(recorder, devDeps, packageName, version, indent);
      } else {
        insertPropertyInAstObjectInOrder(recorder, devDeps, packageName, version, indent);
      }
    }
    host.commitUpdate(recorder);
    return host;
  };
Example #28
0
File: index.ts Project: iwe7/devkit
  return (host: Tree, context: SchematicContext) => {
    const workspace = getWorkspace(host);
    const project = workspace.projects[options.project as string];
    let path: string;
    if (project && project.architect && project.architect.build &&
        project.architect.build.options.index) {
      path = project.architect.build.options.index;
    } else {
      throw new SchematicsException('Could not find index file for the project');
    }
    const buffer = host.read(path);
    if (buffer === null) {
      throw new SchematicsException(`Could not read index file: ${path}`);
    }
    const content = buffer.toString();
    const lines = content.split('\n');
    let closingHeadTagLineIndex = -1;
    let closingHeadTagLine = '';
    lines.forEach((line, index) => {
      if (/<\/head>/.test(line) && closingHeadTagLineIndex === -1) {
        closingHeadTagLine = line;
        closingHeadTagLineIndex = index;
      }
    });

    const indent = getIndent(closingHeadTagLine) + '  ';
    const itemsToAdd = [
      '<link rel="manifest" href="manifest.json">',
      '<meta name="theme-color" content="#1976d2">',
    ];

    const textToInsert = itemsToAdd
      .map(text => indent + text)
      .join('\n');

    const updatedIndex = [
      ...lines.slice(0, closingHeadTagLineIndex),
      textToInsert,
      ...lines.slice(closingHeadTagLineIndex),
    ].join('\n');

    host.overwrite(path, updatedIndex);

    return host;
  };
Example #29
0
  return (host: Tree) => {
    const mainPath = normalize('/' + mainFile);
    let bootstrapCall: ts.Node | null = findBootstrapModuleCall(host, mainPath);
    if (bootstrapCall === null) {
      throw new SchematicsException('Bootstrap module not found.');
    }

    let bootstrapCallExpression: ts.Node | null = null;
    let currentCall = bootstrapCall;
    while (bootstrapCallExpression === null && currentCall.parent) {
      currentCall = currentCall.parent;
      if (ts.isExpressionStatement(currentCall) || ts.isVariableStatement(currentCall)) {
        bootstrapCallExpression = currentCall;
      }
    }
    bootstrapCall = currentCall;

    // In case the bootstrap code is a variable statement
    // we need to determine it's usage
    if (bootstrapCallExpression && ts.isVariableStatement(bootstrapCallExpression)) {
      const declaration = bootstrapCallExpression.declarationList.declarations[0];
      const bootstrapVar = (declaration.name as ts.Identifier).text;
      const sf = bootstrapCallExpression.getSourceFile();
      bootstrapCall = findCallExpressionNode(sf, bootstrapVar) || currentCall;
    }

    // indent contents
    const triviaWidth = bootstrapCall.getLeadingTriviaWidth();
    const beforeText = `document.addEventListener('DOMContentLoaded', () => {\n`
      + ' '.repeat(triviaWidth > 2 ? triviaWidth + 1 : triviaWidth);
    const afterText = `\n${triviaWidth > 2 ? ' '.repeat(triviaWidth - 1) : ''}});`;

    // in some cases we need to cater for a trailing semicolon such as;
    // bootstrap().catch(err => console.log(err));
    const lastToken = bootstrapCall.parent.getLastToken();
    let endPos = bootstrapCall.getEnd();
    if (lastToken && lastToken.kind === ts.SyntaxKind.SemicolonToken) {
      endPos = lastToken.getEnd();
    }

    const recorder = host.beginUpdate(mainPath);
    recorder.insertLeft(bootstrapCall.getStart(), beforeText);
    recorder.insertRight(endPos, afterText);
    host.commitUpdate(recorder);
  };
Example #30
0
function enableWebAnimationsAndGridSupport(tree: Tree, targetFile: string, polyfillsData: any): void {
  // Target the web-animations-js commented import statement and uncomment it.
  const webAnimationsLine = '// import \'web-animations-js\';';
  polyfillsData = polyfillsData.replace(webAnimationsLine,
    webAnimationsLine.substring(3, webAnimationsLine.length));

  polyfillsData = addIgxGridSupportForIe(polyfillsData);
  tree.overwrite(targetFile, polyfillsData);
}