UNPKG

@nrwl/schematics

Version:

Extensible Dev Tools for Monorepos: Schematics

163 lines (162 loc) 7.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const schematics_1 = require("@angular-devkit/schematics"); const core_1 = require("@angular-devkit/core"); const path_1 = require("path"); const workspace_1 = require("@nrwl/workspace"); const workspace_2 = require("@nrwl/workspace"); const workspace_3 = require("@nrwl/workspace"); const literals_1 = require("@angular-devkit/core/src/utils/literals"); function getBuilders(project) { return Array.from(new Set(Object.values(project.architect).map(target => target.builder))); } const builderTypes = { '@angular-devkit/build-angular:karma': ['jasmine'], '@angular-devkit/build-angular:protractor': ['jasmine', 'jasminewd2'], '@nrwl/builders:jest': ['jest', 'node'], '@nrwl/builers:cypress': ['cypress'] }; function getTypes(host, project, context) { let types = []; const tsConfigPaths = getTsConfigs(project, host); const tsConfigs = tsConfigPaths.map(tsconfigPath => workspace_1.readJsonInTree(host, tsconfigPath)); const tsConfigsWithNoTypes = tsConfigPaths.filter(tsconfigPath => { const tsconfig = workspace_1.readJsonInTree(host, tsconfigPath); return !tsconfig.compilerOptions.types; }); if (tsConfigsWithNoTypes.length > 0) { context.logger.warn(literals_1.stripIndents `The following tsconfigs had no types defined: ${tsConfigsWithNoTypes.join(',')}`); return undefined; } types = types.concat(...tsConfigs.map(tsconfig => tsconfig.compilerOptions.types || [])); types = types.concat(...getBuilders(project) .filter(builder => builder in builderTypes) .map(builder => builderTypes[builder])); return types.filter((type, i, arr) => arr.indexOf(type) === i); // dedupe the array; } function createTsConfig(project) { return (host, context) => { const tsConfigPath = core_1.join(core_1.normalize(project.root), 'tsconfig.json'); if (host.exists(tsConfigPath)) { return schematics_1.noop(); } host.create(tsConfigPath, '{}'); const types = getTypes(host, project, context); if (types === undefined) { context.logger.warn(literals_1.stripIndents `No types array was added to ${tsConfigPath} meaning the editor might encounter conflicts for types.}`); } return workspace_1.updateJsonInTree(tsConfigPath, () => { return { extends: `${workspace_3.offsetFromRoot(project.root)}tsconfig.json`, compilerOptions: { types } }; }); }; } function getTsConfigs(project, host, context) { return Array.from(new Set(Object.values(project.architect) .reduce((arr, target) => { return [ ...arr, ...(target.options ? [target.options] : []), ...Object.values(target.configurations || {}) ]; }, []) .reduce((arr, options) => { if (!options.tsConfig) { return arr; } if (!Array.isArray(options.tsConfig)) { return arr.includes(options.tsConfig) ? arr : [...arr, options.tsConfig]; } return [ ...arr, ...options.tsConfig.filter(tsconfig => !arr.includes(tsconfig)) ]; }, []) .filter(tsconfig => { if (!host.exists(tsconfig)) { if (context) { context.logger.warn(`${tsconfig} does not exist but is set as a "tsConfig" in /angular.json`); } return false; } return true; }) .map(tsconfig => { return core_1.normalize(tsconfig); }))); } function updateTsConfig(project, tsconfig) { return workspace_1.updateJsonInTree(tsconfig, json => { json.extends = core_1.dirname(tsconfig) === core_1.normalize(project.root) ? './tsconfig.json' : path_1.relative(core_1.dirname(tsconfig), core_1.join(project.root, 'tsconfig.json')); return json; }); } function updateTsConfigs(project) { return (host, context) => { return schematics_1.chain(getTsConfigs(project, host, context).map(tsconfig => updateTsConfig(project, tsconfig))); }; } function fixCypressConfigs(host, context) { const workspaceJson = workspace_1.readJsonInTree(host, 'angular.json'); return schematics_1.chain(Object.entries(workspaceJson.projects) .filter(([key, project]) => project.architect.e2e && project.architect.e2e.builder === '@nrwl/builders:cypress' && project.architect.lint && !host.exists(project.architect.lint.options.tsConfig) && host.exists(core_1.join(project.root, 'tsconfig.e2e.json'))) .map(([key, project]) => fixCypressConfig(project, key))); } function fixCypressConfig(project, projectKey) { return workspace_1.updateWorkspaceInTree(workspaceJson => { workspaceJson.projects[projectKey].architect.lint.options.tsConfig = core_1.join(project.root, 'tsconfig.e2e.json'); return workspaceJson; }); } function updateProjects(host) { const { projects } = workspace_1.readJsonInTree(host, workspace_2.getWorkspacePath(host)); return schematics_1.chain(Object.entries(projects).map(([key, project]) => { return schematics_1.chain([createTsConfig(project), updateTsConfigs(project)]); })); } function displayInformation(host, context) { context.logger .info(literals_1.stripIndents `With this update, we are changing the structure of the tsconfig files. A tsconfig.json has been added to all project roots which is used by editors to provide intellisense. The tsconfig.(app|lib|spec|e2e).json files now all extend off of the tsconfig.json in the project root. To find out more, visit our wiki: https://github.com/nrwl/nx/wiki/Workspace-Organization#tsconfigs`); } function switchToEs2015(host, context) { return workspace_1.updateJsonInTree('tsconfig.json', json => { json.compilerOptions = json.compilerOptions || {}; json.compilerOptions.module = 'es2015'; context.logger.info('Typescript has been set to compile with es2015 modules'); return json; }); } const updateAngularCLI = workspace_3.addUpdateTask('@angular/cli', '7.1.0'); function default_1() { return schematics_1.chain([ workspace_1.updateJsonInTree('package.json', json => { json.dependencies = json.dependencies || {}; json.dependencies = Object.assign({}, json.dependencies, { '@ngrx/effects': '6.1.2', '@ngrx/router-store': '6.1.2', '@ngrx/store': '6.1.2' }); json.devDependencies = json.devDependencies || {}; json.devDependencies = Object.assign({}, json.devDependencies, { '@ngrx/schematics': '6.1.2', '@ngrx/store-devtools': '6.1.2' }); return json; }), fixCypressConfigs, switchToEs2015, updateProjects, displayInformation, updateAngularCLI ]); } exports.default = default_1;