source: trip-planner-front/node_modules/@angular/cli/commands/add-impl.js@ 1ad8e64

Last change on this file since 1ad8e64 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 13.9 KB
RevLine 
[6a3a178]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 __importDefault = (this && this.__importDefault) || function (mod) {
10 return (mod && mod.__esModule) ? mod : { "default": mod };
11};
12Object.defineProperty(exports, "__esModule", { value: true });
13exports.AddCommand = void 0;
14const core_1 = require("@angular-devkit/core");
15const tools_1 = require("@angular-devkit/schematics/tools");
16const npm_package_arg_1 = __importDefault(require("npm-package-arg"));
17const path_1 = require("path");
18const semver_1 = require("semver");
19const workspace_schema_1 = require("../lib/config/workspace-schema");
20const analytics_1 = require("../models/analytics");
21const schematic_command_1 = require("../models/schematic-command");
22const color_1 = require("../utilities/color");
23const install_package_1 = require("../utilities/install-package");
24const package_manager_1 = require("../utilities/package-manager");
25const package_metadata_1 = require("../utilities/package-metadata");
26const prompt_1 = require("../utilities/prompt");
27const spinner_1 = require("../utilities/spinner");
28const tty_1 = require("../utilities/tty");
29class AddCommand extends schematic_command_1.SchematicCommand {
30 constructor() {
31 super(...arguments);
32 this.allowPrivateSchematics = true;
33 }
34 async initialize(options) {
35 if (options.registry) {
36 return super.initialize({ ...options, packageRegistry: options.registry });
37 }
38 else {
39 return super.initialize(options);
40 }
41 }
42 async run(options) {
43 var _a;
44 await package_manager_1.ensureCompatibleNpm(this.context.root);
45 if (!options.collection) {
46 this.logger.fatal(`The "ng add" command requires a name argument to be specified eg. ` +
47 `${color_1.colors.yellow('ng add [name] ')}. For more details, use "ng help".`);
48 return 1;
49 }
50 let packageIdentifier;
51 try {
52 packageIdentifier = npm_package_arg_1.default(options.collection);
53 }
54 catch (e) {
55 this.logger.error(e.message);
56 return 1;
57 }
58 if (packageIdentifier.name &&
59 packageIdentifier.registry &&
60 this.isPackageInstalled(packageIdentifier.name)) {
61 const validVersion = await this.isProjectVersionValid(packageIdentifier);
62 if (validVersion) {
63 // Already installed so just run schematic
64 this.logger.info('Skipping installation: Package already installed');
65 return this.executeSchematic(packageIdentifier.name, options['--']);
66 }
67 }
68 const spinner = new spinner_1.Spinner();
69 spinner.start('Determining package manager...');
70 const packageManager = await package_manager_1.getPackageManager(this.context.root);
71 const usingYarn = packageManager === workspace_schema_1.PackageManager.Yarn;
72 spinner.info(`Using package manager: ${color_1.colors.grey(packageManager)}`);
73 if (packageIdentifier.name && packageIdentifier.type === 'tag' && !packageIdentifier.rawSpec) {
74 // only package name provided; search for viable version
75 // plus special cases for packages that did not have peer deps setup
76 spinner.start('Searching for compatible package version...');
77 let packageMetadata;
78 try {
79 packageMetadata = await package_metadata_1.fetchPackageMetadata(packageIdentifier.name, this.logger, {
80 registry: options.registry,
81 usingYarn,
82 verbose: options.verbose,
83 });
84 }
85 catch (e) {
86 spinner.fail('Unable to load package information from registry: ' + e.message);
87 return 1;
88 }
89 const latestManifest = packageMetadata.tags['latest'];
90 if (latestManifest && Object.keys(latestManifest.peerDependencies).length === 0) {
91 if (latestManifest.name === '@angular/pwa') {
92 const version = await this.findProjectVersion('@angular/cli');
93 const semverOptions = { includePrerelease: true };
94 if (version &&
95 ((semver_1.validRange(version) && semver_1.intersects(version, '7', semverOptions)) ||
96 (semver_1.valid(version) && semver_1.satisfies(version, '7', semverOptions)))) {
97 packageIdentifier = npm_package_arg_1.default.resolve('@angular/pwa', '0.12');
98 }
99 }
100 else {
101 packageIdentifier = npm_package_arg_1.default.resolve(latestManifest.name, latestManifest.version);
102 }
103 spinner.succeed(`Found compatible package version: ${color_1.colors.grey(packageIdentifier.toString())}.`);
104 }
105 else if (!latestManifest || (await this.hasMismatchedPeer(latestManifest))) {
106 // 'latest' is invalid so search for most recent matching package
107 const versionManifests = Object.values(packageMetadata.versions).filter((value) => !semver_1.prerelease(value.version) && !value.deprecated);
108 versionManifests.sort((a, b) => semver_1.rcompare(a.version, b.version, true));
109 let newIdentifier;
110 for (const versionManifest of versionManifests) {
111 if (!(await this.hasMismatchedPeer(versionManifest))) {
112 newIdentifier = npm_package_arg_1.default.resolve(packageIdentifier.name, versionManifest.version);
113 break;
114 }
115 }
116 if (!newIdentifier) {
117 spinner.warn("Unable to find compatible package. Using 'latest'.");
118 }
119 else {
120 packageIdentifier = newIdentifier;
121 spinner.succeed(`Found compatible package version: ${color_1.colors.grey(packageIdentifier.toString())}.`);
122 }
123 }
124 else {
125 packageIdentifier = npm_package_arg_1.default.resolve(latestManifest.name, latestManifest.version);
126 spinner.succeed(`Found compatible package version: ${color_1.colors.grey(packageIdentifier.toString())}.`);
127 }
128 }
129 let collectionName = packageIdentifier.name;
130 let savePackage;
131 try {
132 spinner.start('Loading package information from registry...');
133 const manifest = await package_metadata_1.fetchPackageManifest(packageIdentifier.toString(), this.logger, {
134 registry: options.registry,
135 verbose: options.verbose,
136 usingYarn,
137 });
138 savePackage = (_a = manifest['ng-add']) === null || _a === void 0 ? void 0 : _a.save;
139 collectionName = manifest.name;
140 if (await this.hasMismatchedPeer(manifest)) {
141 spinner.warn('Package has unmet peer dependencies. Adding the package may not succeed.');
142 }
143 else {
144 spinner.succeed(`Package information loaded.`);
145 }
146 }
147 catch (e) {
148 spinner.fail(`Unable to fetch package information for '${packageIdentifier}': ${e.message}`);
149 return 1;
150 }
151 if (!options.skipConfirmation) {
152 const confirmationResponse = await prompt_1.askConfirmation(`\nThe package ${color_1.colors.blue(packageIdentifier.raw)} will be installed and executed.\n` +
153 'Would you like to proceed?', true, false);
154 if (!confirmationResponse) {
155 if (!tty_1.isTTY()) {
156 this.logger.error('No terminal detected. ' +
157 `'--skip-confirmation' can be used to bypass installation confirmation. ` +
158 `Ensure package name is correct prior to '--skip-confirmation' option usage.`);
159 }
160 this.logger.error('Command aborted.');
161 return 1;
162 }
163 }
164 if (savePackage === false) {
165 // Temporary packages are located in a different directory
166 // Hence we need to resolve them using the temp path
167 const { status, tempNodeModules } = await install_package_1.installTempPackage(packageIdentifier.raw, packageManager, options.registry ? [`--registry="${options.registry}"`] : undefined);
168 const resolvedCollectionPath = require.resolve(path_1.join(collectionName, 'package.json'), {
169 paths: [tempNodeModules],
170 });
171 if (status !== 0) {
172 return status;
173 }
174 collectionName = path_1.dirname(resolvedCollectionPath);
175 }
176 else {
177 const status = await install_package_1.installPackage(packageIdentifier.raw, packageManager, savePackage, options.registry ? [`--registry="${options.registry}"`] : undefined);
178 if (status !== 0) {
179 return status;
180 }
181 }
182 return this.executeSchematic(collectionName, options['--']);
183 }
184 async isProjectVersionValid(packageIdentifier) {
185 if (!packageIdentifier.name) {
186 return false;
187 }
188 let validVersion = false;
189 const installedVersion = await this.findProjectVersion(packageIdentifier.name);
190 if (installedVersion) {
191 if (packageIdentifier.type === 'range' && packageIdentifier.fetchSpec) {
192 validVersion = semver_1.satisfies(installedVersion, packageIdentifier.fetchSpec);
193 }
194 else if (packageIdentifier.type === 'version') {
195 const v1 = semver_1.valid(packageIdentifier.fetchSpec);
196 const v2 = semver_1.valid(installedVersion);
197 validVersion = v1 !== null && v1 === v2;
198 }
199 else if (!packageIdentifier.rawSpec) {
200 validVersion = true;
201 }
202 }
203 return validVersion;
204 }
205 async reportAnalytics(paths, options, dimensions = [], metrics = []) {
206 const collection = options.collection;
207 // Add the collection if it's safe listed.
208 if (collection && analytics_1.isPackageNameSafeForAnalytics(collection)) {
209 dimensions[core_1.analytics.NgCliAnalyticsDimensions.NgAddCollection] = collection;
210 }
211 else {
212 delete dimensions[core_1.analytics.NgCliAnalyticsDimensions.NgAddCollection];
213 }
214 return super.reportAnalytics(paths, options, dimensions, metrics);
215 }
216 isPackageInstalled(name) {
217 try {
218 require.resolve(path_1.join(name, 'package.json'), { paths: [this.context.root] });
219 return true;
220 }
221 catch (e) {
222 if (e.code !== 'MODULE_NOT_FOUND') {
223 throw e;
224 }
225 }
226 return false;
227 }
228 async executeSchematic(collectionName, options = []) {
229 const runOptions = {
230 schematicOptions: options,
231 collectionName,
232 schematicName: 'ng-add',
233 dryRun: false,
234 force: false,
235 };
236 try {
237 return await this.runSchematic(runOptions);
238 }
239 catch (e) {
240 if (e instanceof tools_1.NodePackageDoesNotSupportSchematics) {
241 this.logger.error(core_1.tags.oneLine `
242 The package that you are trying to add does not support schematics. You can try using
243 a different version of the package or contact the package author to add ng-add support.
244 `);
245 return 1;
246 }
247 throw e;
248 }
249 }
250 async findProjectVersion(name) {
251 let installedPackage;
252 try {
253 installedPackage = require.resolve(path_1.join(name, 'package.json'), {
254 paths: [this.context.root],
255 });
256 }
257 catch { }
258 if (installedPackage) {
259 try {
260 const installed = await package_metadata_1.fetchPackageManifest(path_1.dirname(installedPackage), this.logger);
261 return installed.version;
262 }
263 catch { }
264 }
265 let projectManifest;
266 try {
267 projectManifest = await package_metadata_1.fetchPackageManifest(this.context.root, this.logger);
268 }
269 catch { }
270 if (projectManifest) {
271 const version = projectManifest.dependencies[name] || projectManifest.devDependencies[name];
272 if (version) {
273 return version;
274 }
275 }
276 return null;
277 }
278 async hasMismatchedPeer(manifest) {
279 for (const peer in manifest.peerDependencies) {
280 let peerIdentifier;
281 try {
282 peerIdentifier = npm_package_arg_1.default.resolve(peer, manifest.peerDependencies[peer]);
283 }
284 catch {
285 this.logger.warn(`Invalid peer dependency ${peer} found in package.`);
286 continue;
287 }
288 if (peerIdentifier.type === 'version' || peerIdentifier.type === 'range') {
289 try {
290 const version = await this.findProjectVersion(peer);
291 if (!version) {
292 continue;
293 }
294 const options = { includePrerelease: true };
295 if (!semver_1.intersects(version, peerIdentifier.rawSpec, options) &&
296 !semver_1.satisfies(version, peerIdentifier.rawSpec, options)) {
297 return true;
298 }
299 }
300 catch {
301 // Not found or invalid so ignore
302 continue;
303 }
304 }
305 else {
306 // type === 'tag' | 'file' | 'directory' | 'remote' | 'git'
307 // Cannot accurately compare these as the tag/location may have changed since install
308 }
309 }
310 return false;
311 }
312}
313exports.AddCommand = AddCommand;
Note: See TracBrowser for help on using the repository browser.