Skip to content

Commit 83f89f3

Browse files
committedFeb 14, 2020
fix: always bypass cache when ?write=true
The npm CLI makes GET requests with ?write=true in some cases where it's intending to send an immediate PUT or DELETE. Always bypass the cache for such requests, mirroring the behavior of the registry caching mechanisms.
1 parent 55d602e commit 83f89f3

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed
 

‎index.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,13 @@ function regFetch (uri, opts) {
7373
}
7474
}
7575

76+
const parsed = new url.URL(uri)
77+
7678
if (opts.query) {
7779
const q = typeof opts.query === 'string'
7880
? qs.parse(opts.query)
7981
: opts.query
8082

81-
const parsed = new url.URL(uri)
8283
Object.keys(q).forEach(key => {
8384
if (q[key] !== undefined) {
8485
parsed.searchParams.set(key, q[key])
@@ -87,6 +88,17 @@ function regFetch (uri, opts) {
8788
uri = url.format(parsed)
8889
}
8990

91+
if (parsed.searchParams.get('write') === 'true' && method === 'GET') {
92+
// do not cache, because this GET is fetching a rev that will be
93+
// used for a subsequent PUT or DELETE, so we need to conditionally
94+
// update cache.
95+
opts = opts.concat({
96+
offline: false,
97+
'prefer-offline': false,
98+
'prefer-online': true
99+
})
100+
}
101+
90102
const doFetch = (body) => fetch(uri, {
91103
agent: opts.agent,
92104
algorithms: opts.algorithms,

‎test/index.js

+24
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,30 @@ test('json()', t => {
244244
.then(json => t.deepEqual(json, { hello: 'world' }, 'got json body'))
245245
})
246246

247+
test('query string with ?write=true', t => {
248+
const cache = t.testdir()
249+
const opts = OPTS.concat({ 'prefer-offline': true, cache })
250+
const qsString = opts.concat({ query: { write: 'true' } })
251+
const qsBool = opts.concat({ query: { write: true } })
252+
tnock(t, opts.registry)
253+
.get('/hello?write=true')
254+
.times(6)
255+
.reply(200, { write: 'go for it' })
256+
257+
return fetch.json('/hello?write=true', opts)
258+
.then(res => t.strictSame(res, { write: 'go for it' }))
259+
.then(() => fetch.json('/hello?write=true', opts))
260+
.then(res => t.strictSame(res, { write: 'go for it' }))
261+
.then(() => fetch.json('/hello', qsString))
262+
.then(res => t.strictSame(res, { write: 'go for it' }))
263+
.then(() => fetch.json('/hello', qsString))
264+
.then(res => t.strictSame(res, { write: 'go for it' }))
265+
.then(() => fetch.json('/hello', qsBool))
266+
.then(res => t.strictSame(res, { write: 'go for it' }))
267+
.then(() => fetch.json('/hello', qsBool))
268+
.then(res => t.strictSame(res, { write: 'go for it' }))
269+
})
270+
247271
test('fetch.json.stream()', t => {
248272
tnock(t, OPTS.registry).get('/hello').reply(200, {
249273
a: 1,

0 commit comments

Comments
 (0)
Please sign in to comment.