@@ -28,6 +28,7 @@ import { stringify } from "../../util/misc.js";
28
28
import map from "../../util/map.js" ;
29
29
30
30
let invariant = require ( "invariant" ) ;
31
+ let semver = require ( "semver" ) ;
31
32
let emoji = require ( "node-emoji" ) ;
32
33
let path = require ( "path" ) ;
33
34
@@ -191,8 +192,8 @@ export class Install {
191
192
async savePackages ( ) : Promise < void > {
192
193
if ( ! this . args . length ) return ;
193
194
194
- let { save, saveDev, saveExact, saveOptional } = this . flags ;
195
- if ( ! save && ! saveDev && ! saveOptional ) return ;
195
+ let { save, saveDev, saveExact, saveTilde , saveOptional, savePeer } = this . flags ;
196
+ if ( ! save && ! saveDev && ! saveOptional && ! savePeer ) return ;
196
197
197
198
let json = { } ;
198
199
let jsonLoc = path . join ( this . config . cwd , "package.json" ) ;
@@ -211,22 +212,30 @@ export class Install {
211
212
212
213
let parts = PackageRequest . normalisePattern ( pattern ) ;
213
214
let version ;
214
- if ( ! saveExact ) {
215
- version = `^ ${ pkg . version } ` ;
216
- } else {
215
+ if ( parts . range && ! semver . validRange ( parts . range ) ) {
216
+ // if a range was specified in this pattern and it's not a semver range then
217
+ // it's exotic and can't be found on the npm registry
217
218
version = parts . range ;
219
+ } else if ( saveTilde ) { // --save-tilde
220
+ version = `~${ pkg . version } ` ;
221
+ } else if ( saveExact ) { // --save-exact
222
+ version = pkg . version ;
223
+ } else { // default to caret
224
+ version = `^${ pkg . version } ` ;
218
225
}
219
226
220
-
221
- let targetKey ;
222
- if ( save ) targetKey = "dependencies" ;
223
- if ( saveDev ) targetKey = "devDependencies" ;
224
- if ( saveOptional ) targetKey = "optionalDependencies" ;
225
- if ( ! targetKey ) continue ;
227
+ let targetKeys = [ ] ;
228
+ if ( save ) targetKeys . push ( "dependencies" ) ;
229
+ if ( saveDev ) targetKeys . push ( "devDependencies" ) ;
230
+ if ( savePeer ) targetKeys . push ( "peerDependencies" ) ;
231
+ if ( saveOptional ) targetKeys . push ( "optionalDependencies" ) ;
232
+ if ( ! targetKeys . length ) continue ;
226
233
227
234
// add it to package.json
228
- let target = json [ targetKey ] = json [ targetKey ] || { } ;
229
- target [ pkg . name ] = version ;
235
+ for ( let key of targetKeys ) {
236
+ let target = json [ key ] = json [ key ] || { } ;
237
+ target [ pkg . name ] = version ;
238
+ }
230
239
231
240
// add pattern so it's aliased in the lockfile
232
241
let newPattern = `${ pkg . name } @${ version } ` ;
@@ -319,7 +328,8 @@ export class Install {
319
328
*/
320
329
321
330
function hasSaveFlags ( flags : Object ) : boolean {
322
- return flags . save || flags . saveDev || flags . saveExact || flags . saveOptional ;
331
+ return flags . save || flags . saveExact || flags . saveTilde ||
332
+ flags . saveDev || flags . saveExact || flags . savePeer ;
323
333
}
324
334
325
335
/**
@@ -375,10 +385,12 @@ export function setFlags(commander: Object) {
375
385
commander . usage ( "install [packages ...] [flags]" ) ;
376
386
commander . option ( "-f, --flat" , "only allow one version of a package. save all transitive " +
377
387
"dependencies as top level." ) ;
378
- commander . option ( "-S, --save" , "save package to your `dependencies`" ) ; // TODO
379
- commander . option ( "-D, --save-dev" , "save package to your `devDependencies`" ) ; // TODO
380
- commander . option ( "-O, --save-optional" , "save package to your `optionalDependencies`" ) ; // TODO
381
- commander . option ( "-E, --save-exact" , "" ) ; // TODO
388
+ commander . option ( "-S, --save" , "save package to your `dependencies`" ) ;
389
+ commander . option ( "-D, --save-dev" , "save package to your `devDependencies`" ) ;
390
+ commander . option ( "-P, --save-peer" , "save package to your `peerDependencies`" ) ;
391
+ commander . option ( "-O, --save-optional" , "save package to your `optionalDependencies`" ) ;
392
+ commander . option ( "-E, --save-exact" , "" ) ;
393
+ commander . option ( "-T, --save-tilde" , "" ) ;
382
394
commander . option ( "--tag [tag]" , "" ) ; // TODO
383
395
commander . option ( "--dry-run" , "" ) ; // TODO
384
396
commander . option ( "-f, --force" , "" ) ; // TODO
0 commit comments