8
8
9
9
import { analytics , tags } from '@angular-devkit/core' ;
10
10
import { NodePackageDoesNotSupportSchematics } from '@angular-devkit/schematics/tools' ;
11
+ import npa from 'npm-package-arg' ;
11
12
import { dirname , join } from 'path' ;
12
13
import { intersects , prerelease , rcompare , satisfies , valid , validRange } from 'semver' ;
13
14
import { PackageManager } from '../lib/config/workspace-schema' ;
@@ -28,8 +29,6 @@ import { Spinner } from '../utilities/spinner';
28
29
import { isTTY } from '../utilities/tty' ;
29
30
import { Schema as AddCommandSchema } from './add' ;
30
31
31
- const npa = require ( 'npm-package-arg' ) ;
32
-
33
32
export class AddCommand extends SchematicCommand < AddCommandSchema > {
34
33
override readonly allowPrivateSchematics = true ;
35
34
@@ -62,21 +61,12 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
62
61
return 1 ;
63
62
}
64
63
65
- if ( packageIdentifier . registry && this . isPackageInstalled ( packageIdentifier . name ) ) {
66
- let validVersion = false ;
67
- const installedVersion = await this . findProjectVersion ( packageIdentifier . name ) ;
68
- if ( installedVersion ) {
69
- if ( packageIdentifier . type === 'range' ) {
70
- validVersion = satisfies ( installedVersion , packageIdentifier . fetchSpec ) ;
71
- } else if ( packageIdentifier . type === 'version' ) {
72
- const v1 = valid ( packageIdentifier . fetchSpec ) ;
73
- const v2 = valid ( installedVersion ) ;
74
- validVersion = v1 !== null && v1 === v2 ;
75
- } else if ( ! packageIdentifier . rawSpec ) {
76
- validVersion = true ;
77
- }
78
- }
79
-
64
+ if (
65
+ packageIdentifier . name &&
66
+ packageIdentifier . registry &&
67
+ this . isPackageInstalled ( packageIdentifier . name )
68
+ ) {
69
+ const validVersion = await this . isProjectVersionValid ( packageIdentifier ) ;
80
70
if ( validVersion ) {
81
71
// Already installed so just run schematic
82
72
this . logger . info ( 'Skipping installation: Package already installed' ) ;
@@ -92,7 +82,7 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
92
82
const usingYarn = packageManager === PackageManager . Yarn ;
93
83
spinner . info ( `Using package manager: ${ colors . grey ( packageManager ) } ` ) ;
94
84
95
- if ( packageIdentifier . type === 'tag' && ! packageIdentifier . rawSpec ) {
85
+ if ( packageIdentifier . name && packageIdentifier . type === 'tag' && ! packageIdentifier . rawSpec ) {
96
86
// only package name provided; search for viable version
97
87
// plus special cases for packages that did not have peer deps setup
98
88
spinner . start ( 'Searching for compatible package version...' ) ;
@@ -126,7 +116,9 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
126
116
} else {
127
117
packageIdentifier = npa . resolve ( latestManifest . name , latestManifest . version ) ;
128
118
}
129
- spinner . succeed ( `Found compatible package version: ${ colors . grey ( packageIdentifier ) } .` ) ;
119
+ spinner . succeed (
120
+ `Found compatible package version: ${ colors . grey ( packageIdentifier . toString ( ) ) } .` ,
121
+ ) ;
130
122
} else if ( ! latestManifest || ( await this . hasMismatchedPeer ( latestManifest ) ) ) {
131
123
// 'latest' is invalid so search for most recent matching package
132
124
const versionManifests = Object . values ( packageMetadata . versions ) . filter (
@@ -147,11 +139,15 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
147
139
spinner . warn ( "Unable to find compatible package. Using 'latest'." ) ;
148
140
} else {
149
141
packageIdentifier = newIdentifier ;
150
- spinner . succeed ( `Found compatible package version: ${ colors . grey ( packageIdentifier ) } .` ) ;
142
+ spinner . succeed (
143
+ `Found compatible package version: ${ colors . grey ( packageIdentifier . toString ( ) ) } .` ,
144
+ ) ;
151
145
}
152
146
} else {
153
147
packageIdentifier = npa . resolve ( latestManifest . name , latestManifest . version ) ;
154
- spinner . succeed ( `Found compatible package version: ${ colors . grey ( packageIdentifier ) } .` ) ;
148
+ spinner . succeed (
149
+ `Found compatible package version: ${ colors . grey ( packageIdentifier . toString ( ) ) } .` ,
150
+ ) ;
155
151
}
156
152
}
157
153
@@ -160,7 +156,7 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
160
156
161
157
try {
162
158
spinner . start ( 'Loading package information from registry...' ) ;
163
- const manifest = await fetchPackageManifest ( packageIdentifier , this . logger , {
159
+ const manifest = await fetchPackageManifest ( packageIdentifier . toString ( ) , this . logger , {
164
160
registry : options . registry ,
165
161
verbose : options . verbose ,
166
162
usingYarn,
@@ -235,6 +231,28 @@ export class AddCommand extends SchematicCommand<AddCommandSchema> {
235
231
return this . executeSchematic ( collectionName , options [ '--' ] ) ;
236
232
}
237
233
234
+ private async isProjectVersionValid ( packageIdentifier : npa . Result ) : Promise < boolean > {
235
+ if ( ! packageIdentifier . name ) {
236
+ return false ;
237
+ }
238
+
239
+ let validVersion = false ;
240
+ const installedVersion = await this . findProjectVersion ( packageIdentifier . name ) ;
241
+ if ( installedVersion ) {
242
+ if ( packageIdentifier . type === 'range' && packageIdentifier . fetchSpec ) {
243
+ validVersion = satisfies ( installedVersion , packageIdentifier . fetchSpec ) ;
244
+ } else if ( packageIdentifier . type === 'version' ) {
245
+ const v1 = valid ( packageIdentifier . fetchSpec ) ;
246
+ const v2 = valid ( installedVersion ) ;
247
+ validVersion = v1 !== null && v1 === v2 ;
248
+ } else if ( ! packageIdentifier . rawSpec ) {
249
+ validVersion = true ;
250
+ }
251
+ }
252
+
253
+ return validVersion ;
254
+ }
255
+
238
256
override async reportAnalytics (
239
257
paths : string [ ] ,
240
258
options : AddCommandSchema & Arguments ,
0 commit comments