@@ -114,7 +114,7 @@ export class PackageJsonEditor {
114114 const _onChange : ( ) => void = this . _onChange . bind ( this ) ;
115115
116116 try {
117- Object . keys ( dependencies || { } ) . forEach ( ( packageName : string ) => {
117+ Object . entries ( dependencies || { } ) . forEach ( ( [ packageName , version ] : [ string , string ] ) => {
118118 if ( Object . prototype . hasOwnProperty . call ( optionalDependencies , packageName ) ) {
119119 throw new Error (
120120 `The package "${ packageName } " cannot be listed in both ` +
@@ -129,11 +129,11 @@ export class PackageJsonEditor {
129129
130130 this . _dependencies . set (
131131 packageName ,
132- new PackageJsonDependency ( packageName , dependencies [ packageName ] , DependencyType . Regular , _onChange )
132+ new PackageJsonDependency ( packageName , version , DependencyType . Regular , _onChange )
133133 ) ;
134134 } ) ;
135135
136- Object . keys ( optionalDependencies || { } ) . forEach ( ( packageName : string ) => {
136+ Object . entries ( optionalDependencies || { } ) . forEach ( ( [ packageName , version ] : [ string , string ] ) => {
137137 if ( Object . prototype . hasOwnProperty . call ( peerDependencies , packageName ) ) {
138138 throw new Error (
139139 `The package "${ packageName } " cannot be listed in both ` +
@@ -142,50 +142,35 @@ export class PackageJsonEditor {
142142 }
143143 this . _dependencies . set (
144144 packageName ,
145- new PackageJsonDependency (
146- packageName ,
147- optionalDependencies [ packageName ] ,
148- DependencyType . Optional ,
149- _onChange
150- )
145+ new PackageJsonDependency ( packageName , version , DependencyType . Optional , _onChange )
151146 ) ;
152147 } ) ;
153148
154- Object . keys ( peerDependencies || { } ) . forEach ( ( packageName : string ) => {
149+ Object . entries ( peerDependencies || { } ) . forEach ( ( [ packageName , version ] : [ string , string ] ) => {
155150 this . _dependencies . set (
156151 packageName ,
157- new PackageJsonDependency (
158- packageName ,
159- peerDependencies [ packageName ] ,
160- DependencyType . Peer ,
161- _onChange
162- )
152+ new PackageJsonDependency ( packageName , version , DependencyType . Peer , _onChange )
163153 ) ;
164154 } ) ;
165155
166- Object . keys ( devDependencies || { } ) . forEach ( ( packageName : string ) => {
156+ Object . entries ( devDependencies || { } ) . forEach ( ( [ packageName , version ] : [ string , string ] ) => {
167157 this . _devDependencies . set (
168158 packageName ,
169- new PackageJsonDependency ( packageName , devDependencies [ packageName ] , DependencyType . Dev , _onChange )
159+ new PackageJsonDependency ( packageName , version , DependencyType . Dev , _onChange )
170160 ) ;
171161 } ) ;
172162
173- Object . keys ( resolutions || { } ) . forEach ( ( packageName : string ) => {
163+ Object . entries ( resolutions || { } ) . forEach ( ( [ packageName , version ] : [ string , string ] ) => {
174164 this . _resolutions . set (
175165 packageName ,
176- new PackageJsonDependency (
177- packageName ,
178- resolutions [ packageName ] ,
179- DependencyType . YarnResolutions ,
180- _onChange
181- )
166+ new PackageJsonDependency ( packageName , version , DependencyType . YarnResolutions , _onChange )
182167 ) ;
183168 } ) ;
184169
185- Object . keys ( dependenciesMeta || { } ) . forEach ( ( packageName : string ) => {
170+ Object . entries ( dependenciesMeta || { } ) . forEach ( ( [ packageName , { injected = false } ] ) => {
186171 this . _dependenciesMeta . set (
187172 packageName ,
188- new PackageJsonDependencyMeta ( packageName , dependenciesMeta [ packageName ] . injected , _onChange )
173+ new PackageJsonDependencyMeta ( packageName , injected , _onChange )
189174 ) ;
190175 } ) ;
191176
@@ -198,7 +183,13 @@ export class PackageJsonEditor {
198183 }
199184
200185 public static load ( filePath : string ) : PackageJsonEditor {
201- return new PackageJsonEditor ( filePath , JsonFile . load ( filePath ) ) ;
186+ const packageJson : IPackageJson = JsonFile . load ( filePath ) ;
187+ return new PackageJsonEditor ( filePath , packageJson ) ;
188+ }
189+
190+ public static async loadAsync ( filePath : string ) : Promise < PackageJsonEditor > {
191+ const packageJson : IPackageJson = await JsonFile . loadAsync ( filePath ) ;
192+ return new PackageJsonEditor ( filePath , packageJson ) ;
202193 }
203194
204195 public static fromObject ( object : IPackageJson , filename : string ) : PackageJsonEditor {
@@ -270,17 +261,24 @@ export class PackageJsonEditor {
270261 switch ( dependencyType ) {
271262 case DependencyType . Regular :
272263 case DependencyType . Optional :
273- case DependencyType . Peer :
264+ case DependencyType . Peer : {
274265 this . _dependencies . set ( packageName , dependency ) ;
275266 break ;
276- case DependencyType . Dev :
267+ }
268+
269+ case DependencyType . Dev : {
277270 this . _devDependencies . set ( packageName , dependency ) ;
278271 break ;
279- case DependencyType . YarnResolutions :
272+ }
273+
274+ case DependencyType . YarnResolutions : {
280275 this . _resolutions . set ( packageName , dependency ) ;
281276 break ;
282- default :
277+ }
278+
279+ default : {
283280 throw new InternalError ( 'Unsupported DependencyType' ) ;
281+ }
284282 }
285283
286284 this . _modified = true ;
@@ -290,17 +288,24 @@ export class PackageJsonEditor {
290288 switch ( dependencyType ) {
291289 case DependencyType . Regular :
292290 case DependencyType . Optional :
293- case DependencyType . Peer :
291+ case DependencyType . Peer : {
294292 this . _dependencies . delete ( packageName ) ;
295293 break ;
296- case DependencyType . Dev :
294+ }
295+
296+ case DependencyType . Dev : {
297297 this . _devDependencies . delete ( packageName ) ;
298298 break ;
299- case DependencyType . YarnResolutions :
299+ }
300+
301+ case DependencyType . YarnResolutions : {
300302 this . _resolutions . delete ( packageName ) ;
301303 break ;
302- default :
304+ }
305+
306+ default : {
303307 throw new InternalError ( 'Unsupported DependencyType' ) ;
308+ }
304309 }
305310
306311 this . _modified = true ;
@@ -316,6 +321,21 @@ export class PackageJsonEditor {
316321 } ) ;
317322 return true ;
318323 }
324+
325+ return false ;
326+ }
327+
328+ public async saveIfModifiedAsync ( ) : Promise < boolean > {
329+ if ( this . _modified ) {
330+ this . _modified = false ;
331+ this . _sourceData = this . _normalize ( this . _sourceData ) ;
332+ await JsonFile . saveAsync ( this . _sourceData , this . filePath , {
333+ updateExistingFile : true ,
334+ jsonSyntax : JsonSyntax . Strict
335+ } ) ;
336+ return true ;
337+ }
338+
319339 return false ;
320340 }
321341
@@ -353,53 +373,64 @@ export class PackageJsonEditor {
353373 const keys : string [ ] = [ ...this . _dependencies . keys ( ) ] . sort ( ) ;
354374
355375 for ( const packageName of keys ) {
356- const dependency : PackageJsonDependency = this . _dependencies . get ( packageName ) ! ;
376+ const { dependencyType , name , version } : PackageJsonDependency = this . _dependencies . get ( packageName ) ! ;
357377
358- switch ( dependency . dependencyType ) {
359- case DependencyType . Regular :
378+ switch ( dependencyType ) {
379+ case DependencyType . Regular : {
360380 if ( ! normalizedData . dependencies ) {
361381 normalizedData . dependencies = { } ;
362382 }
363- normalizedData . dependencies [ dependency . name ] = dependency . version ;
383+
384+ normalizedData . dependencies [ name ] = version ;
364385 break ;
365- case DependencyType . Optional :
386+ }
387+
388+ case DependencyType . Optional : {
366389 if ( ! normalizedData . optionalDependencies ) {
367390 normalizedData . optionalDependencies = { } ;
368391 }
369- normalizedData . optionalDependencies [ dependency . name ] = dependency . version ;
392+
393+ normalizedData . optionalDependencies [ name ] = version ;
370394 break ;
371- case DependencyType . Peer :
395+ }
396+
397+ case DependencyType . Peer : {
372398 if ( ! normalizedData . peerDependencies ) {
373399 normalizedData . peerDependencies = { } ;
374400 }
375- normalizedData . peerDependencies [ dependency . name ] = dependency . version ;
401+
402+ normalizedData . peerDependencies [ name ] = version ;
376403 break ;
404+ }
405+
377406 case DependencyType . Dev : // uses this._devDependencies instead
378407 case DependencyType . YarnResolutions : // uses this._resolutions instead
379- default :
408+ default : {
380409 throw new InternalError ( 'Unsupported DependencyType' ) ;
410+ }
381411 }
382412 }
383413
384414 const devDependenciesKeys : string [ ] = [ ...this . _devDependencies . keys ( ) ] . sort ( ) ;
385-
386415 for ( const packageName of devDependenciesKeys ) {
387- const dependency : PackageJsonDependency = this . _devDependencies . get ( packageName ) ! ;
416+ const { name , version } : PackageJsonDependency = this . _devDependencies . get ( packageName ) ! ;
388417
389418 if ( ! normalizedData . devDependencies ) {
390419 normalizedData . devDependencies = { } ;
391420 }
392- normalizedData . devDependencies [ dependency . name ] = dependency . version ;
421+
422+ normalizedData . devDependencies [ name ] = version ;
393423 }
394424
395425 // (Do not sort this._resolutions because order may be significant; the RFC is unclear about that.)
396426 for ( const packageName of this . _resolutions . keys ( ) ) {
397- const dependency : PackageJsonDependency = this . _resolutions . get ( packageName ) ! ;
427+ const { name , version } : PackageJsonDependency = this . _resolutions . get ( packageName ) ! ;
398428
399429 if ( ! normalizedData . resolutions ) {
400430 normalizedData . resolutions = { } ;
401431 }
402- normalizedData . resolutions [ dependency . name ] = dependency . version ;
432+
433+ normalizedData . resolutions [ name ] = version ;
403434 }
404435
405436 return normalizedData ;
0 commit comments