pkg.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. const PackageJson = require('@npmcli/package-json')
  2. const BaseCommand = require('./base-command.js')
  3. const Queryable = require('./utils/queryable.js')
  4. class Pkg extends BaseCommand {
  5. static get description () {
  6. return 'Manages your package.json'
  7. }
  8. /* istanbul ignore next - see test/lib/load-all-commands.js */
  9. static get name () {
  10. return 'pkg'
  11. }
  12. /* istanbul ignore next - see test/lib/load-all-commands.js */
  13. static get usage () {
  14. return [
  15. 'set <key>=<value> [<key>=<value> ...]',
  16. 'get [<key> [<key> ...]]',
  17. 'delete <key> [<key> ...]',
  18. ]
  19. }
  20. /* istanbul ignore next - see test/lib/load-all-commands.js */
  21. static get params () {
  22. return [
  23. 'force',
  24. 'json',
  25. 'workspace',
  26. 'workspaces',
  27. ]
  28. }
  29. exec (args, cb) {
  30. this.prefix = this.npm.localPrefix
  31. this.pkg(args).then(() => cb()).catch(cb)
  32. }
  33. execWorkspaces (args, filters, cb) {
  34. this.pkgWorkspaces(args, filters).then(() => cb()).catch(cb)
  35. }
  36. async pkg (args) {
  37. if (this.npm.config.get('global')) {
  38. throw Object.assign(
  39. new Error(`There's no package.json file to manage on global mode`),
  40. { code: 'EPKGGLOBAL' }
  41. )
  42. }
  43. const [cmd, ..._args] = args
  44. switch (cmd) {
  45. case 'get':
  46. return this.get(_args)
  47. case 'set':
  48. return this.set(_args)
  49. case 'delete':
  50. return this.delete(_args)
  51. default:
  52. throw this.usageError()
  53. }
  54. }
  55. async pkgWorkspaces (args, filters) {
  56. await this.setWorkspaces(filters)
  57. const result = {}
  58. for (const [workspaceName, workspacePath] of this.workspaces.entries()) {
  59. this.prefix = workspacePath
  60. result[workspaceName] = await this.pkg(args)
  61. }
  62. // when running in workspaces names, make sure to key by workspace
  63. // name the results of each value retrieved in each ws
  64. this.npm.output(JSON.stringify(result, null, 2))
  65. }
  66. async get (args) {
  67. const pkgJson = await PackageJson.load(this.prefix)
  68. const { content } = pkgJson
  69. let result = !args.length && content
  70. if (!result) {
  71. const q = new Queryable(content)
  72. result = q.query(args)
  73. // in case there's only a single result from the query
  74. // just prints that one element to stdout
  75. if (Object.keys(result).length === 1)
  76. result = result[args]
  77. }
  78. // only outputs if not running with workspaces config,
  79. // in case you're retrieving info for workspaces the pkgWorkspaces
  80. // will handle the output to make sure it get keyed by ws name
  81. if (!this.workspaces)
  82. this.npm.output(JSON.stringify(result, null, 2))
  83. return result
  84. }
  85. async set (args) {
  86. const setError = () =>
  87. Object.assign(
  88. new TypeError('npm pkg set expects a key=value pair of args.'),
  89. { code: 'EPKGSET' }
  90. )
  91. if (!args.length)
  92. throw setError()
  93. const force = this.npm.config.get('force')
  94. const json = this.npm.config.get('json')
  95. const pkgJson = await PackageJson.load(this.prefix)
  96. const q = new Queryable(pkgJson.content)
  97. for (const arg of args) {
  98. const [key, ...rest] = arg.split('=')
  99. const value = rest.join('=')
  100. if (!key || !value)
  101. throw setError()
  102. q.set(key, json ? JSON.parse(value) : value, { force })
  103. }
  104. pkgJson.update(q.toJSON())
  105. await pkgJson.save()
  106. }
  107. async delete (args) {
  108. const setError = () =>
  109. Object.assign(
  110. new TypeError('npm pkg delete expects key args.'),
  111. { code: 'EPKGDELETE' }
  112. )
  113. if (!args.length)
  114. throw setError()
  115. const pkgJson = await PackageJson.load(this.prefix)
  116. const q = new Queryable(pkgJson.content)
  117. for (const key of args) {
  118. if (!key)
  119. throw setError()
  120. q.delete(key)
  121. }
  122. pkgJson.update(q.toJSON())
  123. await pkgJson.save()
  124. }
  125. }
  126. module.exports = Pkg