You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*!
  2. * resolve-package <https://github.com/tunnckoCore/resolve-package>
  3. *
  4. * Copyright (c) Charlike Mike Reagent <@tunnckoCore> (http://i.am.charlike.online)
  5. * Released under the MIT license.
  6. */
  7. 'use strict'
  8. const fs = require('fs')
  9. const path = require('path')
  10. const get = require('get-installed-path')
  11. /**
  12. * > Get full absolute path of package with `name` from
  13. * local node_modules or from globally installed.
  14. *
  15. * **Example**
  16. *
  17. * ```js
  18. * const resolvePackage = require('resolve-package')
  19. *
  20. * resolvePackage('npm').then((fp) => {
  21. * console.log(fp)
  22. * // => '~/.nvm/versions/node/v7.0.0/lib/node_modules/npm/lib/npm.js'
  23. * })
  24. *
  25. * resolvePackage('standard').then((fp) => {
  26. * console.log(fp)
  27. * // => '~/.nvm/versions/node/v7.0.0/lib/node_modules/standard/index.js'
  28. * })
  29. *
  30. * resolvePackage('get-installed-path').then((fp) => {
  31. * console.log(fp)
  32. * // => '~/code/resolve-package/node_modules/get-installed-path/index.js'
  33. * })
  34. *
  35. * resolvePackage('foo-quqixs-dasdasdh').catch((err) => {
  36. * console.error(err) // => Error module not found
  37. * })
  38. * ```
  39. *
  40. * @name resolvePackage
  41. * @param {String} `name` package name
  42. * @param {Function} `opts` optional options such as below
  43. * @param {String} `opts.cwd` directory where is the `node_modules` folder
  44. * @param {String} `opts.mainFile` main file for directories, default `index.js`
  45. * @param {String} `opts.mainField` name of the package.json's "main" field, default `main`
  46. * @return {Promise}
  47. * @api public
  48. */
  49. const resolvePackage = (name, opts) => new Promise((resolve, reject) => {
  50. opts = opts && typeof opts === 'object' ? opts : {}
  51. opts.local = true
  52. get(name, opts).then(tryLoad(opts, resolve), (e) => {
  53. opts.local = false
  54. get(name, opts).then(tryLoad(opts, resolve), reject)
  55. })
  56. })
  57. const tryLoad = (opts, resolve) => (fp) => {
  58. readPackage(fp).then(
  59. (pkg) => {
  60. if (typeof opts.mainFile === 'string') {
  61. return resolve(path.resolve(fp, opts.mainFile))
  62. }
  63. if (typeof opts.mainField === 'string') {
  64. fp = path.resolve(fp, pkg[opts.mainField])
  65. return resolve(fp)
  66. }
  67. resolve(path.resolve(fp, pkg.main || ''))
  68. },
  69. (e) => {
  70. const index = typeof opts.mainFile === 'string'
  71. ? opts.mainFile
  72. : 'index.js'
  73. resolve(path.resolve(fp, index))
  74. }
  75. )
  76. }
  77. const readPackage = (fp) => new Promise((resolve, reject) => {
  78. fs.readFile(path.resolve(fp, 'package.json'), 'utf8', (err, str) => {
  79. if (err) return reject(err)
  80. const json = JSON.parse(str)
  81. resolve(json)
  82. })
  83. })
  84. module.exports = resolvePackage