diff --git a/README.md b/README.md
index 1583fec..3dd38a9 100644
--- a/README.md
+++ b/README.md
@@ -162,7 +162,7 @@ to trust only that specific signing authority.
Multiple CAs can be trusted by specifying an array of certificates instead of a
single string.
-See also [`opts.strict-ssl`](#opts-strict-ssl), [`opts.ca`](#opts-ca) and
+See also [`opts.strictSSL`](#opts-strictSSL), [`opts.ca`](#opts-ca) and
[`opts.key`](#opts-key)
##### `opts.cache`
@@ -175,8 +175,8 @@ will be cached according to [IETF RFC 7234](https://tools.ietf.org/html/rfc7234)
rules. This will speed up future requests, as well as make the cached data
available offline if necessary/requested.
-See also [`offline`](#opts-offline), [`prefer-offline`](#opts-prefer-offline),
-and [`prefer-online`](#opts-prefer-online).
+See also [`offline`](#opts-offline), [`preferOffline`](#opts-preferOffline),
+and [`preferOnline`](#opts-preferOnline).
##### `opts.cert`
@@ -197,7 +197,7 @@ It is _not_ the path to a certificate file (and there is no "certfile" option).
See also: [`opts.ca`](#opts-ca) and [`opts.key`](#opts-key)
-##### `opts.fetch-retries`
+##### `opts.fetchRetries`
* Type: Number
* Default: 2
@@ -208,7 +208,7 @@ packages from the registry.
See also [`opts.retry`](#opts-retry) to provide all retry options as a single
object.
-##### `opts.fetch-retry-factor`
+##### `opts.fetchRetryFactor`
* Type: Number
* Default: 10
@@ -219,7 +219,7 @@ packages.
See also [`opts.retry`](#opts-retry) to provide all retry options as a single
object.
-##### `opts.fetch-retry-mintimeout`
+##### `opts.fetchRetryMintimeout`
* Type: Number
* Default: 10000 (10 seconds)
@@ -230,7 +230,7 @@ packages.
See also [`opts.retry`](#opts-retry) to provide all retry options as a single
object.
-##### `opts.fetch-retry-maxtimeout`
+##### `opts.fetchRetryMaxtimeout`
* Type: Number
* Default: 60000 (1 minute)
@@ -241,9 +241,8 @@ packages.
See also [`opts.retry`](#opts-retry) to provide all retry options as a single
object.
-##### `opts.force-auth`
+##### `opts.forceAuth`
-* Alias: `opts.forceAuth`
* Type: Object
* Default: null
@@ -269,9 +268,8 @@ Additional headers for the outgoing request. This option can also be used to
override headers automatically generated by `npm-registry-fetch`, such as
`Content-Type`.
-##### `opts.ignore-body`
+##### `opts.ignoreBody`
-* Alias: `opts.ignoreBody`
* Type: Boolean
* Default: false
@@ -298,9 +296,8 @@ previously-generated integrity hash for the saved request information, so
`EINTEGRITY` errors can happen if [`opts.cache`](#opts-cache) is used, even if
`opts.integrity` is not passed in.
-##### `opts.is-from-ci`
+##### `opts.isFromCI`
-* Alias: `opts.isFromCI`
* Type: Boolean
* Default: Based on environment variables
@@ -324,7 +321,7 @@ It is _not_ the path to a key file (and there is no "keyfile" option).
See also: [`opts.ca`](#opts-ca) and [`opts.cert`](#opts-cert)
-##### `opts.local-address`
+##### `opts.localAddress`
* Type: IP Address String
* Default: null
@@ -342,9 +339,8 @@ See also [`opts.proxy`](#opts-proxy)
Logger object to use for logging operation details. Must have the same methods
as `npmlog`.
-##### `opts.map-json`
+##### `opts.mapJSON`
-* Alias: `mapJson`, `mapJSON`
* Type: Function
* Default: undefined
@@ -352,9 +348,8 @@ When using `fetch.json.stream()` (NOT `fetch.json()`), this will be passed down
to [`JSONStream`](https://npm.im/JSONStream) as the second argument to
`JSONStream.parse`, and can be used to transform stream data before output.
-##### `opts.maxsockets`
+##### `opts.maxSockets`
-* Alias: `opts.max-sockets`
* Type: Integer
* Default: 12
@@ -375,9 +370,8 @@ HTTP method to use for the outgoing request. Case-insensitive.
If true, proxying will be disabled even if [`opts.proxy`](#opts-proxy) is used.
-##### `opts.npm-session`
+##### `opts.npmSession`
-* Alias: `opts.npmSession`
* Type: String
* Default: null
@@ -392,7 +386,7 @@ invocations of the CLI).
Force offline mode: no network requests will be done during install. To allow
`npm-registry-fetch` to fill in missing cache data, see
-[`opts.prefer-offline`](#opts-prefer-offline).
+[`opts.preferOffline`](#opts-preferOffline).
This option is only really useful if you're also using
[`opts.cache`](#opts-cache).
@@ -408,7 +402,7 @@ account.
##### `opts.password`
-* Alias: _password
+* Alias: `_password`
* Type: String
* Default: null
@@ -426,7 +420,7 @@ That is:
See also [`opts.username`](#opts-username)
-##### `opts.prefer-offline`
+##### `opts.preferOffline`
* Type: Boolean
* Default: false
@@ -438,7 +432,7 @@ will be requested from the server. To force full offline mode, use
This option is generally only useful if you're also using
[`opts.cache`](#opts-cache).
-##### `opts.prefer-online`
+##### `opts.preferOnline`
* Type: Boolean
* Default: false
@@ -450,9 +444,8 @@ This option is generally only useful if you're also using
[`opts.cache`](#opts-cache).
-##### `opts.project-scope`
+##### `opts.projectScope`
-* Alias: `opts.projectScope`
* Type: String
* Default: null
@@ -483,7 +476,6 @@ If the request URI already has a query string, it will be merged with
##### `opts.refer`
-* Alias: `opts.referer`
* Type: String
* Default: null
@@ -547,7 +539,7 @@ If provided, can be used to automatically configure [`opts.scope`](#opts-scope)
based on a specific package name. Non-registry package specs will throw an
error.
-##### `opts.strict-ssl`
+##### `opts.strictSSL`
* Type: Boolean
* Default: true
@@ -580,7 +572,7 @@ Can be scoped to a registry by using a "nerf dart" for that registry. That is:
}
```
-##### `opts.user-agent`
+##### `opts.userAgent`
* Type: String
* Default: `'npm-registry-fetch@/node@+ ()'`
@@ -612,4 +604,4 @@ See also [`opts.password`](#opts-password)
* Default: null
** DEPRECATED ** This is a legacy authentication token supported only for
-*compatibility. Please use [`opts.token`](#opts-token) instead.
+compatibility. Please use [`opts.token`](#opts-token) instead.
diff --git a/auth.js b/auth.js
index 3198b9c..11c3bde 100644
--- a/auth.js
+++ b/auth.js
@@ -1,17 +1,14 @@
'use strict'
-const config = require('./config.js')
+const defaultOpts = require('./default-opts.js')
const url = require('url')
module.exports = getAuth
-function getAuth (registry, opts) {
+function getAuth (registry, opts_ = {}) {
if (!registry) { throw new Error('registry is required') }
- opts = config(opts)
+ const opts = opts_.forceAuth ? opts_.forceAuth : { ...defaultOpts, ...opts_ }
const AUTH = {}
const regKey = registry && registryKey(registry)
- if (opts.forceAuth) {
- opts = opts.forceAuth
- }
const doKey = (key, alias) => addKey(opts, AUTH, regKey, key, alias)
doKey('token')
doKey('_authToken', 'token')
diff --git a/check-response.js b/check-response.js
index 3137ea7..933c8f7 100644
--- a/check-response.js
+++ b/check-response.js
@@ -1,12 +1,13 @@
'use strict'
-const config = require('./config.js')
const errors = require('./errors.js')
const LRU = require('lru-cache')
const { Response } = require('minipass-fetch')
+const defaultOpts = require('./default-opts.js')
+
module.exports = checkResponse
-function checkResponse (method, res, registry, startTime, opts) {
- opts = config(opts)
+function checkResponse (method, res, registry, startTime, opts_ = {}) {
+ const opts = { ...defaultOpts, ...opts_ }
if (res.headers.has('npm-notice') && !res.headers.has('x-local-cache')) {
opts.log.notice('', res.headers.get('npm-notice'))
}
diff --git a/config.js b/config.js
deleted file mode 100644
index d6681d0..0000000
--- a/config.js
+++ /dev/null
@@ -1,92 +0,0 @@
-'use strict'
-
-const pkg = require('./package.json')
-const figgyPudding = require('figgy-pudding')
-const silentLog = require('./silentlog.js')
-const ciDetect = require('@npmcli/ci-detect')
-
-const AUTH_REGEX = /^(?:.*:)?(token|_authToken|username|_password|password|email|always-auth|_auth|otp)$/
-const SCOPE_REGISTRY_REGEX = /@.*:registry$/gi
-module.exports = figgyPudding({
- agent: {},
- algorithms: {},
- body: {},
- ca: {},
- cache: {},
- cert: {},
- 'fetch-retries': {},
- 'fetch-retry-factor': {},
- 'fetch-retry-maxtimeout': {},
- 'fetch-retry-mintimeout': {},
- 'force-auth': {},
- forceAuth: 'force-auth',
- gzip: {},
- headers: {},
- 'https-proxy': {},
- 'ignore-body': {},
- ignoreBody: 'ignore-body',
- integrity: {},
- 'is-from-ci': 'isFromCI',
- isFromCI: {
- default () {
- return ciDetect()
- }
- },
- key: {},
- 'local-address': {},
- log: {
- default: silentLog
- },
- 'map-json': 'mapJson',
- mapJSON: 'mapJson',
- mapJson: {},
- 'max-sockets': 'maxsockets',
- maxsockets: {
- default: 12
- },
- memoize: {},
- method: {
- default: 'GET'
- },
- 'no-proxy': {},
- noproxy: {},
- 'npm-session': 'npmSession',
- npmSession: {},
- offline: {},
- otp: {},
- 'prefer-offline': {},
- 'prefer-online': {},
- projectScope: {},
- 'project-scope': 'projectScope',
- proxy: {},
- query: {},
- refer: {},
- referer: 'refer',
- registry: {
- default: 'https://registry.npmjs.org/'
- },
- retry: {},
- scope: {},
- spec: {},
- 'strict-ssl': {},
- timeout: {
- default: 30 * 1000
- },
- 'user-agent': {
- default: `${
- pkg.name
- }@${
- pkg.version
- }/node@${
- process.version
- }+${
- process.arch
- } (${
- process.platform
- })`
- }
-}, {
- other (key) {
- return key.match(AUTH_REGEX) || key.match(SCOPE_REGISTRY_REGEX)
- }
-})
diff --git a/default-opts.js b/default-opts.js
new file mode 100644
index 0000000..4d51da4
--- /dev/null
+++ b/default-opts.js
@@ -0,0 +1,22 @@
+const pkg = require('./package.json')
+const ciDetect = require('@npmcli/ci-detect')
+module.exports = {
+ isFromCI: ciDetect(),
+ log: require('./silentlog.js'),
+ maxSockets: 12,
+ method: 'GET',
+ registry: 'https://registry.npmjs.org/',
+ timeout: 30 * 1000,
+ strictSSL: true,
+ noProxy: process.env.NOPROXY,
+ userAgent: `${pkg.name
+ }@${
+ pkg.version
+ }/node@${
+ process.version
+ }+${
+ process.arch
+ } (${
+ process.platform
+ })`
+}
diff --git a/index.js b/index.js
index 47d0ab6..ffd8127 100644
--- a/index.js
+++ b/index.js
@@ -2,9 +2,7 @@
const Buffer = require('safe-buffer').Buffer
-const ciDetect = require('@npmcli/ci-detect')
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('minipass-json-stream')
@@ -14,6 +12,8 @@ const url = require('url')
const zlib = require('minizlib')
const Minipass = require('minipass')
+const defaultOpts = require('./default-opts.js')
+
// WhatWG URL throws if it's not fully resolved
const urlIsValid = u => {
try {
@@ -24,12 +24,15 @@ const urlIsValid = u => {
}
module.exports = regFetch
-function regFetch (uri, opts) {
- opts = config(opts)
- const registry = (
+function regFetch (uri, /* istanbul ignore next */ opts_ = {}) {
+ const opts = {
+ ...defaultOpts,
+ ...opts_
+ }
+ const registry = opts.registry = (
(opts.spec && pickRegistry(opts.spec, opts)) ||
opts.registry ||
- /* istanbul ignore next: default set in figgy pudding config */
+ /* istanbul ignore next */
'https://registry.npmjs.org/'
)
@@ -41,9 +44,7 @@ function regFetch (uri, opts) {
}`
}
- const method = opts.method ||
- /* istanbul ignore next: default set in figgy pudding config */
- 'GET'
+ const method = opts.method || 'GET'
// through that takes into account the scope, the prefix of `uri`, etc
const startTime = Date.now()
@@ -98,21 +99,21 @@ function regFetch (uri, opts) {
headers,
integrity: opts.integrity,
key: opts.key,
- localAddress: opts['local-address'],
- maxSockets: opts.maxsockets,
+ localAddress: opts.localAddress,
+ maxSockets: opts.maxSockets,
memoize: opts.memoize,
method: method,
- noProxy: opts['no-proxy'] || opts.noproxy,
- proxy: opts['https-proxy'] || opts.proxy,
+ noProxy: opts.noProxy,
+ proxy: opts.httpsProxy || opts.proxy,
referer: opts.refer,
- retry: opts.retry != null ? opts.retry : {
- retries: opts['fetch-retries'],
- factor: opts['fetch-retry-factor'],
- minTimeout: opts['fetch-retry-mintimeout'],
- maxTimeout: opts['fetch-retry-maxtimeout']
+ retry: opts.retry ? opts.retry : {
+ retries: opts.fetchRetries,
+ factor: opts.fetchRetryFactor,
+ minTimeout: opts.fetchRetryMintimeout,
+ maxTimeout: opts.fetchRetryMaxtimeout
},
- strictSSL: !!opts['strict-ssl'],
- timeout: opts.timeout
+ strictSSL: opts.strictSSL,
+ timeout: opts.timeout || 30 * 1000
}).then(res => checkResponse(
method, res, registry, startTime, opts
))
@@ -126,9 +127,9 @@ function fetchJSON (uri, opts) {
}
module.exports.json.stream = fetchJSONStream
-function fetchJSONStream (uri, jsonPath, opts) {
- opts = config(opts)
- const parser = JSONStream.parse(jsonPath, opts.mapJson)
+function fetchJSONStream (uri, jsonPath, /* istanbul ignore next */ opts_ = {}) {
+ const opts = { ...defaultOpts, ...opts_ }
+ const parser = JSONStream.parse(jsonPath, opts.mapJSON)
regFetch(uri, opts).then(res =>
res.body.on('error',
/* istanbul ignore next: unlikely and difficult to test */
@@ -138,9 +139,8 @@ function fetchJSONStream (uri, jsonPath, opts) {
}
module.exports.pickRegistry = pickRegistry
-function pickRegistry (spec, opts) {
+function pickRegistry (spec, opts = {}) {
spec = npa(spec)
- opts = config(opts)
let registry = spec.scope &&
opts[spec.scope.replace(/^@?/, '@') + ':registry']
@@ -149,9 +149,7 @@ function pickRegistry (spec, opts) {
}
if (!registry) {
- registry = opts.registry ||
- /* istanbul ignore next: default set by figgy pudding config */
- 'https://registry.npmjs.org/'
+ registry = opts.registry || 'https://registry.npmjs.org/'
}
return registry
@@ -160,23 +158,21 @@ function pickRegistry (spec, opts) {
function getCacheMode (opts) {
return opts.offline
? 'only-if-cached'
- : opts['prefer-offline']
+ : opts.preferOffline
? 'force-cache'
- : opts['prefer-online']
+ : opts.preferOnline
? 'no-cache'
: 'default'
}
function getHeaders (registry, uri, opts) {
const headers = Object.assign({
- 'npm-in-ci': !!(
- opts['is-from-ci'] || ciDetect()
- ),
- 'npm-scope': opts['project-scope'],
- 'npm-session': opts['npm-session'],
- 'user-agent': opts['user-agent'],
+ 'npm-in-ci': !!opts.isFromCI,
+ 'npm-scope': opts.projectScope,
+ 'npm-session': opts.npmSession,
+ 'user-agent': opts.userAgent,
referer: opts.refer
- }, opts.headers)
+ }, opts.headers || {})
const auth = getAuth(registry, opts)
// If a tarball is hosted on a different place than the manifest, only send
diff --git a/package.json b/package.json
index ddc971a..4d795fb 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,6 @@
"license": "ISC",
"dependencies": {
"@npmcli/ci-detect": "^1.0.0",
- "figgy-pudding": "^3.4.1",
"lru-cache": "^5.1.1",
"make-fetch-happen": "^7.1.0",
"minipass": "^3.0.0",
diff --git a/test/cache.js b/test/cache.js
index 97f7092..82f10d2 100644
--- a/test/cache.js
+++ b/test/cache.js
@@ -2,7 +2,6 @@
const { promisify } = require('util')
const statAsync = promisify(require('fs').stat)
-const config = require('../config.js')
const npmlog = require('npmlog')
const path = require('path')
const test = require('tap').test
@@ -14,7 +13,7 @@ const testDir = require('./util/test-dir.js')(__filename)
npmlog.level = process.env.LOGLEVEL || 'silent'
const REGISTRY = 'https://mock.reg'
-const OPTS = config({
+const OPTS = {
log: npmlog,
memoize: false,
timeout: 0,
@@ -26,7 +25,7 @@ const OPTS = config({
},
cache: path.join(testDir, '_cacache'),
registry: REGISTRY
-})
+}
test('can cache GET requests', t => {
tnock(t, REGISTRY)
@@ -35,22 +34,22 @@ test('can cache GET requests', t => {
.reply(200, { obj: 'value' })
return fetch.json('/normal', OPTS)
.then(val => t.deepEqual(val, { obj: 'value' }, 'got expected response'))
- .then(() => statAsync(OPTS.get('cache')))
+ .then(() => statAsync(OPTS.cache))
.then(stat => t.ok(stat.isDirectory(), 'cache directory created'))
.then(() => fetch.json('/normal', OPTS))
.then(val => t.deepEqual(val, { obj: 'value' }, 'response was cached'))
})
-test('prefer-offline', t => {
+test('preferOffline', t => {
tnock(t, REGISTRY)
- .get('/prefer-offline')
+ .get('/preferOffline')
.times(1)
.reply(200, { obj: 'value' })
- return fetch.json('/prefer-offline', OPTS.concat({ 'prefer-offline': true }))
+ return fetch.json('/preferOffline', { ...OPTS, preferOffline: true })
.then(val => t.deepEqual(val, { obj: 'value' }, 'got expected response'))
- .then(() => statAsync(OPTS.get('cache')))
+ .then(() => statAsync(OPTS.cache))
.then(stat => t.ok(stat.isDirectory(), 'cache directory created'))
- .then(() => fetch.json('/prefer-offline', OPTS.concat({ 'prefer-offline': true })))
+ .then(() => fetch.json('/preferOffline', { ...OPTS, preferOffline: true }))
.then(val => t.deepEqual(val, { obj: 'value' }, 'response was cached'))
})
@@ -61,24 +60,24 @@ test('offline', t => {
.reply(200, { obj: 'value' })
return fetch.json('/offline', OPTS)
.then(val => t.deepEqual(val, { obj: 'value' }, 'got expected response'))
- .then(() => statAsync(OPTS.get('cache')))
+ .then(() => statAsync(OPTS.cache))
.then(stat => t.ok(stat.isDirectory(), 'cache directory created'))
- .then(() => fetch.json('/offline', OPTS.concat({ offline: true })))
+ .then(() => fetch.json('/offline', { ...OPTS, offline: true }))
.then(val => t.deepEqual(val, { obj: 'value' }, 'response was cached'))
})
test('offline fails if not cached', t =>
- t.rejects(() => fetch('/offline-fails', OPTS.concat({ offline: true }))))
+ t.rejects(() => fetch('/offline-fails', { ...OPTS, offline: true })))
-test('prefer-online', t => {
+test('preferOnline', t => {
tnock(t, REGISTRY)
- .get('/prefer-online')
+ .get('/preferOnline')
.times(2)
.reply(200, { obj: 'value' })
- return fetch.json('/prefer-online', OPTS)
+ return fetch.json('/preferOnline', OPTS)
.then(val => t.deepEqual(val, { obj: 'value' }, 'got expected response'))
- .then(() => statAsync(OPTS.get('cache')))
+ .then(() => statAsync(OPTS.cache))
.then(stat => t.ok(stat.isDirectory(), 'cache directory created'))
- .then(() => fetch.json('/prefer-online', OPTS.concat({ 'prefer-online': true })))
+ .then(() => fetch.json('/preferOnline', { ...OPTS, preferOnline: true }))
.then(val => t.deepEqual(val, { obj: 'value' }, 'response was refetched'))
})
diff --git a/test/check-response.js b/test/check-response.js
index 1be1436..9556608 100644
--- a/test/check-response.js
+++ b/test/check-response.js
@@ -1,7 +1,6 @@
const { Readable } = require('stream')
const test = require('tap').test
-const config = require('../config.js')
const checkResponse = require('../check-response.js')
const errors = require('./errors.js')
const silentLog = require('../silentlog.js')
@@ -27,7 +26,16 @@ test('any response error should be silent', t => {
status: 400
})
t.rejects(checkResponse('get', res, 'registry', Date.now(), { ignoreBody: true }), errors.HttpErrorGeneral)
- t.done()
+ t.end()
+})
+
+test('all checks are ok, nothing to report', t => {
+ const res = Object.assign({}, mockFetchRes, {
+ buffer: () => Promise.resolve(Buffer.from('ok')),
+ status: 400
+ })
+ t.rejects(checkResponse('get', res, 'registry', Date.now()), errors.HttpErrorGeneral)
+ t.end()
})
test('log x-fetch-attempts header value', t => {
@@ -37,13 +45,13 @@ test('log x-fetch-attempts header value', t => {
headers,
status: 400
})
- t.rejects(checkResponse('get', res, 'registry', Date.now(), config({
+ t.rejects(checkResponse('get', res, 'registry', Date.now(), {
log: Object.assign({}, silentLog, {
http (header, msg) {
t.ok(msg.endsWith('attempt #3'), 'should log correct number of attempts')
}
})
- })))
+ }))
t.plan(2)
})
@@ -56,12 +64,12 @@ test('bad-formatted warning headers', t => {
const res = Object.assign({}, mockFetchRes, {
headers
})
- t.ok(checkResponse('get', res, 'registry', Date.now(), config({
+ t.ok(checkResponse('get', res, 'registry', Date.now(), {
log: Object.assign({}, silentLog, {
warn (header, msg) {
t.fail('should not log warnings')
}
})
- })))
+ }))
t.plan(1)
})
diff --git a/test/config.js b/test/config.js
deleted file mode 100644
index 2029257..0000000
--- a/test/config.js
+++ /dev/null
@@ -1,32 +0,0 @@
-'use strict'
-
-const config = require('../config.js')
-const npmlog = require('npmlog')
-const { test } = require('tap')
-
-npmlog.level = process.env.LOGLEVEL || 'silent'
-
-test('isFromCI config option', t => {
- const CI = process.env.CI
- process.env.CI = false
- t.teardown(t => {
- process.env.CI = CI
- })
- const OPTS = config({
- log: npmlog,
- timeout: 0,
- registry: 'https://mock.reg/'
- })
- t.notOk(OPTS.isFromCI, 'should be false if not on a CI env')
- t.end()
-})
-
-test('default timeout', t => {
- const DEFAULT_OPTS = config({})
- t.equal(DEFAULT_OPTS.timeout, 30 * 1000, 'default timeout is 30s')
- const SPECIFIED_OPTS = config({
- timeout: 15 * 1000
- })
- t.equal(SPECIFIED_OPTS.timeout, 15 * 1000, 'default timeout can be overridden')
- t.end()
-})
diff --git a/test/errors.js b/test/errors.js
index 54d7de1..e3ab7c5 100644
--- a/test/errors.js
+++ b/test/errors.js
@@ -1,6 +1,5 @@
'use strict'
-const config = require('../config.js')
const npa = require('npm-package-arg')
const npmlog = require('npmlog')
const test = require('tap').test
@@ -9,7 +8,7 @@ const tnock = require('./util/tnock.js')
const fetch = require('../index.js')
npmlog.level = process.env.LOGLEVEL || 'silent'
-const OPTS = config({
+const OPTS = {
log: npmlog,
timeout: 0,
retry: {
@@ -19,7 +18,7 @@ const OPTS = config({
maxTimeout: 10
},
registry: 'https://mock.reg/'
-})
+}
test('generic request errors', t => {
tnock(t, OPTS.registry)
@@ -69,9 +68,10 @@ test('pkgid with `opts.spec`', t => {
tnock(t, OPTS.registry)
.get('/ohno/_rewrite/ohyeah')
.reply(400, 'failwhale!')
- return fetch('/ohno/_rewrite/ohyeah', OPTS.concat({
+ return fetch('/ohno/_rewrite/ohyeah', {
+ ...OPTS,
spec: npa('foo@1.2.3')
- }))
+ })
.then(
() => { throw new Error('should not have succeeded!') },
err => t.equal(err.pkgid, 'foo@1.2.3', 'opts.spec used for pkgid')
diff --git a/test/index.js b/test/index.js
index 93818b4..2ad80ad 100644
--- a/test/index.js
+++ b/test/index.js
@@ -2,7 +2,6 @@
const Buffer = require('safe-buffer').Buffer
-const config = require('../config.js')
const Minipass = require('minipass')
const npmlog = require('npmlog')
const silentLog = require('../silentlog.js')
@@ -14,7 +13,7 @@ const zlib = require('zlib')
const fetch = require('../index.js')
npmlog.level = process.env.LOGLEVEL || 'silent'
-const OPTS = config({
+const OPTS = {
// just to make sure we hit the second branch when
// we are ACTUALLY in CI
isFromCI: false,
@@ -27,13 +26,16 @@ const OPTS = config({
maxTimeout: 10
},
registry: 'https://mock.reg/'
-})
+}
test('hello world', t => {
tnock(t, OPTS.registry)
.get('/hello')
.reply(200, { hello: 'world' })
- return fetch('/hello', OPTS)
+ return fetch('/hello', {
+ method: false, // will fall back to GET if falsey,
+ ...OPTS
+ })
.then(res => {
t.equal(res.status, 200, 'got successful response')
return res.json()
@@ -54,10 +56,11 @@ test('JSON body param', t => {
}, 'got the JSON version of the body')
return reqBody
})
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
method: 'POST',
body: { hello: 'world' }
- })
+ }
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
@@ -81,10 +84,11 @@ test('buffer body param', t => {
)
return reqBody
})
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
method: 'POST',
body: Buffer.from('hello', 'utf8')
- })
+ }
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
@@ -110,10 +114,11 @@ test('stream body param', t => {
})
const stream = new Minipass()
setImmediate(() => stream.end(JSON.stringify({ hello: 'world' })))
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
method: 'POST',
body: stream
- })
+ }
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
@@ -135,11 +140,12 @@ test('JSON body param', t => {
.post('/hello')
// NOTE: can't really test the body itself here because nock freaks out.
.reply(200)
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
method: 'POST',
body: { hello: 'world' },
gzip: true
- })
+ }
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200, 'request succeeded')
@@ -166,11 +172,12 @@ test('gzip + buffer body param', t => {
)
return reqBody
})
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
method: 'POST',
body: Buffer.from('hello', 'utf8'),
gzip: true
- })
+ }
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
@@ -201,7 +208,8 @@ test('gzip + stream body param', t => {
})
const stream = new Minipass()
setImmediate(() => stream.end(JSON.stringify({ hello: 'world' })))
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
method: 'POST',
body: stream,
gzip: true,
@@ -209,7 +217,7 @@ test('gzip + stream body param', t => {
everything: undefined,
is: undefined
}
- })
+ }
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200)
@@ -222,18 +230,20 @@ test('query strings', t => {
tnock(t, OPTS.registry)
.get('/hello?hi=there&who=wor%20ld')
.reply(200, { hello: 'world' })
- return fetch.json('/hello?hi=there', OPTS.concat({
+ return fetch.json('/hello?hi=there', {
+ ...OPTS,
query: 'who=wor ld'
- })).then(json => t.equal(json.hello, 'world', 'query-string merged'))
+ }).then(json => t.equal(json.hello, 'world', 'query-string merged'))
})
test('query strings - undefined values', t => {
tnock(t, OPTS.registry)
.get('/hello?who=wor%20ld')
.reply(200, { ok: true })
- return fetch.json('/hello', OPTS.concat({
+ return fetch.json('/hello', {
+ ...OPTS,
query: { hi: undefined, who: 'wor ld' }
- })).then(json => t.ok(json.ok, 'undefined keys not included in query string'))
+ }).then(json => t.ok(json.ok, 'undefined keys not included in query string'))
})
test('json()', t => {
@@ -259,17 +269,18 @@ test('fetch.json.stream()', t => {
})
})
-test('fetch.json.stream opts.mapJson', t => {
+test('fetch.json.stream opts.mapJSON', t => {
tnock(t, OPTS.registry).get('/hello').reply(200, {
a: 1,
b: 2,
c: 3
})
- return fetch.json.stream('/hello', '*', OPTS.concat({
- mapJson (value, [key]) {
+ return fetch.json.stream('/hello', '*', {
+ ...OPTS,
+ mapJSON (value, [key]) {
return [key, value]
}
- })).collect().then(data => {
+ }).collect().then(data => {
t.deepEqual(data, [
['a', 1],
['b', 2],
@@ -279,11 +290,12 @@ test('fetch.json.stream opts.mapJson', t => {
})
test('fetch.json.stream gets fetch error on stream', t => {
- return t.rejects(fetch.json.stream('/hello', '*', OPTS.concat({
+ return t.rejects(fetch.json.stream('/hello', '*', {
+ ...OPTS,
body: Promise.reject(new Error('no body for you')),
method: 'POST',
gzip: true // make sure we don't gzip the promise, lol!
- })).collect(), {
+ }).collect(), {
message: 'no body for you'
})
})
@@ -292,7 +304,7 @@ test('opts.ignoreBody', t => {
tnock(t, OPTS.registry)
.get('/hello')
.reply(200, { hello: 'world' })
- return fetch('/hello', OPTS.concat({ ignoreBody: true }))
+ return fetch('/hello', { ...OPTS, ignoreBody: true })
.then(res => {
t.equal(res.body, null, 'body omitted')
})
@@ -302,9 +314,10 @@ test('method configurable', t => {
tnock(t, OPTS.registry)
.delete('/hello')
.reply(200)
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
method: 'DELETE'
- })
+ }
return fetch('/hello', opts)
.then(res => {
t.equal(res.status, 200, 'successfully used DELETE method')
@@ -317,14 +330,15 @@ test('npm-notice header logging', t => {
.reply(200, { hello: 'world' }, {
'npm-notice': 'npm <3 u'
})
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
log: Object.assign({}, silentLog, {
notice (header, msg) {
t.equal(header, '', 'empty log header thing')
t.equal(msg, 'npm <3 u', 'logged out npm-notice at NOTICE level')
}
})
- })
+ }
t.plan(3)
return fetch('/hello', opts)
.then(res => t.equal(res.status, 200, 'got successful response'))
@@ -337,13 +351,13 @@ test('optionally verifies request body integrity', t => {
.times(2)
.reply(200, 'hello')
const integrity = ssri.fromData('hello')
- return fetch('/hello', OPTS.concat({ integrity }))
+ return fetch('/hello', { ...OPTS, integrity })
.then(res => res.buffer())
.then(buf => t.equal(
buf.toString('utf8'), 'hello', 'successfully got the right data')
)
.then(() => {
- return fetch('/hello', OPTS.concat({ integrity: 'sha1-nope' }))
+ return fetch('/hello', { ...OPTS, integrity: 'sha1-nope' })
.then(res => {
t.ok(res.body, 'no error until body starts getting read')
return res
@@ -398,18 +412,20 @@ test('pickRegistry through opts.spec', t => {
.get('/pkg')
.times(2)
.reply(200, { source: scopedReg })
- return fetch.json('/pkg', OPTS.concat({
+ return fetch.json('/pkg', {
+ ...OPTS,
spec: 'pkg@1.2.3',
'@myscope:registry': scopedReg
- })).then(json => t.equal(
+ }).then(json => t.equal(
json.source,
OPTS.registry,
'request made to main registry'
- )).then(() => fetch.json('/pkg', OPTS.concat({
+ )).then(() => fetch.json('/pkg', {
+ ...OPTS,
spec: 'pkg@1.2.3',
'@myscope:registry': scopedReg,
scope: '@myscope'
- }))).then(json => t.equal(
+ })).then(json => t.equal(
json.source,
scopedReg,
'request made to scope registry using opts.scope'
@@ -427,14 +443,15 @@ test('log warning header info', t => {
tnock(t, OPTS.registry)
.get('/hello')
.reply(200, { hello: 'world' }, { Warning: '199 - "ENOTFOUND" "Wed, 21 Oct 2015 07:28:00 GMT"' })
- const opts = OPTS.concat({
+ const opts = {
+ ...OPTS,
log: Object.assign({}, silentLog, {
warn (header, msg) {
t.equal(header, 'registry', 'expected warn log header')
t.equal(msg, `Using stale data from ${OPTS.registry} because the host is inaccessible -- are you offline?`, 'logged out at WARNING level')
}
})
- })
+ }
t.plan(3)
return fetch('/hello', opts)
.then(res => t.equal(res.status, 200, 'got successful response'))