Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V5 minipass refactor #11

Merged
merged 9 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
language: node_js
sudo: false
node_js:
- "9"
- "8"
- "6"
- node
- 12
- 10
- 8
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# npm-registry-fetch [![npm version](https://img.shields.io/npm/v/npm-registry-fetch.svg)](https://npm.im/npm-registry-fetch) [![license](https://img.shields.io/npm/l/npm-registry-fetch.svg)](https://npm.im/npm-registry-fetch) [![Travis](https://img.shields.io/travis/npm/npm-registry-fetch/latest.svg)](https://travis-ci.org/npm/npm-registry-fetch) [![AppVeyor](https://img.shields.io/appveyor/ci/zkat/npm-registry-fetch/latest.svg)](https://ci.appveyor.com/project/npm/npm-registry-fetch) [![Coverage Status](https://coveralls.io/repos/github/npm/npm-registry-fetch/badge.svg?branch=latest)](https://coveralls.io/github/npm/npm-registry-fetch?branch=latest)
# npm-registry-fetch [![npm version](https://img.shields.io/npm/v/npm-registry-fetch.svg)](https://npm.im/npm-registry-fetch) [![license](https://img.shields.io/npm/l/npm-registry-fetch.svg)](https://npm.im/npm-registry-fetch) [![Travis](https://img.shields.io/travis/npm/npm-registry-fetch/latest.svg)](https://travis-ci.org/npm/npm-registry-fetch) [![AppVeyor](https://img.shields.io/appveyor/ci/npm/npm-registry-fetch/latest.svg)](https://ci.appveyor.com/project/npm/npm-registry-fetch) [![Coverage Status](https://coveralls.io/repos/github/npm/npm-registry-fetch/badge.svg?branch=latest)](https://coveralls.io/github/npm/npm-registry-fetch?branch=latest)

