UNPKG

7.54 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright Google LLC All Rights Reserved.
5 *
6 * Use of this source code is governed by an MIT-style license that can be
7 * found in the LICENSE file at https://angular.io/license
8 */
9var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10 if (k2 === undefined) k2 = k;
11 var desc = Object.getOwnPropertyDescriptor(m, k);
12 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13 desc = { enumerable: true, get: function() { return m[k]; } };
14 }
15 Object.defineProperty(o, k2, desc);
16}) : (function(o, m, k, k2) {
17 if (k2 === undefined) k2 = k;
18 o[k2] = m[k];
19}));
20var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21 Object.defineProperty(o, "default", { enumerable: true, value: v });
22}) : function(o, v) {
23 o["default"] = v;
24});
25var __importStar = (this && this.__importStar) || function (mod) {
26 if (mod && mod.__esModule) return mod;
27 var result = {};
28 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
29 __setModuleDefault(result, mod);
30 return result;
31};
32Object.defineProperty(exports, "__esModule", { value: true });
33const core_1 = require("@angular-devkit/core");
34const schematics_1 = require("@angular-devkit/schematics");
35const standalone_1 = require("../private/standalone");
36const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
37const utility_1 = require("../utility");
38const ast_utils_1 = require("../utility/ast-utils");
39const change_1 = require("../utility/change");
40const dependencies_1 = require("../utility/dependencies");
41const ng_ast_utils_1 = require("../utility/ng-ast-utils");
42const paths_1 = require("../utility/paths");
43const project_targets_1 = require("../utility/project-targets");
44const workspace_models_1 = require("../utility/workspace-models");
45function addDependencies() {
46 return (host) => {
47 const coreDep = (0, dependencies_1.getPackageJsonDependency)(host, '@angular/core');
48 if (!coreDep) {
49 throw new schematics_1.SchematicsException('Could not find "@angular/core" version.');
50 }
51 return (0, utility_1.addDependency)('@angular/service-worker', coreDep.version);
52 };
53}
54function updateAppModule(mainPath) {
55 return (host, context) => {
56 context.logger.debug('Updating appmodule');
57 const modulePath = (0, ng_ast_utils_1.getAppModulePath)(host, mainPath);
58 context.logger.debug(`module path: ${modulePath}`);
59 addImport(host, modulePath, 'ServiceWorkerModule', '@angular/service-worker');
60 addImport(host, modulePath, 'isDevMode', '@angular/core');
61 // register SW in application module
62 const importText = core_1.tags.stripIndent `
63 ServiceWorkerModule.register('ngsw-worker.js', {
64 enabled: !isDevMode(),
65 // Register the ServiceWorker as soon as the application is stable
66 // or after 30 seconds (whichever comes first).
67 registrationStrategy: 'registerWhenStable:30000'
68 })
69 `;
70 const moduleSource = getTsSourceFile(host, modulePath);
71 const metadataChanges = (0, ast_utils_1.addSymbolToNgModuleMetadata)(moduleSource, modulePath, 'imports', importText);
72 if (metadataChanges) {
73 const recorder = host.beginUpdate(modulePath);
74 (0, change_1.applyToUpdateRecorder)(recorder, metadataChanges);
75 host.commitUpdate(recorder);
76 }
77 return host;
78 };
79}
80function addProvideServiceWorker(mainPath) {
81 return (host) => {
82 const updatedFilePath = (0, standalone_1.addFunctionalProvidersToStandaloneBootstrap)(host, mainPath, 'provideServiceWorker', '@angular/service-worker', [
83 ts.factory.createStringLiteral('ngsw-worker.js', true),
84 ts.factory.createObjectLiteralExpression([
85 ts.factory.createPropertyAssignment(ts.factory.createIdentifier('enabled'), ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.ExclamationToken, ts.factory.createCallExpression(ts.factory.createIdentifier('isDevMode'), undefined, []))),
86 ts.factory.createPropertyAssignment(ts.factory.createIdentifier('registrationStrategy'), ts.factory.createStringLiteral('registerWhenStable:30000', true)),
87 ], true),
88 ]);
89 addImport(host, updatedFilePath, 'isDevMode', '@angular/core');
90 return host;
91 };
92}
93function getTsSourceFile(host, path) {
94 const content = host.readText(path);
95 const source = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
96 return source;
97}
98function default_1(options) {
99 return async (host) => {
100 const workspace = await (0, utility_1.readWorkspace)(host);
101 const project = workspace.projects.get(options.project);
102 if (!project) {
103 throw new schematics_1.SchematicsException(`Invalid project name (${options.project})`);
104 }
105 if (project.extensions.projectType !== 'application') {
106 throw new schematics_1.SchematicsException(`Service worker requires a project type of "application".`);
107 }
108 const buildTarget = project.targets.get('build');
109 if (!buildTarget) {
110 throw (0, project_targets_1.targetBuildNotFoundError)();
111 }
112 const buildOptions = buildTarget.options;
113 let browserEntryPoint;
114 let resourcesOutputPath = '';
115 const ngswConfigPath = (0, core_1.join)((0, core_1.normalize)(project.root), 'ngsw-config.json');
116 if (buildTarget.builder === workspace_models_1.Builders.Application) {
117 browserEntryPoint = buildOptions.browser;
118 resourcesOutputPath = '/media';
119 const productionConf = buildTarget.configurations?.production;
120 if (productionConf) {
121 productionConf.serviceWorker = ngswConfigPath;
122 }
123 }
124 else {
125 browserEntryPoint = buildOptions.main;
126 buildOptions.serviceWorker = true;
127 buildOptions.ngswConfigPath = ngswConfigPath;
128 if (buildOptions.resourcesOutputPath) {
129 resourcesOutputPath = (0, core_1.normalize)(`/${buildOptions.resourcesOutputPath}`);
130 }
131 }
132 await (0, utility_1.writeWorkspace)(host, workspace);
133 return (0, schematics_1.chain)([
134 addDependencies(),
135 (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files'), [
136 (0, schematics_1.applyTemplates)({
137 ...options,
138 resourcesOutputPath,
139 relativePathToWorkspaceRoot: (0, paths_1.relativePathToWorkspaceRoot)(project.root),
140 }),
141 (0, schematics_1.move)(project.root),
142 ])),
143 (0, ng_ast_utils_1.isStandaloneApp)(host, browserEntryPoint)
144 ? addProvideServiceWorker(browserEntryPoint)
145 : updateAppModule(browserEntryPoint),
146 ]);
147 };
148}
149exports.default = default_1;
150function addImport(host, filePath, symbolName, moduleName) {
151 const moduleSource = getTsSourceFile(host, filePath);
152 const change = (0, ast_utils_1.insertImport)(moduleSource, filePath, symbolName, moduleName);
153 if (change) {
154 const recorder = host.beginUpdate(filePath);
155 (0, change_1.applyToUpdateRecorder)(recorder, [change]);
156 host.commitUpdate(recorder);
157 }
158}