"use strict"; /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const core_1 = require("@angular-devkit/core"); const schematics_1 = require("@angular-devkit/schematics"); const tasks_1 = require("@angular-devkit/schematics/tasks"); const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript")); const ast_utils_1 = require("../utility/ast-utils"); const change_1 = require("../utility/change"); const dependencies_1 = require("../utility/dependencies"); const ng_ast_utils_1 = require("../utility/ng-ast-utils"); const paths_1 = require("../utility/paths"); const project_targets_1 = require("../utility/project-targets"); const workspace_1 = require("../utility/workspace"); function addDependencies() { return (host, context) => { const packageName = '@angular/service-worker'; context.logger.debug(`adding dependency (${packageName})`); const coreDep = (0, dependencies_1.getPackageJsonDependency)(host, '@angular/core'); if (coreDep === null) { throw new schematics_1.SchematicsException('Could not find version.'); } const serviceWorkerDep = { ...coreDep, name: packageName, }; (0, dependencies_1.addPackageJsonDependency)(host, serviceWorkerDep); return host; }; } function updateAppModule(mainPath) { return (host, context) => { context.logger.debug('Updating appmodule'); const modulePath = (0, ng_ast_utils_1.getAppModulePath)(host, mainPath); context.logger.debug(`module path: ${modulePath}`); // add import let moduleSource = getTsSourceFile(host, modulePath); let importModule = 'ServiceWorkerModule'; let importPath = '@angular/service-worker'; if (!(0, ast_utils_1.isImported)(moduleSource, importModule, importPath)) { const change = (0, ast_utils_1.insertImport)(moduleSource, modulePath, importModule, importPath); if (change) { const recorder = host.beginUpdate(modulePath); (0, change_1.applyToUpdateRecorder)(recorder, [change]); host.commitUpdate(recorder); } } // add import for environments // import { environment } from '../environments/environment'; moduleSource = getTsSourceFile(host, modulePath); const environmentExportName = (0, ast_utils_1.getEnvironmentExportName)(moduleSource); // if environemnt import already exists then use the found one // otherwise use the default name importModule = environmentExportName || 'environment'; // TODO: dynamically find environments relative path importPath = '../environments/environment'; if (!environmentExportName) { // if environment import was not found then insert the new one // with default path and default export name const change = (0, ast_utils_1.insertImport)(moduleSource, modulePath, importModule, importPath); if (change) { const recorder = host.beginUpdate(modulePath); (0, change_1.applyToUpdateRecorder)(recorder, [change]); host.commitUpdate(recorder); } } // register SW in app module const importText = core_1.tags.stripIndent ` ServiceWorkerModule.register('ngsw-worker.js', { enabled: ${importModule}.production, // Register the ServiceWorker as soon as the app is stable // or after 30 seconds (whichever comes first). registrationStrategy: 'registerWhenStable:30000' }) `; moduleSource = getTsSourceFile(host, modulePath); const metadataChanges = (0, ast_utils_1.addSymbolToNgModuleMetadata)(moduleSource, modulePath, 'imports', importText); if (metadataChanges) { const recorder = host.beginUpdate(modulePath); (0, change_1.applyToUpdateRecorder)(recorder, metadataChanges); host.commitUpdate(recorder); } return host; }; } function getTsSourceFile(host, path) { const buffer = host.read(path); if (!buffer) { throw new schematics_1.SchematicsException(`Could not read file (${path}).`); } const content = buffer.toString(); const source = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true); return source; } function default_1(options) { return async (host, context) => { const workspace = await (0, workspace_1.getWorkspace)(host); const project = workspace.projects.get(options.project); if (!project) { throw new schematics_1.SchematicsException(`Invalid project name (${options.project})`); } if (project.extensions.projectType !== 'application') { throw new schematics_1.SchematicsException(`Service worker requires a project type of "application".`); } const buildTarget = project.targets.get('build'); if (!buildTarget) { throw (0, project_targets_1.targetBuildNotFoundError)(); } const buildOptions = (buildTarget.options || {}); const root = project.root; buildOptions.serviceWorker = true; buildOptions.ngswConfigPath = (0, core_1.join)((0, core_1.normalize)(root), 'ngsw-config.json'); let { resourcesOutputPath = '' } = buildOptions; if (resourcesOutputPath) { resourcesOutputPath = (0, core_1.normalize)(`/${resourcesOutputPath}`); } const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [ (0, schematics_1.applyTemplates)({ ...options, resourcesOutputPath, relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(project.root), }), (0, schematics_1.move)(project.root), ]); context.addTask(new tasks_1.NodePackageInstallTask()); return (0, schematics_1.chain)([ (0, schematics_1.mergeWith)(templateSource), (0, workspace_1.updateWorkspace)(workspace), addDependencies(), updateAppModule(buildOptions.main), ]); }; } exports.default = default_1;