@@ -14,6 +14,7 @@ import {
14
14
Tree ,
15
15
} from '@angular-devkit/schematics' ;
16
16
import { NodePackageInstallTask , RunSchematicTask } from '@angular-devkit/schematics/tasks' ;
17
+ import * as npa from 'npm-package-arg' ;
17
18
import { Observable , from as observableFrom , of } from 'rxjs' ;
18
19
import { map , mergeMap , reduce , switchMap } from 'rxjs/operators' ;
19
20
import * as semver from 'semver' ;
@@ -788,7 +789,7 @@ function _addPeerDependencies(
788
789
}
789
790
790
791
791
- function _getAllDependencies ( tree : Tree ) : Map < string , VersionRange > {
792
+ function _getAllDependencies ( tree : Tree ) : Array < readonly [ string , VersionRange ] > {
792
793
const packageJsonContent = tree . read ( '/package.json' ) ;
793
794
if ( ! packageJsonContent ) {
794
795
throw new SchematicsException ( 'Could not find a package.json. Are you in a Node project?' ) ;
@@ -801,11 +802,11 @@ function _getAllDependencies(tree: Tree): Map<string, VersionRange> {
801
802
throw new SchematicsException ( 'package.json could not be parsed: ' + e . message ) ;
802
803
}
803
804
804
- return new Map < string , VersionRange > ( [
805
- ...Object . entries ( packageJson . peerDependencies || { } ) ,
806
- ...Object . entries ( packageJson . devDependencies || { } ) ,
807
- ...Object . entries ( packageJson . dependencies || { } ) ,
808
- ] as [ string , VersionRange ] [ ] ) ;
805
+ return [
806
+ ...Object . entries ( packageJson . peerDependencies || { } ) as Array < [ string , VersionRange ] > ,
807
+ ...Object . entries ( packageJson . devDependencies || { } ) as Array < [ string , VersionRange ] > ,
808
+ ...Object . entries ( packageJson . dependencies || { } ) as Array < [ string , VersionRange ] > ,
809
+ ] ;
809
810
}
810
811
811
812
function _formatVersion ( version : string | undefined ) {
@@ -826,6 +827,16 @@ function _formatVersion(version: string | undefined) {
826
827
return version ;
827
828
}
828
829
830
+ /**
831
+ * Returns whether or not the given package specifier (the value string in a
832
+ * `package.json` dependency) is hosted in the NPM registry.
833
+ * @throws When the specifier cannot be parsed.
834
+ */
835
+ function isPkgFromRegistry ( name : string , specifier : string ) : boolean {
836
+ const result = npa . resolve ( name , specifier ) ;
837
+
838
+ return ! ! result . registry ;
839
+ }
829
840
830
841
export default function ( options : UpdateSchema ) : Rule {
831
842
if ( ! options . packages ) {
@@ -847,14 +858,23 @@ export default function(options: UpdateSchema): Rule {
847
858
848
859
options . from = _formatVersion ( options . from ) ;
849
860
options . to = _formatVersion ( options . to ) ;
861
+ const usingYarn = options . packageManager === 'yarn' ;
850
862
851
863
return ( tree : Tree , context : SchematicContext ) => {
852
864
const logger = context . logger ;
853
- const allDependencies = _getAllDependencies ( tree ) ;
854
- const packages = _buildPackageList ( options , allDependencies , logger ) ;
855
- const usingYarn = options . packageManager === 'yarn' ;
865
+ const npmDeps = new Map ( _getAllDependencies ( tree ) . filter ( ( [ name , specifier ] ) => {
866
+ try {
867
+ return isPkgFromRegistry ( name , specifier ) ;
868
+ } catch {
869
+ // Abort on failure because package.json is malformed.
870
+ throw new SchematicsException (
871
+ `Failed to parse dependency "${ name } " with specifier "${ specifier } "`
872
+ + ` from package.json. Is the specifier malformed?` ) ;
873
+ }
874
+ } ) ) ;
875
+ const packages = _buildPackageList ( options , npmDeps , logger ) ;
856
876
857
- return observableFrom ( [ ... allDependencies . keys ( ) ] ) . pipe (
877
+ return observableFrom ( npmDeps . keys ( ) ) . pipe (
858
878
// Grab all package.json from the npm repository. This requires a lot of HTTP calls so we
859
879
// try to parallelize as many as possible.
860
880
mergeMap ( depName => getNpmPackageJson (
@@ -899,8 +919,8 @@ export default function(options: UpdateSchema): Rule {
899
919
do {
900
920
lastPackagesSize = packages . size ;
901
921
npmPackageJsonMap . forEach ( ( npmPackageJson ) => {
902
- _addPackageGroup ( tree , packages , allDependencies , npmPackageJson , logger ) ;
903
- _addPeerDependencies ( tree , packages , allDependencies , npmPackageJson , npmPackageJsonMap , logger ) ;
922
+ _addPackageGroup ( tree , packages , npmDeps , npmPackageJson , logger ) ;
923
+ _addPeerDependencies ( tree , packages , npmDeps , npmPackageJson , npmPackageJsonMap , logger ) ;
904
924
} ) ;
905
925
} while ( packages . size > lastPackagesSize ) ;
906
926
@@ -909,7 +929,7 @@ export default function(options: UpdateSchema): Rule {
909
929
npmPackageJsonMap . forEach ( ( npmPackageJson ) => {
910
930
packageInfoMap . set (
911
931
npmPackageJson . name ,
912
- _buildPackageInfo ( tree , packages , allDependencies , npmPackageJson , logger ) ,
932
+ _buildPackageInfo ( tree , packages , npmDeps , npmPackageJson , logger ) ,
913
933
) ;
914
934
} ) ;
915
935
0 commit comments