[`npm-registry-fetch`](https://github.com/npm/npm-registry-fetch) is a Node.js
library that implements a `fetch`-like API for accessing npm registry APIs
Expand Down
2 changes: 1 addition & 1 deletion auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = getAuth
function getAuth (registry, opts) {
if (!registry) { throw new Error('registry is required') }
opts = config(opts)
let AUTH = {}
const AUTH = {}
const regKey = registry && registryKey(registry)
if (opts.forceAuth) {
opts = opts.forceAuth
Expand Down
29 changes: 17 additions & 12 deletions check-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const config = require('./config.js')
const errors = require('./errors.js')
const LRU = require('lru-cache')

const {Response} = require('minipass-fetch')
module.exports = checkResponse
function checkResponse (method, res, registry, startTime, opts) {
opts = config(opts)
Expand All @@ -18,7 +18,7 @@ function checkResponse (method, res, registry, startTime, opts) {
res.body.on('end', () => logRequest(method, res, startTime, opts))
if (opts.ignoreBody) {
res.body.resume()
res.body = null
return new Response(null, res)
}
return res
}
Expand All @@ -41,17 +41,22 @@ const BAD_HOSTS = new LRU({ max: 50 })
function checkWarnings (res, registry, opts) {
if (res.headers.has('warning') && !BAD_HOSTS.has(registry)) {
const warnings = {}
res.headers.raw()['warning'].forEach(w => {
const match = w.match(WARNING_REGEXP)
if (match) {
warnings[match[1]] = {
code: match[1],
host: match[2],
message: match[3],
date: new Date(match[4])
// note: headers.raw() will preserve case, so we might have a
// key on the object like 'WaRnInG' if that was used first
for (const [key, value] of Object.entries(res.headers.raw())) {
if (key.toLowerCase() !== 'warning') { continue }
value.forEach(w => {
const match = w.match(WARNING_REGEXP)
if (match) {
warnings[match[1]] = {
code: match[1],
host: match[2],
message: match[3],
date: new Date(match[4])
}
}
}
})
})
}
BAD_HOSTS.set(registry, true)
if (warnings['199']) {
if (warnings['199'].message.match(/ENOTFOUND/)) {
Expand Down
1 change: 0 additions & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ module.exports = figgyPudding({
'prefer-online': {},
'projectScope': {},
'project-scope': 'projectScope',
'Promise': {default: () => Promise},
'proxy': {},
'query': {},
'refer': {},
Expand Down
63 changes: 38 additions & 25 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,63 @@ const checkResponse = require('./check-response.js')
const config = require('./config.js')
const getAuth = require('./auth.js')
const fetch = require('make-fetch-happen')
const JSONStream = require('JSONStream')
const JSONStream = require('minipass-json-stream')
const npa = require('npm-package-arg')
const {PassThrough} = require('stream')
const qs = require('querystring')
const url = require('url')
const zlib = require('zlib')
const zlib = require('minizlib')
const Minipass = require('minipass')

module.exports = regFetch
function regFetch (uri, opts) {
opts = config(opts)
const registry = (
(opts.spec && pickRegistry(opts.spec, opts)) ||
opts.registry ||
/* istanbul ignore next: default set in figgy pudding config */
'https://registry.npmjs.org/'
)

uri = url.parse(uri).protocol
? uri
: `${
registry.trim().replace(/\/?$/g, '')
}/${
uri.trim().replace(/^\//, '')
}`

const method = opts.method ||
/* istanbul ignore next: default set in figgy pudding config */
'GET'

// through that takes into account the scope, the prefix of `uri`, etc
const startTime = Date.now()
const headers = getHeaders(registry, uri, opts)
let body = opts.body
const bodyIsStream = body &&
const bodyIsStream = Minipass.isStream(body)
const bodyIsPromise = body &&
typeof body === 'object' &&
typeof body.pipe === 'function'
if (body && !bodyIsStream && typeof body !== 'string' && !Buffer.isBuffer(body)) {
typeof body.then === 'function'

if (body && !bodyIsStream && !bodyIsPromise && typeof body !== 'string' && !Buffer.isBuffer(body)) {
headers['content-type'] = headers['content-type'] || 'application/json'
body = JSON.stringify(body)
} else if (body && !headers['content-type']) {
headers['content-type'] = 'application/octet-stream'
}

if (opts.gzip) {
headers['content-encoding'] = 'gzip'
if (bodyIsStream) {
const gz = zlib.createGzip()
body.on('error', err => gz.emit('error', err))
const gz = new zlib.Gzip()
body.on('error', /* istanbul ignore next: unlikely and hard to test */
err => gz.emit('error', err))
body = body.pipe(gz)
} else {
body = new opts.Promise((resolve, reject) => {
zlib.gzip(body, (err, gz) => err ? reject(err) : resolve(gz))
})
} else if (!bodyIsPromise) {
body = new zlib.Gzip().end(body).concat()
}
}

if (opts.query) {
let q = opts.query
if (typeof q === 'string') {
Expand All @@ -73,7 +83,8 @@ function regFetch (uri, opts) {
uri = url.format(parsed)
}
}
return opts.Promise.resolve(body).then(body => fetch(uri, {

const doFetch = (body) => fetch(uri, {
agent: opts.agent,
algorithms: opts.algorithms,
body,
Expand All @@ -87,9 +98,8 @@ function regFetch (uri, opts) {
localAddress: opts['local-address'],
maxSockets: opts.maxsockets,
memoize: opts.memoize,
method: opts.method || 'GET',
method: method,
noProxy: opts['no-proxy'] || opts.noproxy,
Promise: opts.Promise,
proxy: opts['https-proxy'] || opts.proxy,
referer: opts.refer,
retry: opts.retry != null ? opts.retry : {
Expand All @@ -101,8 +111,10 @@ function regFetch (uri, opts) {
strictSSL: !!opts['strict-ssl'],
timeout: opts.timeout
}).then(res => checkResponse(
opts.method || 'GET', res, registry, startTime, opts
)))
method, res, registry, startTime, opts
))

return Promise.resolve(body).then(doFetch)
}

module.exports.json = fetchJSON
Expand All @@ -114,13 +126,12 @@ module.exports.json.stream = fetchJSONStream
function fetchJSONStream (uri, jsonPath, opts) {
opts = config(opts)
const parser = JSONStream.parse(jsonPath, opts.mapJson)
const pt = parser.pipe(new PassThrough({objectMode: true}))
parser.on('error', err => pt.emit('error', err))
regFetch(uri, opts).then(res => {
res.body.on('error', err => parser.emit('error', err))
res.body.pipe(parser)
}, err => pt.emit('error', err))
return pt
regFetch(uri, opts).then(res =>
res.body.on('error',
/* istanbul ignore next: unlikely and difficult to test */
er => parser.emit('error', er)).pipe(parser)
).catch(er => parser.emit('error', er))
return parser
}

module.exports.pickRegistry = pickRegistry
Expand All @@ -135,7 +146,9 @@ function pickRegistry (spec, opts) {
}

if (!registry) {
registry = opts.registry || 'https://registry.npmjs.org/'
registry = opts.registry ||
/* istanbul ignore next: default set by figgy pudding config */
'https://registry.npmjs.org/'
}

return registry
Expand Down
Loading