11cb0ef41Sopenharmony_ciconst { resolve, basename } = require('path')
21cb0ef41Sopenharmony_ciconst { unlink } = require('fs').promises
31cb0ef41Sopenharmony_ciconst log = require('../utils/log-shim')
41cb0ef41Sopenharmony_ciconst BaseCommand = require('../base-command.js')
51cb0ef41Sopenharmony_ciclass Shrinkwrap extends BaseCommand {
61cb0ef41Sopenharmony_ci  static description = 'Lock down dependency versions for publication'
71cb0ef41Sopenharmony_ci  static name = 'shrinkwrap'
81cb0ef41Sopenharmony_ci  static ignoreImplicitWorkspace = false
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci  async exec () {
111cb0ef41Sopenharmony_ci    // if has a npm-shrinkwrap.json, nothing to do
121cb0ef41Sopenharmony_ci    // if has a package-lock.json, rename to npm-shrinkwrap.json
131cb0ef41Sopenharmony_ci    // if has neither, load the actual tree and save that as npm-shrinkwrap.json
141cb0ef41Sopenharmony_ci    //
151cb0ef41Sopenharmony_ci    // loadVirtual, fall back to loadActual
161cb0ef41Sopenharmony_ci    // rename shrinkwrap file type, and tree.meta.save()
171cb0ef41Sopenharmony_ci    if (this.npm.global) {
181cb0ef41Sopenharmony_ci      const er = new Error('`npm shrinkwrap` does not work for global packages')
191cb0ef41Sopenharmony_ci      er.code = 'ESHRINKWRAPGLOBAL'
201cb0ef41Sopenharmony_ci      throw er
211cb0ef41Sopenharmony_ci    }
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci    const Arborist = require('@npmcli/arborist')
241cb0ef41Sopenharmony_ci    const path = this.npm.prefix
251cb0ef41Sopenharmony_ci    const sw = resolve(path, 'npm-shrinkwrap.json')
261cb0ef41Sopenharmony_ci    const arb = new Arborist({ ...this.npm.flatOptions, path })
271cb0ef41Sopenharmony_ci    const tree = await arb.loadVirtual().catch(() => arb.loadActual())
281cb0ef41Sopenharmony_ci    const { meta } = tree
291cb0ef41Sopenharmony_ci    const newFile = meta.hiddenLockfile || !meta.loadedFromDisk
301cb0ef41Sopenharmony_ci    const oldFilename = meta.filename
311cb0ef41Sopenharmony_ci    const notSW = !newFile && basename(oldFilename) !== 'npm-shrinkwrap.json'
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci    // The computed lockfile version of a hidden lockfile is always 3
341cb0ef41Sopenharmony_ci    // even if the actual value of the property is a different.
351cb0ef41Sopenharmony_ci    // When shrinkwrap is run with only a hidden lockfile we want to
361cb0ef41Sopenharmony_ci    // set the shrinkwrap lockfile version as whatever was explicitly
371cb0ef41Sopenharmony_ci    // requested with a fallback to the actual value from the hidden
381cb0ef41Sopenharmony_ci    // lockfile.
391cb0ef41Sopenharmony_ci    if (meta.hiddenLockfile) {
401cb0ef41Sopenharmony_ci      meta.lockfileVersion = arb.options.lockfileVersion ||
411cb0ef41Sopenharmony_ci        meta.originalLockfileVersion
421cb0ef41Sopenharmony_ci    }
431cb0ef41Sopenharmony_ci    meta.hiddenLockfile = false
441cb0ef41Sopenharmony_ci    meta.filename = sw
451cb0ef41Sopenharmony_ci    await meta.save()
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci    const updatedVersion = meta.originalLockfileVersion !== meta.lockfileVersion
481cb0ef41Sopenharmony_ci      ? meta.lockfileVersion
491cb0ef41Sopenharmony_ci      : null
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci    if (newFile) {
521cb0ef41Sopenharmony_ci      let message = 'created a lockfile as npm-shrinkwrap.json'
531cb0ef41Sopenharmony_ci      if (updatedVersion) {
541cb0ef41Sopenharmony_ci        message += ` with version ${updatedVersion}`
551cb0ef41Sopenharmony_ci      }
561cb0ef41Sopenharmony_ci      log.notice('', message)
571cb0ef41Sopenharmony_ci    } else if (notSW) {
581cb0ef41Sopenharmony_ci      await unlink(oldFilename)
591cb0ef41Sopenharmony_ci      let message = 'package-lock.json has been renamed to npm-shrinkwrap.json'
601cb0ef41Sopenharmony_ci      if (updatedVersion) {
611cb0ef41Sopenharmony_ci        message += ` and updated to version ${updatedVersion}`
621cb0ef41Sopenharmony_ci      }
631cb0ef41Sopenharmony_ci      log.notice('', message)
641cb0ef41Sopenharmony_ci    } else if (updatedVersion) {
651cb0ef41Sopenharmony_ci      log.notice('', `npm-shrinkwrap.json updated to version ${updatedVersion}`)
661cb0ef41Sopenharmony_ci    } else {
671cb0ef41Sopenharmony_ci      log.notice('', 'npm-shrinkwrap.json up to date')
681cb0ef41Sopenharmony_ci    }
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_cimodule.exports = Shrinkwrap
72