+94
-38
@@ -10,51 +10,107 @@ /*! | ||
| const axios = require('axios'); | ||
| const https = require('https'); | ||
| const { parse } = require('parse-package-name'); | ||
| module.exports = (name, version, cb) => { | ||
| if (typeof version === 'function') { | ||
| cb = version; | ||
| version = ''; | ||
| const YARM_HOSTNAME = 'registry.yarnpkg.com'; | ||
| const NPM_HOSTNAME = 'registry.npmjs.org'; | ||
| const handleBadResponse = (res, name, data, parsed) => { | ||
| const err = new Error(data.message); | ||
| err.status = res.statusCode || res.status; | ||
| err.code = data.code; | ||
| if (data.code === 'MethodNotAllowedError') { | ||
| err.message = `package.json not found for "${name}"`; | ||
| if (parsed.version?.startsWith('v')) { | ||
| err.message += ` are you sure version ${parsed.version} should start with a "v"?`; | ||
| } | ||
| } | ||
| if (name && name[0] === '@') { | ||
| name = '@' + encodeURIComponent(name.slice(1)); | ||
| version = ''; // npm does not allow version for scoped packages | ||
| } else if (!version) { | ||
| version = 'latest'; | ||
| return err; | ||
| }; | ||
| const createOptions = (name, { hostname = YARM_HOSTNAME } = {}) => { | ||
| const parsed = parse(name); | ||
| if (name.startsWith('@') && hostname === NPM_HOSTNAME) { | ||
| parsed.name = `@${encodeURIComponent(parsed.name.slice(1))}`; | ||
| } | ||
| // the following code hits the yarn CNAME (they call it a "proxy") | ||
| // when npm's registry fails. In practice, this usually won't make a | ||
| // difference since yarn is pseudo-proxying npm's registry in the | ||
| // first place, but in the case of CDN failure, it might help. | ||
| let pending = request('https://registry.npmjs.org', name, version) | ||
| .catch(err => { | ||
| return request('https://registry.yarnpkg.com').catch(() => { | ||
| return Promise.reject(err); | ||
| }); | ||
| }); | ||
| const domain = `https://${hostname.replace(/^https?:\/\//, '')}`; | ||
| const options = { | ||
| hostname, | ||
| path: `/${parsed.name}/${parsed.version}${parsed.path}`, | ||
| method: 'GET', | ||
| headers: { | ||
| 'Content-Type': 'application/json' | ||
| } | ||
| }; | ||
| if (typeof cb === 'function') { | ||
| pending.then(res => cb(null, res)).catch(cb); | ||
| return; | ||
| if (parsed.path) { | ||
| options.path += parsed.path; | ||
| } | ||
| return pending; | ||
| const url = new URL(options.path, domain); | ||
| return { options, url, parsed }; | ||
| }; | ||
| function request(url, name, version) { | ||
| return axios.get(`${url}/${name}/${version}`) | ||
| .then(res => res.data) | ||
| .catch(err => { | ||
| if (err.response.status === 500) { | ||
| return Promise.reject(new Error(err.response.status)); | ||
| const getUnpkg = async (name, hostname) => { | ||
| const parsed = parse(name); | ||
| if (!name.endsWith('/package.json') && !parsed.path) { | ||
| name += '/package.json'; | ||
| } | ||
| const res = await fetch(new URL(name, hostname)); | ||
| const output = await res.text(); | ||
| return JSON.parse(output); | ||
| }; | ||
| const getPkg = async (name, { hostname = NPM_HOSTNAME, ...options } = {}) => { | ||
| if (hostname !== YARM_HOSTNAME && hostname.includes('unpkg')) { | ||
| return getUnpkg(name, hostname); | ||
| } | ||
| if (typeof fetch === 'undefined') { | ||
| return request(name, { ...options, hostname: NPM_HOSTNAME }); | ||
| } | ||
| const { url, ...parsed } = createOptions(name, { hostname }); | ||
| const res = await fetch(url); | ||
| const output = await res.text(); | ||
| const data = JSON.parse(output); | ||
| if (res.status !== 200) { | ||
| throw handleBadResponse(res, name, data, { url, ...parsed }); | ||
| } | ||
| return data; | ||
| }; | ||
| const request = (name, args) => { | ||
| const { options, parsed } = createOptions(name, args); | ||
| return new Promise((resolve, reject) => { | ||
| const req = https.request(options, res => { | ||
| let output = ''; | ||
| if (res.statusCode !== 200) { | ||
| reject(handleBadResponse(res, name, { code: 'NotFound' }, parsed)); | ||
| return; | ||
| } | ||
| if (err.response.status === 404) { | ||
| let error = new Error('document not found'); | ||
| error.code = err.response.status; | ||
| error.pkgName = name; | ||
| return Promise.reject(error); | ||
| } | ||
| return Promise.reject(err); | ||
| res.on('data', chunk => { | ||
| output += chunk; | ||
| }); | ||
| res.on('end', () => resolve(JSON.parse(output))); | ||
| }); | ||
| } | ||
| req.on('error', reject); | ||
| req.end(); | ||
| }); | ||
| }; | ||
| module.exports = getPkg; |
+3
-2
| { | ||
| "name": "get-pkg", | ||
| "description": "Get the package.json for a project from npm.", | ||
| "version": "1.1.0", | ||
| "version": "2.0.0", | ||
| "homepage": "https://github.com/jonschlinkert/get-pkg", | ||
@@ -23,3 +23,4 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
| "dependencies": { | ||
| "axios": "^0.18.0" | ||
| "node-fetch": "^3.3.1", | ||
| "parse-package-name": "^1.0.0" | ||
| }, | ||
@@ -26,0 +27,0 @@ "devDependencies": { |
+11
-18
@@ -1,2 +0,2 @@ | ||
| # get-pkg [](https://www.npmjs.com/package/get-pkg) [](https://npmjs.org/package/get-pkg) [](https://npmjs.org/package/get-pkg) [](https://travis-ci.org/jonschlinkert/get-pkg) | ||
| # get-pkg [](https://www.npmjs.com/package/get-pkg) [](https://npmjs.org/package/get-pkg) [](https://npmjs.org/package/get-pkg) | ||
@@ -21,12 +21,6 @@ > Get the package.json for a project from npm. | ||
| const getPkg = require('get-pkg'); | ||
| const data = await getPkg('generate') | ||
| // takes a callback | ||
| getPkg('generate', function(err, pkg) { | ||
| console.log(pkg); | ||
| }); | ||
| // or returns a promise | ||
| getPkg('generate') | ||
| .then(pkg => console.log(pkg)) | ||
| .catch(console.error); | ||
| console.log(data); | ||
| //=> { name: 'generate', ... } | ||
| ``` | ||
@@ -76,8 +70,7 @@ | ||
| | **Commits** | **Contributor** | | ||
| | --- | --- | | ||
| | 16 | [jonschlinkert](https://github.com/jonschlinkert) | | ||
| | 3 | [stefanwalther](https://github.com/stefanwalther) | | ||
| | 2 | [doowb](https://github.com/doowb) | | ||
| | 1 | [joakimbeng](https://github.com/joakimbeng) | | ||
| | **Commits** | **Contributor** | | ||
| | --- | --- | | ||
| | 21 | [jonschlinkert](https://github.com/jonschlinkert) | | ||
| | 2 | [doowb](https://github.com/doowb) | | ||
| | 1 | [joakimbeng](https://github.com/joakimbeng) | | ||
@@ -94,3 +87,3 @@ ### Author | ||
| Copyright © 2018, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
| Copyright © 2023, [Jon Schlinkert](https://github.com/jonschlinkert). | ||
| Released under the [MIT License](LICENSE). | ||
@@ -100,2 +93,2 @@ | ||
| _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on December 08, 2018._ | ||
| _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on July 24, 2023._ |
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
8294
12.19%87
70.59%2
100%91
-6.19%2
100%4
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed