@vltpkg/registry-client 0.0.0-9 → 1.0.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +1 -1
  2. package/dist/esm/cache-entry.d.ts +32 -8
  3. package/dist/esm/cache-entry.d.ts.map +1 -1
  4. package/dist/esm/cache-entry.js +141 -62
  5. package/dist/esm/cache-entry.js.map +1 -1
  6. package/dist/esm/handle-304-response.js +1 -1
  7. package/dist/esm/handle-304-response.js.map +1 -1
  8. package/dist/esm/index.d.ts +2 -2
  9. package/dist/esm/index.d.ts.map +1 -1
  10. package/dist/esm/index.js +48 -25
  11. package/dist/esm/index.js.map +1 -1
  12. package/dist/esm/otplease.d.ts.map +1 -1
  13. package/dist/esm/otplease.js +33 -25
  14. package/dist/esm/otplease.js.map +1 -1
  15. package/dist/esm/raw-header.d.ts +3 -3
  16. package/dist/esm/raw-header.d.ts.map +1 -1
  17. package/dist/esm/raw-header.js +12 -11
  18. package/dist/esm/raw-header.js.map +1 -1
  19. package/dist/esm/redirect.d.ts +1 -1
  20. package/dist/esm/redirect.d.ts.map +1 -1
  21. package/dist/esm/redirect.js +5 -1
  22. package/dist/esm/redirect.js.map +1 -1
  23. package/dist/esm/revalidate.d.ts +1 -1
  24. package/dist/esm/revalidate.d.ts.map +1 -1
  25. package/dist/esm/revalidate.js +11 -5
  26. package/dist/esm/revalidate.js.map +1 -1
  27. package/dist/esm/set-raw-header.d.ts +1 -1
  28. package/dist/esm/set-raw-header.d.ts.map +1 -1
  29. package/dist/esm/set-raw-header.js +6 -4
  30. package/dist/esm/set-raw-header.js.map +1 -1
  31. package/dist/esm/string-encoding.d.ts +9 -0
  32. package/dist/esm/string-encoding.d.ts.map +1 -0
  33. package/dist/esm/string-encoding.js +25 -0
  34. package/dist/esm/string-encoding.js.map +1 -0
  35. package/dist/esm/token-response.d.ts +1 -1
  36. package/dist/esm/token-response.d.ts.map +1 -1
  37. package/dist/esm/token-response.js +5 -2
  38. package/dist/esm/token-response.js.map +1 -1
  39. package/dist/esm/web-auth-challenge.d.ts +2 -2
  40. package/dist/esm/web-auth-challenge.d.ts.map +1 -1
  41. package/dist/esm/web-auth-challenge.js +13 -6
  42. package/dist/esm/web-auth-challenge.js.map +1 -1
  43. package/package.json +23 -22
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAIrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAM9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,EAAS,UAAU,EAAE,MAAM,QAAQ,CAAA;AAE1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EACL,WAAW,EACX,KAAK,EAEL,OAAO,EACP,SAAS,EACT,QAAQ,EACT,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAO7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE/D,OAAO,EACL,UAAU,EACV,WAAW,EACX,KAAK,EACL,OAAO,EACP,SAAS,EACT,QAAQ,EACR,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,aAAa,EAClB,KAAK,gBAAgB,GACtB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,CAAA;AAC5C,eAAO,MAAM,iBAAiB,MAAO,OAAO,KAAG,CAAC,IAAI,eACvB,CAAA;AAE7B,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,yDAAyD;IACzD,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,yDAAyD;IACzD,wBAAwB,CAAC,EAAE,MAAM,CAAA;IAEjC,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;;;;;;;;;;;OAcG;IACH,+BAA+B,CAAC,EAAE,MAAM,CAAA;CACzC,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG,IAAI,CAC7C,UAAU,CAAC,cAAc,EACzB,QAAQ,GAAG,MAAM,CAClB,GAAG;IACF;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;IAC7C;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAA;IAErB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IAExB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IAExB;;;;OAIG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAE1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAA;IAEhB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,KAAK,CAAA;CAC7B,CAAA;AAgBD,eAAO,MAAM,SAAS,QAA8C,CAAA;AAoBpE,qBAAa,cAAc;;IACzB,KAAK,EAAE,UAAU,CAAA;IACjB,KAAK,EAAE,KAAK,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,0BAA0B,EAAE,MAAM,CAAA;gBAEtB,OAAO,EAAE,qBAAqB;IA0C1C;;OAEG;IACG,MAAM,CAAC,CAAC,EACZ,GAAG,EAAE,GAAG,GAAG,MAAM,EACjB,OAAO,GAAE,4BAAiC,EAC1C,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,GACzB,OAAO,CAAC,CAAC,EAAE,CAAC;IAYf;;OAEG;IACG,IAAI,CAAC,CAAC,EACV,GAAG,EAAE,GAAG,GAAG,MAAM,EACjB,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,EACzB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIzB;;;OAGG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM;IA0B7B;;;;;OAKG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM;IAqC5B;;;OAGG;IACG,aAAa,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,gBAAgB;IA6CrD,OAAO,CACX,GAAG,EAAE,GAAG,GAAG,MAAM,EACjB,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,UAAU,CAAC;CAuJvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  import { Cache } from '@vltpkg/cache';
2
2
  import { register as cacheUnzipRegister } from '@vltpkg/cache-unzip';
3
- import { asError, error } from '@vltpkg/error-cause';
3
+ import { error } from '@vltpkg/error-cause';
4
+ import { asError } from '@vltpkg/types';
4
5
  import { logRequest } from '@vltpkg/output';
5
6
  import { urlOpen } from '@vltpkg/url-open';
6
7
  import { XDG } from '@vltpkg/xdg';
7
- import { resolve } from 'node:path';
8
+ import { dirname, resolve } from 'node:path';
8
9
  import { setTimeout } from 'node:timers/promises';
9
10
  import { loadPackageJson } from 'package-json-from-dist';
10
11
  import { Agent, RetryAgent } from 'undici';
@@ -17,18 +18,17 @@ import { handle304Response } from "./handle-304-response.js";
17
18
  import { otplease } from "./otplease.js";
18
19
  import { isRedirect, redirect } from "./redirect.js";
19
20
  import { setCacheHeaders } from "./set-cache-headers.js";
20
- import { isTokenResponse } from "./token-response.js";
21
- import { isWebAuthChallenge } from "./web-auth-challenge.js";
21
+ import { getTokenResponse } from "./token-response.js";
22
+ import { getWebAuthChallenge } from "./web-auth-challenge.js";
23
+ import { getEncondedValue } from "./string-encoding.js";
22
24
  export { CacheEntry, deleteToken, getKC, isToken, keychains, setToken, };
23
25
  export const isCacheableMethod = (m) => m === 'GET' || m === 'HEAD';
24
26
  const { version } = loadPackageJson(import.meta.filename, process.env.__VLT_INTERNAL_REGISTRY_CLIENT_PACKAGE_JSON);
25
- /* c8 ignore start - we do test this, but coverage fails */
26
27
  const nua = globalThis.navigator?.userAgent ??
27
28
  (bun ? `Bun/${bun}`
28
29
  : deno ? `Deno/${deno}`
29
30
  : node ? `Node.js/${node}`
30
31
  : '(unknown platform)');
31
- /* c8 ignore stop */
32
32
  export const userAgent = `@vltpkg/registry-client/${version} ${nua}`;
33
33
  const agentOptions = {
34
34
  bodyTimeout: 600_000,
@@ -52,7 +52,8 @@ export class RegistryClient {
52
52
  identity;
53
53
  staleWhileRevalidateFactor;
54
54
  constructor(options) {
55
- const { cache = xdg.cache(), 'fetch-retry-factor': timeoutFactor = 2, 'fetch-retry-mintimeout': minTimeout = 0, 'fetch-retry-maxtimeout': maxTimeout = 30_000, 'fetch-retries': maxRetries = 3, identity = '', 'stale-while-revalidate-factor': staleWhileRevalidateFactor = 60, } = options;
55
+ const { cache = xdg.cache(), 'fetch-retry-factor': timeoutFactor = 2, 'fetch-retry-mintimeout': minTimeout = 0, 'fetch-retry-maxtimeout': maxTimeout = 30_000, 'fetch-retries': maxRetries = 3, identity = '', 'stale-while-revalidate-factor': staleWhileRevalidateFactor = 576, // 48h for a 5min cache
56
+ } = options;
56
57
  this.identity = identity;
57
58
  this.staleWhileRevalidateFactor = staleWhileRevalidateFactor;
58
59
  const path = resolve(cache, 'registry-client');
@@ -129,8 +130,8 @@ export class RegistryClient {
129
130
  async login(registry) {
130
131
  // - make POST to '/-/v1/login'
131
132
  // - include a body of {} and npm-auth-type:web
132
- // - get a {doneUrl, loginUrl}
133
- // - open the loginUrl
133
+ // - get a {doneUrl, authUrl}
134
+ // - open the authUrl
134
135
  // - hang on the doneUrl until done
135
136
  //
136
137
  // if that fails: fall back to couchdb login
@@ -145,8 +146,8 @@ export class RegistryClient {
145
146
  body: '{}',
146
147
  });
147
148
  if (response.statusCode === 200) {
148
- const challenge = response.json();
149
- if (isWebAuthChallenge(challenge)) {
149
+ const challenge = getWebAuthChallenge(response.json());
150
+ if (challenge) {
150
151
  const result = await this.webAuthOpener(challenge);
151
152
  await setToken(registry, `Bearer ${result.token}`, this.identity);
152
153
  return;
@@ -158,10 +159,10 @@ export class RegistryClient {
158
159
  }
159
160
  /* c8 ignore stop */
160
161
  /**
161
- * Given a {@link WebAuthChallenge}, open the `loginUrl` in a browser and
162
+ * Given a {@link WebAuthChallenge}, open the `authUrl` in a browser and
162
163
  * hang on the `doneUrl` until it returns a {@link TokenResponse} object.
163
164
  */
164
- async webAuthOpener({ doneUrl, loginUrl }) {
165
+ async webAuthOpener({ doneUrl, authUrl }) {
165
166
  const ac = new AbortController();
166
167
  const { signal } = ac;
167
168
  /* c8 ignore start - race condition */
@@ -170,7 +171,7 @@ export class RegistryClient {
170
171
  ac.abort();
171
172
  return result;
172
173
  }),
173
- urlOpen(loginUrl, { signal }).catch((er) => {
174
+ urlOpen(authUrl, { signal }).catch((er) => {
174
175
  if (asError(er).name === 'AbortError')
175
176
  return;
176
177
  ac.abort();
@@ -187,24 +188,23 @@ export class RegistryClient {
187
188
  });
188
189
  const { signal } = options;
189
190
  if (response.statusCode === 202) {
190
- const rt = response.getHeader('retry-after');
191
- const retryAfter = rt ? Number(rt.toString()) : -1;
191
+ const rt = response.getHeaderString('retry-after');
192
+ const retryAfter = rt ? Number(rt) : -1;
192
193
  if (retryAfter > 0) {
193
194
  await setTimeout(retryAfter * 1000, null, { signal });
194
195
  }
195
196
  return await this.#checkLogin(url, options);
196
197
  }
197
198
  if (response.statusCode === 200) {
198
- const body = response.json();
199
- if (isTokenResponse(body))
200
- return body;
199
+ const token = getTokenResponse(response.json());
200
+ if (token)
201
+ return token;
201
202
  }
202
203
  throw error('Invalid response from web login endpoint', {
203
204
  response,
204
205
  });
205
206
  }
206
207
  async request(url, options = {}) {
207
- logRequest(url, 'start');
208
208
  const u = typeof url === 'string' ? new URL(url) : url;
209
209
  const { method = 'GET', integrity, redirections = new Set(), signal, otp = (process.env.VLT_OTP ?? '').trim(), staleWhileRevalidate = true, } = options;
210
210
  let { trustIntegrity } = options;
@@ -219,13 +219,16 @@ export class RegistryClient {
219
219
  : undefined;
220
220
  const entry = buffer ? CacheEntry.decode(buffer) : undefined;
221
221
  if (entry?.valid) {
222
+ logRequest(url, 'cache');
222
223
  return entry;
223
224
  }
224
225
  if (staleWhileRevalidate && entry?.staleWhileRevalidate && m) {
225
226
  // revalidate while returning the stale entry
226
- register(this.cache.path(), m, url);
227
+ register(dirname(this.cache.path()), m, url);
228
+ logRequest(url, 'stale');
227
229
  return entry;
228
230
  }
231
+ logRequest(url, 'start');
229
232
  // either no cache entry, or need to revalidate before use.
230
233
  setCacheHeaders(options, entry);
231
234
  redirections.add(String(url));
@@ -244,7 +247,22 @@ export class RegistryClient {
244
247
  options.method = options.method ?? 'GET';
245
248
  // will remove if we don't have a token.
246
249
  options.headers = addHeader(options.headers, 'authorization', await getToken(origin, this.identity));
247
- const result = await this.#handleResponse(u, options, await this.agent.request(options), entry);
250
+ let response = null;
251
+ try {
252
+ response = await this.agent.request(options);
253
+ /* c8 ignore start */
254
+ }
255
+ catch (er) {
256
+ // Rethrow so we get a better stack trace
257
+ throw error('Request failed', {
258
+ code: 'EREQUEST',
259
+ cause: er,
260
+ url,
261
+ method,
262
+ });
263
+ }
264
+ /* c8 ignore stop */
265
+ const result = await this.#handleResponse(u, options, response, entry);
248
266
  if (result.getHeader('integrity')) {
249
267
  trustIntegrity = true;
250
268
  }
@@ -252,7 +270,9 @@ export class RegistryClient {
252
270
  result.checkIntegrity({ url });
253
271
  }
254
272
  if (useCache) {
255
- this.cache.set(key, result.encode(), {
273
+ // Get the encoded buffer from the cache entry
274
+ const buffer = result.encode();
275
+ this.cache.set(key, Buffer.from(buffer.buffer, buffer.byteOffset, buffer.byteLength), {
256
276
  integrity: result.integrity,
257
277
  });
258
278
  }
@@ -270,11 +290,11 @@ export class RegistryClient {
270
290
  for (const [key, value] of Object.entries(response.headers)) {
271
291
  /* c8 ignore start - theoretical */
272
292
  if (Array.isArray(value)) {
273
- h.push(Buffer.from(key), Buffer.from(value.join(', ')));
293
+ h.push(getEncondedValue(key), getEncondedValue(value.join(', ')));
274
294
  /* c8 ignore stop */
275
295
  }
276
296
  else if (typeof value === 'string') {
277
- h.push(Buffer.from(key), Buffer.from(value));
297
+ h.push(getEncondedValue(key), getEncondedValue(value));
278
298
  }
279
299
  }
280
300
  const { integrity, trustIntegrity } = options;
@@ -284,6 +304,9 @@ export class RegistryClient {
284
304
  integrity,
285
305
  trustIntegrity,
286
306
  'stale-while-revalidate-factor': this.staleWhileRevalidateFactor,
307
+ contentLength: response.headers['content-length'] ?
308
+ Number(response.headers['content-length'])
309
+ : /* c8 ignore next */ undefined,
287
310
  });
288
311
  if (isRedirect(result)) {
289
312
  response.body.resume();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Cache } from '@vltpkg/cache'\nimport { register as cacheUnzipRegister } from '@vltpkg/cache-unzip'\nimport { asError, error } from '@vltpkg/error-cause'\nimport { logRequest } from '@vltpkg/output'\nimport type { Integrity } from '@vltpkg/types'\nimport { urlOpen } from '@vltpkg/url-open'\nimport { XDG } from '@vltpkg/xdg'\nimport { resolve } from 'node:path'\nimport { setTimeout } from 'node:timers/promises'\nimport { loadPackageJson } from 'package-json-from-dist'\nimport type { Dispatcher } from 'undici'\nimport { Agent, RetryAgent } from 'undici'\nimport { addHeader } from './add-header.ts'\nimport type { Token } from './auth.ts'\nimport {\n deleteToken,\n getKC,\n getToken,\n isToken,\n keychains,\n setToken,\n} from './auth.ts'\nimport type { JSONObj } from './cache-entry.ts'\nimport { CacheEntry } from './cache-entry.ts'\nimport { register } from './cache-revalidate.ts'\nimport { bun, deno, node } from './env.ts'\nimport { handle304Response } from './handle-304-response.ts'\nimport { otplease } from './otplease.ts'\nimport { isRedirect, redirect } from './redirect.ts'\nimport { setCacheHeaders } from './set-cache-headers.ts'\nimport type { TokenResponse } from './token-response.ts'\nimport { isTokenResponse } from './token-response.ts'\nimport type { WebAuthChallenge } from './web-auth-challenge.ts'\nimport { isWebAuthChallenge } from './web-auth-challenge.ts'\nexport {\n CacheEntry,\n deleteToken,\n getKC,\n isToken,\n keychains,\n setToken,\n type JSONObj,\n type Token,\n type TokenResponse,\n type WebAuthChallenge,\n}\n\nexport type CacheableMethod = 'GET' | 'HEAD'\nexport const isCacheableMethod = (m: unknown): m is CacheableMethod =>\n m === 'GET' || m === 'HEAD'\n\nexport type RegistryClientOptions = {\n /**\n * Path on disk where the cache should be stored\n *\n * Defaults to the XDG cache folder for `vlt/registry-client`\n */\n cache?: string\n /**\n * Number of retries to perform when encountering network errors or\n * likely-transient errors from git hosts.\n */\n 'fetch-retries'?: number\n /** The exponential backoff factor to use when retrying git hosts */\n 'fetch-retry-factor'?: number\n /** Number of milliseconds before starting first retry */\n 'fetch-retry-mintimeout'?: number\n /** Maximum number of milliseconds between two retries */\n 'fetch-retry-maxtimeout'?: number\n\n /** the identity to use for storing auth tokens */\n identity?: string\n\n /**\n * If the server does not serve a `stale-while-revalidate` value in the\n * `cache-control` header, then this multiplier is applied to the `max-age`\n * or `s-maxage` values.\n *\n * By default, this is `60`, so for example a response that is cacheable for\n * 5 minutes will allow a stale response while revalidating for up to 5\n * hours.\n *\n * If the server *does* provide a `stale-while-revalidate` value, then that\n * is always used.\n *\n * Set to 0 to prevent any `stale-while-revalidate` behavior unless\n * explicitly allowed by the server's `cache-control` header.\n */\n 'stale-while-revalidate-factor'?: number\n}\n\nexport type RegistryClientRequestOptions = Omit<\n Dispatcher.RequestOptions,\n 'method' | 'path'\n> & {\n /**\n * `path` should not be set when using the RegistryClient.\n * It will be overwritten with the path on the URL being requested.\n * This only here for compliance with the DispatchOptions base type.\n * @deprecated\n */\n path?: string\n\n /**\n * Method is optional, defaults to 'GET'\n */\n method?: Dispatcher.DispatchOptions['method']\n /**\n * Provide an SRI string to verify integrity of the item being fetched.\n *\n * This is only relevant when it must make a request to the registry. Once in\n * the local disk cache, items are assumed to be trustworthy.\n */\n integrity?: Integrity\n\n /**\n * Set to true if the integrity should be trusted implicitly without\n * a recalculation, for example if it comes from a trusted registry that\n * also serves the tarball itself.\n */\n trustIntegrity?: boolean\n\n /**\n * Follow up to 10 redirections by default. Set this to 0 to just return\n * the 3xx response. If the max redirections are expired, and we still get\n * a redirection response, then fail the request. Redirection cycles are\n * always treated as an error.\n */\n maxRedirections?: number\n\n /**\n * the number of redirections that have already been seen. This is used\n * internally, and should always start at 0.\n * @internal\n */\n redirections?: Set<string>\n\n /**\n * Set to `false` to suppress ANY lookups from cache. This will also\n * prevent storing the result to the cache.\n */\n useCache?: false\n\n /**\n * Set to pass an `npm-otp` header on the request.\n *\n * This should not be set except by the RegistryClient itself, when\n * we receive a 401 response with an OTP challenge.\n * @internal\n */\n otp?: string\n\n /**\n * Set to false to explicitly prevent `stale-while-revalidate` behavior,\n * for use in revalidating while stale.\n * @internal\n */\n staleWhileRevalidate?: false\n}\n\nconst { version } = loadPackageJson(\n import.meta.filename,\n process.env.__VLT_INTERNAL_REGISTRY_CLIENT_PACKAGE_JSON,\n) as {\n version: string\n}\n/* c8 ignore start - we do test this, but coverage fails */\nconst nua =\n (globalThis.navigator as Navigator | undefined)?.userAgent ??\n (bun ? `Bun/${bun}`\n : deno ? `Deno/${deno}`\n : node ? `Node.js/${node}`\n : '(unknown platform)')\n/* c8 ignore stop */\nexport const userAgent = `@vltpkg/registry-client/${version} ${nua}`\n\nconst agentOptions: Agent.Options = {\n bodyTimeout: 600_000,\n headersTimeout: 600_000,\n keepAliveMaxTimeout: 1_200_000,\n keepAliveTimeout: 600_000,\n keepAliveTimeoutThreshold: 30_000,\n connect: {\n timeout: 600_000,\n keepAlive: true,\n keepAliveInitialDelay: 30_000,\n sessionTimeout: 600,\n },\n connections: 128,\n pipelining: 10,\n}\n\nconst xdg = new XDG('vlt')\n\nexport class RegistryClient {\n agent: RetryAgent\n cache: Cache\n identity: string\n staleWhileRevalidateFactor: number\n\n constructor(options: RegistryClientOptions) {\n const {\n cache = xdg.cache(),\n 'fetch-retry-factor': timeoutFactor = 2,\n 'fetch-retry-mintimeout': minTimeout = 0,\n 'fetch-retry-maxtimeout': maxTimeout = 30_000,\n 'fetch-retries': maxRetries = 3,\n identity = '',\n 'stale-while-revalidate-factor':\n staleWhileRevalidateFactor = 60,\n } = options\n this.identity = identity\n this.staleWhileRevalidateFactor = staleWhileRevalidateFactor\n const path = resolve(cache, 'registry-client')\n this.cache = new Cache({\n path,\n onDiskWrite(_path, key, data) {\n if (CacheEntry.isGzipEntry(data)) {\n cacheUnzipRegister(path, key)\n }\n },\n })\n const dispatch = new Agent(agentOptions)\n this.agent = new RetryAgent(dispatch, {\n maxRetries,\n timeoutFactor,\n minTimeout,\n maxTimeout,\n retryAfter: true,\n errorCodes: [\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'EHOSTDOWN',\n 'ENETDOWN',\n 'ENETUNREACH',\n 'ENOTFOUND',\n 'EPIPE',\n 'UND_ERR_SOCKET',\n ],\n })\n }\n\n /**\n * Fetch the entire set of a paginated list of objects\n */\n async scroll<T>(\n url: URL | string,\n options: RegistryClientRequestOptions = {},\n seek?: (obj: T) => boolean,\n ): Promise<T[]> {\n const resp = await this.request(url, options)\n const { objects, urls } = resp.json() as {\n objects: T[]\n urls: { next?: string }\n }\n // if we have more, and haven't found our target, fetch more\n return urls.next && !(seek && objects.some(seek)) ?\n objects.concat(await this.scroll<T>(urls.next, options, seek))\n : objects\n }\n\n /**\n * find a given item in a paginated set\n */\n async seek<T>(\n url: URL | string,\n seek: (obj: T) => boolean,\n options: RegistryClientRequestOptions = {},\n ): Promise<T | undefined> {\n return (await this.scroll(url, options, seek)).find(seek)\n }\n\n /**\n * Log out from the registry specified, attempting to destroy the\n * token if the registry supports that endpoint.\n */\n async logout(registry: string) {\n // if we have no token for that registry, nothing to do\n const tok = await getToken(registry, this.identity)\n if (!tok) return\n\n const s = tok.replace(/^(Bearer|Basic) /i, '')\n\n const tokensUrl = new URL('-/npm/v1/tokens', registry)\n const record = await this.seek<{\n key: string\n token: string\n }>(tokensUrl, ({ token }) => s.startsWith(token), {\n useCache: false,\n }).catch(() => undefined)\n\n if (record) {\n const { key } = record\n await this.request(\n new URL(`-/npm/v1/tokens/token/${key}`, registry),\n { useCache: false, method: 'DELETE' },\n )\n }\n\n await deleteToken(registry, this.identity)\n }\n\n /**\n * Log into the registry specified\n *\n * Does not return the token or expose it, just saves to the auth keychain\n * and returns void if it worked. Otherwise, error is raised.\n */\n async login(registry: string) {\n // - make POST to '/-/v1/login'\n // - include a body of {} and npm-auth-type:web\n // - get a {doneUrl, loginUrl}\n // - open the loginUrl\n // - hang on the doneUrl until done\n //\n // if that fails: fall back to couchdb login\n const webLoginURL = new URL('-/v1/login', registry)\n const response = await this.request(webLoginURL, {\n method: 'POST',\n useCache: false,\n headers: {\n 'content-type': 'application/json',\n 'npm-auth-type': 'web',\n },\n body: '{}',\n })\n\n if (response.statusCode === 200) {\n const challenge = response.json()\n if (isWebAuthChallenge(challenge)) {\n const result = await this.webAuthOpener(challenge)\n await setToken(\n registry,\n `Bearer ${result.token}`,\n this.identity,\n )\n return\n }\n }\n /* c8 ignore start */\n // TODO: fall back to username/password login, and/or couchdb PUT login\n throw error('Failed to perform web login', { response })\n }\n /* c8 ignore stop */\n\n /**\n * Given a {@link WebAuthChallenge}, open the `loginUrl` in a browser and\n * hang on the `doneUrl` until it returns a {@link TokenResponse} object.\n */\n async webAuthOpener({ doneUrl, loginUrl }: WebAuthChallenge) {\n const ac = new AbortController()\n const { signal } = ac\n /* c8 ignore start - race condition */\n const [result] = await Promise.all([\n this.#checkLogin(doneUrl, { signal }).then(result => {\n ac.abort()\n return result\n }),\n urlOpen(loginUrl, { signal }).catch((er: unknown) => {\n if (asError(er).name === 'AbortError') return\n ac.abort()\n throw er\n }),\n ])\n /* c8 ignore stop */\n return result\n }\n\n async #checkLogin(\n url: URL | string,\n options: RegistryClientRequestOptions = {},\n ): Promise<TokenResponse> {\n const response = await this.request(url, {\n ...options,\n useCache: false,\n })\n const { signal } = options as { signal?: AbortSignal }\n if (response.statusCode === 202) {\n const rt = response.getHeader('retry-after')\n const retryAfter = rt ? Number(rt.toString()) : -1\n if (retryAfter > 0) {\n await setTimeout(retryAfter * 1000, null, { signal })\n }\n return await this.#checkLogin(url, options)\n }\n if (response.statusCode === 200) {\n const body = response.json()\n if (isTokenResponse(body)) return body\n }\n throw error('Invalid response from web login endpoint', {\n response,\n })\n }\n\n async request(\n url: URL | string,\n options: RegistryClientRequestOptions = {},\n ): Promise<CacheEntry> {\n logRequest(url, 'start')\n\n const u = typeof url === 'string' ? new URL(url) : url\n const {\n method = 'GET',\n integrity,\n redirections = new Set(),\n signal,\n otp = (process.env.VLT_OTP ?? '').trim(),\n staleWhileRevalidate = true,\n } = options\n let { trustIntegrity } = options\n\n const m = isCacheableMethod(method) ? method : undefined\n const { useCache = !!m } = options\n\n ;(signal as AbortSignal | null)?.throwIfAborted()\n\n // first, try to get from the cache before making any request.\n const { origin } = u\n const key = `${method !== 'GET' ? method + ' ' : ''}${u}`\n const buffer =\n useCache ?\n await this.cache.fetch(key, { context: { integrity } })\n : undefined\n\n const entry = buffer ? CacheEntry.decode(buffer) : undefined\n if (entry?.valid) {\n return entry\n }\n\n if (staleWhileRevalidate && entry?.staleWhileRevalidate && m) {\n // revalidate while returning the stale entry\n register(this.cache.path(), m, url)\n return entry\n }\n\n // either no cache entry, or need to revalidate before use.\n setCacheHeaders(options, entry)\n\n redirections.add(String(url))\n\n Object.assign(options, {\n path: u.pathname.replace(/\\/+$/, '') + u.search,\n ...agentOptions,\n })\n\n options.origin = u.origin\n options.headers = addHeader(\n addHeader(\n options.headers,\n 'accept-encoding',\n 'gzip;q=1.0, identity;q=0.5',\n ),\n 'user-agent',\n userAgent,\n )\n if (otp) {\n options.headers = addHeader(options.headers, 'npm-otp', otp)\n }\n if (integrity) {\n options.headers = addHeader(\n options.headers,\n 'accept-integrity',\n integrity,\n )\n }\n options.method = options.method ?? 'GET'\n\n // will remove if we don't have a token.\n options.headers = addHeader(\n options.headers,\n 'authorization',\n await getToken(origin, this.identity),\n )\n\n const result = await this.#handleResponse(\n u,\n options,\n await this.agent.request(options as Dispatcher.RequestOptions),\n entry,\n )\n\n if (result.getHeader('integrity')) {\n trustIntegrity = true\n }\n\n if (result.isGzip && !trustIntegrity) {\n result.checkIntegrity({ url })\n }\n if (useCache) {\n this.cache.set(key, result.encode(), {\n integrity: result.integrity,\n })\n }\n return result\n }\n\n async #handleResponse(\n url: URL,\n options: RegistryClientRequestOptions,\n response: Dispatcher.ResponseData,\n entry?: CacheEntry,\n ): Promise<CacheEntry> {\n if (handle304Response(response, entry)) return entry\n\n if (response.statusCode === 401) {\n const repeatRequest = await otplease(this, options, response)\n if (repeatRequest) return await this.request(url, repeatRequest)\n }\n\n const h: Buffer[] = []\n for (const [key, value] of Object.entries(response.headers)) {\n /* c8 ignore start - theoretical */\n if (Array.isArray(value)) {\n h.push(Buffer.from(key), Buffer.from(value.join(', ')))\n /* c8 ignore stop */\n } else if (typeof value === 'string') {\n h.push(Buffer.from(key), Buffer.from(value))\n }\n }\n\n const { integrity, trustIntegrity } = options\n const result = new CacheEntry(\n /* c8 ignore next - should always have a status code */\n response.statusCode || 200,\n h,\n {\n integrity,\n trustIntegrity,\n 'stale-while-revalidate-factor':\n this.staleWhileRevalidateFactor,\n },\n )\n\n if (isRedirect(result)) {\n response.body.resume()\n const [nextURL, nextOptions] = redirect(options, result, url)\n if (nextOptions && nextURL) {\n return await this.request(nextURL, nextOptions)\n }\n return result\n }\n\n response.body.on('data', (chunk: Buffer) => result.addBody(chunk))\n return await new Promise<CacheEntry>((res, rej) => {\n response.body.on('error', rej)\n response.body.on('end', () => res(result))\n })\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Cache } from '@vltpkg/cache'\nimport { register as cacheUnzipRegister } from '@vltpkg/cache-unzip'\nimport { error } from '@vltpkg/error-cause'\nimport { asError } from '@vltpkg/types'\nimport { logRequest } from '@vltpkg/output'\nimport type { Integrity } from '@vltpkg/types'\nimport { urlOpen } from '@vltpkg/url-open'\nimport { XDG } from '@vltpkg/xdg'\nimport { dirname, resolve } from 'node:path'\nimport { setTimeout } from 'node:timers/promises'\nimport { loadPackageJson } from 'package-json-from-dist'\nimport type { Dispatcher } from 'undici'\nimport { Agent, RetryAgent } from 'undici'\nimport { addHeader } from './add-header.ts'\nimport type { Token } from './auth.ts'\nimport {\n deleteToken,\n getKC,\n getToken,\n isToken,\n keychains,\n setToken,\n} from './auth.ts'\nimport type { JSONObj } from './cache-entry.ts'\nimport { CacheEntry } from './cache-entry.ts'\nimport { register } from './cache-revalidate.ts'\nimport { bun, deno, node } from './env.ts'\nimport { handle304Response } from './handle-304-response.ts'\nimport { otplease } from './otplease.ts'\nimport { isRedirect, redirect } from './redirect.ts'\nimport { setCacheHeaders } from './set-cache-headers.ts'\nimport type { TokenResponse } from './token-response.ts'\nimport { getTokenResponse } from './token-response.ts'\nimport type { WebAuthChallenge } from './web-auth-challenge.ts'\nimport { getWebAuthChallenge } from './web-auth-challenge.ts'\nimport { getEncondedValue } from './string-encoding.ts'\nexport {\n CacheEntry,\n deleteToken,\n getKC,\n isToken,\n keychains,\n setToken,\n type JSONObj,\n type Token,\n type TokenResponse,\n type WebAuthChallenge,\n}\n\nexport type CacheableMethod = 'GET' | 'HEAD'\nexport const isCacheableMethod = (m: unknown): m is CacheableMethod =>\n m === 'GET' || m === 'HEAD'\n\nexport type RegistryClientOptions = {\n /**\n * Path on disk where the cache should be stored\n *\n * Defaults to the XDG cache folder for `vlt/registry-client`\n */\n cache?: string\n /**\n * Number of retries to perform when encountering network errors or\n * likely-transient errors from git hosts.\n */\n 'fetch-retries'?: number\n /** The exponential backoff factor to use when retrying git hosts */\n 'fetch-retry-factor'?: number\n /** Number of milliseconds before starting first retry */\n 'fetch-retry-mintimeout'?: number\n /** Maximum number of milliseconds between two retries */\n 'fetch-retry-maxtimeout'?: number\n\n /** the identity to use for storing auth tokens */\n identity?: string\n\n /**\n * If the server does not serve a `stale-while-revalidate` value in the\n * `cache-control` header, then this multiplier is applied to the `max-age`\n * or `s-maxage` values.\n *\n * By default, this is `60`, so for example a response that is cacheable for\n * 5 minutes will allow a stale response while revalidating for up to 5\n * hours.\n *\n * If the server *does* provide a `stale-while-revalidate` value, then that\n * is always used.\n *\n * Set to 0 to prevent any `stale-while-revalidate` behavior unless\n * explicitly allowed by the server's `cache-control` header.\n */\n 'stale-while-revalidate-factor'?: number\n}\n\nexport type RegistryClientRequestOptions = Omit<\n Dispatcher.RequestOptions,\n 'method' | 'path'\n> & {\n /**\n * `path` should not be set when using the RegistryClient.\n * It will be overwritten with the path on the URL being requested.\n * This only here for compliance with the DispatchOptions base type.\n * @deprecated\n */\n path?: string\n\n /**\n * Method is optional, defaults to 'GET'\n */\n method?: Dispatcher.DispatchOptions['method']\n /**\n * Provide an SRI string to verify integrity of the item being fetched.\n *\n * This is only relevant when it must make a request to the registry. Once in\n * the local disk cache, items are assumed to be trustworthy.\n */\n integrity?: Integrity\n\n /**\n * Set to true if the integrity should be trusted implicitly without\n * a recalculation, for example if it comes from a trusted registry that\n * also serves the tarball itself.\n */\n trustIntegrity?: boolean\n\n /**\n * Follow up to 10 redirections by default. Set this to 0 to just return\n * the 3xx response. If the max redirections are expired, and we still get\n * a redirection response, then fail the request. Redirection cycles are\n * always treated as an error.\n */\n maxRedirections?: number\n\n /**\n * the number of redirections that have already been seen. This is used\n * internally, and should always start at 0.\n * @internal\n */\n redirections?: Set<string>\n\n /**\n * Set to `false` to suppress ANY lookups from cache. This will also\n * prevent storing the result to the cache.\n */\n useCache?: false\n\n /**\n * Set to pass an `npm-otp` header on the request.\n *\n * This should not be set except by the RegistryClient itself, when\n * we receive a 401 response with an OTP challenge.\n * @internal\n */\n otp?: string\n\n /**\n * Set to false to explicitly prevent `stale-while-revalidate` behavior,\n * for use in revalidating while stale.\n * @internal\n */\n staleWhileRevalidate?: false\n}\n\nconst { version } = loadPackageJson(\n import.meta.filename,\n process.env.__VLT_INTERNAL_REGISTRY_CLIENT_PACKAGE_JSON,\n) as {\n version: string\n}\n\nconst nua =\n (globalThis.navigator as Navigator | undefined)?.userAgent ??\n (bun ? `Bun/${bun}`\n : deno ? `Deno/${deno}`\n : node ? `Node.js/${node}`\n : '(unknown platform)')\n\nexport const userAgent = `@vltpkg/registry-client/${version} ${nua}`\n\nconst agentOptions: Agent.Options = {\n bodyTimeout: 600_000,\n headersTimeout: 600_000,\n keepAliveMaxTimeout: 1_200_000,\n keepAliveTimeout: 600_000,\n keepAliveTimeoutThreshold: 30_000,\n connect: {\n timeout: 600_000,\n keepAlive: true,\n keepAliveInitialDelay: 30_000,\n sessionTimeout: 600,\n },\n connections: 128,\n pipelining: 10,\n}\n\nconst xdg = new XDG('vlt')\n\nexport class RegistryClient {\n agent: RetryAgent\n cache: Cache\n identity: string\n staleWhileRevalidateFactor: number\n\n constructor(options: RegistryClientOptions) {\n const {\n cache = xdg.cache(),\n 'fetch-retry-factor': timeoutFactor = 2,\n 'fetch-retry-mintimeout': minTimeout = 0,\n 'fetch-retry-maxtimeout': maxTimeout = 30_000,\n 'fetch-retries': maxRetries = 3,\n identity = '',\n 'stale-while-revalidate-factor':\n staleWhileRevalidateFactor = 576, // 48h for a 5min cache\n } = options\n this.identity = identity\n this.staleWhileRevalidateFactor = staleWhileRevalidateFactor\n const path = resolve(cache, 'registry-client')\n this.cache = new Cache({\n path,\n onDiskWrite(_path, key, data) {\n if (CacheEntry.isGzipEntry(data)) {\n cacheUnzipRegister(path, key)\n }\n },\n })\n const dispatch = new Agent(agentOptions)\n this.agent = new RetryAgent(dispatch, {\n maxRetries,\n timeoutFactor,\n minTimeout,\n maxTimeout,\n retryAfter: true,\n errorCodes: [\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'EHOSTDOWN',\n 'ENETDOWN',\n 'ENETUNREACH',\n 'ENOTFOUND',\n 'EPIPE',\n 'UND_ERR_SOCKET',\n ],\n })\n }\n\n /**\n * Fetch the entire set of a paginated list of objects\n */\n async scroll<T>(\n url: URL | string,\n options: RegistryClientRequestOptions = {},\n seek?: (obj: T) => boolean,\n ): Promise<T[]> {\n const resp = await this.request(url, options)\n const { objects, urls } = resp.json() as {\n objects: T[]\n urls: { next?: string }\n }\n // if we have more, and haven't found our target, fetch more\n return urls.next && !(seek && objects.some(seek)) ?\n objects.concat(await this.scroll<T>(urls.next, options, seek))\n : objects\n }\n\n /**\n * find a given item in a paginated set\n */\n async seek<T>(\n url: URL | string,\n seek: (obj: T) => boolean,\n options: RegistryClientRequestOptions = {},\n ): Promise<T | undefined> {\n return (await this.scroll(url, options, seek)).find(seek)\n }\n\n /**\n * Log out from the registry specified, attempting to destroy the\n * token if the registry supports that endpoint.\n */\n async logout(registry: string) {\n // if we have no token for that registry, nothing to do\n const tok = await getToken(registry, this.identity)\n if (!tok) return\n\n const s = tok.replace(/^(Bearer|Basic) /i, '')\n\n const tokensUrl = new URL('-/npm/v1/tokens', registry)\n const record = await this.seek<{\n key: string\n token: string\n }>(tokensUrl, ({ token }) => s.startsWith(token), {\n useCache: false,\n }).catch(() => undefined)\n\n if (record) {\n const { key } = record\n await this.request(\n new URL(`-/npm/v1/tokens/token/${key}`, registry),\n { useCache: false, method: 'DELETE' },\n )\n }\n\n await deleteToken(registry, this.identity)\n }\n\n /**\n * Log into the registry specified\n *\n * Does not return the token or expose it, just saves to the auth keychain\n * and returns void if it worked. Otherwise, error is raised.\n */\n async login(registry: string) {\n // - make POST to '/-/v1/login'\n // - include a body of {} and npm-auth-type:web\n // - get a {doneUrl, authUrl}\n // - open the authUrl\n // - hang on the doneUrl until done\n //\n // if that fails: fall back to couchdb login\n const webLoginURL = new URL('-/v1/login', registry)\n const response = await this.request(webLoginURL, {\n method: 'POST',\n useCache: false,\n headers: {\n 'content-type': 'application/json',\n 'npm-auth-type': 'web',\n },\n body: '{}',\n })\n\n if (response.statusCode === 200) {\n const challenge = getWebAuthChallenge(response.json())\n if (challenge) {\n const result = await this.webAuthOpener(challenge)\n await setToken(\n registry,\n `Bearer ${result.token}`,\n this.identity,\n )\n return\n }\n }\n /* c8 ignore start */\n // TODO: fall back to username/password login, and/or couchdb PUT login\n throw error('Failed to perform web login', { response })\n }\n /* c8 ignore stop */\n\n /**\n * Given a {@link WebAuthChallenge}, open the `authUrl` in a browser and\n * hang on the `doneUrl` until it returns a {@link TokenResponse} object.\n */\n async webAuthOpener({ doneUrl, authUrl }: WebAuthChallenge) {\n const ac = new AbortController()\n const { signal } = ac\n /* c8 ignore start - race condition */\n const [result] = await Promise.all([\n this.#checkLogin(doneUrl, { signal }).then(result => {\n ac.abort()\n return result\n }),\n urlOpen(authUrl, { signal }).catch((er: unknown) => {\n if (asError(er).name === 'AbortError') return\n ac.abort()\n throw er\n }),\n ])\n /* c8 ignore stop */\n return result\n }\n\n async #checkLogin(\n url: URL | string,\n options: RegistryClientRequestOptions = {},\n ): Promise<TokenResponse> {\n const response = await this.request(url, {\n ...options,\n useCache: false,\n })\n const { signal } = options as { signal?: AbortSignal }\n if (response.statusCode === 202) {\n const rt = response.getHeaderString('retry-after')\n const retryAfter = rt ? Number(rt) : -1\n if (retryAfter > 0) {\n await setTimeout(retryAfter * 1000, null, { signal })\n }\n return await this.#checkLogin(url, options)\n }\n if (response.statusCode === 200) {\n const token = getTokenResponse(response.json())\n if (token) return token\n }\n throw error('Invalid response from web login endpoint', {\n response,\n })\n }\n\n async request(\n url: URL | string,\n options: RegistryClientRequestOptions = {},\n ): Promise<CacheEntry> {\n const u = typeof url === 'string' ? new URL(url) : url\n const {\n method = 'GET',\n integrity,\n redirections = new Set(),\n signal,\n otp = (process.env.VLT_OTP ?? '').trim(),\n staleWhileRevalidate = true,\n } = options\n let { trustIntegrity } = options\n\n const m = isCacheableMethod(method) ? method : undefined\n const { useCache = !!m } = options\n\n ;(signal as AbortSignal | null)?.throwIfAborted()\n\n // first, try to get from the cache before making any request.\n const { origin } = u\n const key = `${method !== 'GET' ? method + ' ' : ''}${u}`\n const buffer =\n useCache ?\n await this.cache.fetch(key, { context: { integrity } })\n : undefined\n\n const entry = buffer ? CacheEntry.decode(buffer) : undefined\n if (entry?.valid) {\n logRequest(url, 'cache')\n return entry\n }\n\n if (staleWhileRevalidate && entry?.staleWhileRevalidate && m) {\n // revalidate while returning the stale entry\n register(dirname(this.cache.path()), m, url)\n logRequest(url, 'stale')\n return entry\n }\n\n logRequest(url, 'start')\n\n // either no cache entry, or need to revalidate before use.\n setCacheHeaders(options, entry)\n\n redirections.add(String(url))\n\n Object.assign(options, {\n path: u.pathname.replace(/\\/+$/, '') + u.search,\n ...agentOptions,\n })\n\n options.origin = u.origin\n options.headers = addHeader(\n addHeader(\n options.headers,\n 'accept-encoding',\n 'gzip;q=1.0, identity;q=0.5',\n ),\n 'user-agent',\n userAgent,\n )\n if (otp) {\n options.headers = addHeader(options.headers, 'npm-otp', otp)\n }\n if (integrity) {\n options.headers = addHeader(\n options.headers,\n 'accept-integrity',\n integrity,\n )\n }\n options.method = options.method ?? 'GET'\n\n // will remove if we don't have a token.\n options.headers = addHeader(\n options.headers,\n 'authorization',\n await getToken(origin, this.identity),\n )\n\n let response: Dispatcher.ResponseData | null = null\n try {\n response = await this.agent.request(\n options as Dispatcher.RequestOptions,\n )\n /* c8 ignore start */\n } catch (er) {\n // Rethrow so we get a better stack trace\n throw error('Request failed', {\n code: 'EREQUEST',\n cause: er,\n url,\n method,\n })\n }\n /* c8 ignore stop */\n\n const result = await this.#handleResponse(\n u,\n options,\n response,\n entry,\n )\n\n if (result.getHeader('integrity')) {\n trustIntegrity = true\n }\n\n if (result.isGzip && !trustIntegrity) {\n result.checkIntegrity({ url })\n }\n if (useCache) {\n // Get the encoded buffer from the cache entry\n const buffer = result.encode()\n this.cache.set(\n key,\n Buffer.from(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n ),\n {\n integrity: result.integrity,\n },\n )\n }\n return result\n }\n\n async #handleResponse(\n url: URL,\n options: RegistryClientRequestOptions,\n response: Dispatcher.ResponseData,\n entry?: CacheEntry,\n ): Promise<CacheEntry> {\n if (handle304Response(response, entry)) return entry\n\n if (response.statusCode === 401) {\n const repeatRequest = await otplease(this, options, response)\n if (repeatRequest) return await this.request(url, repeatRequest)\n }\n\n const h: Uint8Array[] = []\n for (const [key, value] of Object.entries(response.headers)) {\n /* c8 ignore start - theoretical */\n if (Array.isArray(value)) {\n h.push(\n getEncondedValue(key),\n getEncondedValue(value.join(', ')),\n )\n /* c8 ignore stop */\n } else if (typeof value === 'string') {\n h.push(getEncondedValue(key), getEncondedValue(value))\n }\n }\n\n const { integrity, trustIntegrity } = options\n const result = new CacheEntry(\n /* c8 ignore next - should always have a status code */\n response.statusCode || 200,\n h,\n {\n integrity,\n trustIntegrity,\n 'stale-while-revalidate-factor':\n this.staleWhileRevalidateFactor,\n contentLength:\n response.headers['content-length'] ?\n Number(response.headers['content-length'])\n : /* c8 ignore next */ undefined,\n },\n )\n\n if (isRedirect(result)) {\n response.body.resume()\n const [nextURL, nextOptions] = redirect(options, result, url)\n if (nextOptions && nextURL) {\n return await this.request(nextURL, nextOptions)\n }\n return result\n }\n\n response.body.on('data', (chunk: Uint8Array) =>\n result.addBody(chunk),\n )\n return await new Promise<CacheEntry>((res, rej) => {\n response.body.on('error', rej)\n response.body.on('end', () => res(result))\n })\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"otplease.d.ts","sourceRoot":"","sources":["../../src/otplease.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EACV,cAAc,EACd,4BAA4B,EAC7B,MAAM,YAAY,CAAA;AASnB,eAAO,MAAM,QAAQ,WACX,cAAc,WACb,4BAA4B,YAC3B,UAAU,CAAC,YAAY,KAChC,OAAO,CAAC,4BAA4B,GAAG,SAAS,CAuDlD,CAAA"}
1
+ {"version":3,"file":"otplease.d.ts","sourceRoot":"","sources":["../../src/otplease.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EACV,cAAc,EACd,4BAA4B,EAC7B,MAAM,YAAY,CAAA;AAqBnB,eAAO,MAAM,QAAQ,WACX,cAAc,WACb,4BAA4B,YAC3B,UAAU,CAAC,YAAY,KAChC,OAAO,CAAC,4BAA4B,GAAG,SAAS,CAuDlD,CAAA"}
@@ -1,7 +1,18 @@
1
1
  import { error } from '@vltpkg/error-cause';
2
- import { isWebAuthChallenge } from "./web-auth-challenge.js";
2
+ import { getWebAuthChallenge } from "./web-auth-challenge.js";
3
3
  import { urlOpen } from '@vltpkg/url-open';
4
4
  import { createInterface } from 'node:readline/promises';
5
+ // eslint-disable-next-line no-console
6
+ const log = (msg) => console.error(msg);
7
+ const question = async (text) => {
8
+ const rl = createInterface({
9
+ input: process.stdin,
10
+ output: process.stdout,
11
+ });
12
+ const answer = await rl.question(text);
13
+ rl.close();
14
+ return answer;
15
+ };
5
16
  const otpChallengeNotice = /^Open ([^ ]+) to use your security key for authentication or enter OTP from your authenticator app/i;
6
17
  export const otplease = async (client, options, response) => {
7
18
  const waHeader = String(response.headers['www-authenticate'] ?? '');
@@ -13,43 +24,40 @@ export const otplease = async (client, options, response) => {
13
24
  }
14
25
  if (wwwAuth.has('otp')) {
15
26
  // do a web auth opener to get otp token
16
- const challenge = await response.body.json();
17
- if (isWebAuthChallenge(challenge)) {
27
+ const challenge = getWebAuthChallenge(await response.body.json().catch(() => null));
28
+ if (challenge) {
18
29
  return {
19
30
  ...options,
20
31
  otp: (await client.webAuthOpener(challenge)).token,
21
32
  };
22
33
  }
23
- else {
24
- const { 'npm-notice': npmNotice } = response.headers;
25
- if (npmNotice) {
26
- const n = String(npmNotice);
27
- const match = otpChallengeNotice.exec(n);
28
- if (match) {
29
- void urlOpen(match[1]);
30
- const otp = await createInterface({
31
- input: process.stdin,
32
- output: process.stdout,
33
- }).question(n);
34
- return { ...options, otp };
35
- }
34
+ const { 'npm-notice': npmNotice } = response.headers;
35
+ if (npmNotice) {
36
+ const notice = String(npmNotice);
37
+ const match = otpChallengeNotice.exec(notice);
38
+ if (match?.[1]) {
39
+ await urlOpen(match[1]);
40
+ log(notice);
41
+ return {
42
+ ...options,
43
+ otp: await question('OTP: '),
44
+ };
36
45
  }
37
- throw error('Unrecognized OTP authentication challenge', {
38
- response,
39
- });
40
46
  }
47
+ throw error('Unrecognized OTP authentication challenge', {
48
+ response,
49
+ });
41
50
  }
42
51
  if (wwwAuth.size) {
43
52
  throw error('Unknown authentication challenge', { response });
44
53
  }
45
54
  // see if the body is prompting for otp
46
- const text = await response.body.text();
55
+ const text = await response.body.text().catch(() => '');
47
56
  if (text.toLowerCase().includes('one-time pass')) {
48
- const otp = await createInterface({
49
- input: process.stdin,
50
- output: process.stdout,
51
- }).question(text);
52
- return { ...options, otp };
57
+ return {
58
+ ...options,
59
+ otp: await question(text),
60
+ };
53
61
  }
54
62
  };
55
63
  //# sourceMappingURL=otplease.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"otplease.js","sourceRoot":"","sources":["../../src/otplease.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAM3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,MAAM,kBAAkB,GACtB,qGAAqG,CAAA;AAEvG,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAC3B,MAAsB,EACtB,OAAqC,EACrC,QAAiC,EACkB,EAAE;IACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAA;IACnE,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CACrD,CAAA;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC,mDAAmD,EAAE;YAC/D,QAAQ;SACT,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,wCAAwC;QACxC,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QAC5C,IAAI,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAC;YAClC,OAAO;gBACL,GAAG,OAAO;gBACV,GAAG,EAAE,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;aACnD,CAAA;QACH,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAA;YACpD,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;gBAC3B,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAEnB,CAAA;gBACpB,IAAI,KAAK,EAAE,CAAC;oBACV,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;oBACtB,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC;wBAChC,KAAK,EAAE,OAAO,CAAC,KAAK;wBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;qBACvB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;oBACd,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAA;gBAC5B,CAAC;YACH,CAAC;YACD,MAAM,KAAK,CAAC,2CAA2C,EAAE;gBACvD,QAAQ;aACT,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,KAAK,CAAC,kCAAkC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC/D,CAAC;IAED,uCAAuC;IACvC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;IACvC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACjD,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC;YAChC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QACjB,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,CAAA;IAC5B,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { Dispatcher } from 'undici'\nimport type {\n RegistryClient,\n RegistryClientRequestOptions,\n} from './index.ts'\nimport { isWebAuthChallenge } from './web-auth-challenge.ts'\n\nimport { urlOpen } from '@vltpkg/url-open'\nimport { createInterface } from 'node:readline/promises'\n\nconst otpChallengeNotice =\n /^Open ([^ ]+) to use your security key for authentication or enter OTP from your authenticator app/i\n\nexport const otplease = async (\n client: RegistryClient,\n options: RegistryClientRequestOptions,\n response: Dispatcher.ResponseData,\n): Promise<RegistryClientRequestOptions | undefined> => {\n const waHeader = String(response.headers['www-authenticate'] ?? '')\n const wwwAuth = new Set(\n waHeader ? waHeader.toLowerCase().split(/,\\s*/) : [],\n )\n\n if (wwwAuth.has('ipaddress')) {\n throw error('Authorization is not allowed from your ip address', {\n response,\n })\n }\n\n if (wwwAuth.has('otp')) {\n // do a web auth opener to get otp token\n const challenge = await response.body.json()\n if (isWebAuthChallenge(challenge)) {\n return {\n ...options,\n otp: (await client.webAuthOpener(challenge)).token,\n }\n } else {\n const { 'npm-notice': npmNotice } = response.headers\n if (npmNotice) {\n const n = String(npmNotice)\n const match = otpChallengeNotice.exec(n) as\n | null\n | [string, string]\n if (match) {\n void urlOpen(match[1])\n const otp = await createInterface({\n input: process.stdin,\n output: process.stdout,\n }).question(n)\n return { ...options, otp }\n }\n }\n throw error('Unrecognized OTP authentication challenge', {\n response,\n })\n }\n }\n\n if (wwwAuth.size) {\n throw error('Unknown authentication challenge', { response })\n }\n\n // see if the body is prompting for otp\n const text = await response.body.text()\n if (text.toLowerCase().includes('one-time pass')) {\n const otp = await createInterface({\n input: process.stdin,\n output: process.stdout,\n }).question(text)\n return { ...options, otp }\n }\n}\n"]}
1
+ {"version":3,"file":"otplease.js","sourceRoot":"","sources":["../../src/otplease.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport type { Dispatcher } from 'undici'\nimport type {\n RegistryClient,\n RegistryClientRequestOptions,\n} from './index.ts'\nimport { getWebAuthChallenge } from './web-auth-challenge.ts'\nimport { urlOpen } from '@vltpkg/url-open'\nimport { createInterface } from 'node:readline/promises'\n\n// eslint-disable-next-line no-console\nconst log = (msg: string) => console.error(msg)\n\nconst question = async (text: string): Promise<string> => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n })\n const answer = await rl.question(text)\n rl.close()\n return answer\n}\n\nconst otpChallengeNotice =\n /^Open ([^ ]+) to use your security key for authentication or enter OTP from your authenticator app/i\n\nexport const otplease = async (\n client: RegistryClient,\n options: RegistryClientRequestOptions,\n response: Dispatcher.ResponseData,\n): Promise<RegistryClientRequestOptions | undefined> => {\n const waHeader = String(response.headers['www-authenticate'] ?? '')\n const wwwAuth = new Set(\n waHeader ? waHeader.toLowerCase().split(/,\\s*/) : [],\n )\n\n if (wwwAuth.has('ipaddress')) {\n throw error('Authorization is not allowed from your ip address', {\n response,\n })\n }\n\n if (wwwAuth.has('otp')) {\n // do a web auth opener to get otp token\n const challenge = getWebAuthChallenge(\n await response.body.json().catch(() => null),\n )\n if (challenge) {\n return {\n ...options,\n otp: (await client.webAuthOpener(challenge)).token,\n }\n }\n\n const { 'npm-notice': npmNotice } = response.headers\n if (npmNotice) {\n const notice = String(npmNotice)\n const match = otpChallengeNotice.exec(notice)\n if (match?.[1]) {\n await urlOpen(match[1])\n log(notice)\n return {\n ...options,\n otp: await question('OTP: '),\n }\n }\n }\n\n throw error('Unrecognized OTP authentication challenge', {\n response,\n })\n }\n\n if (wwwAuth.size) {\n throw error('Unknown authentication challenge', { response })\n }\n\n // see if the body is prompting for otp\n const text = await response.body.text().catch(() => '')\n if (text.toLowerCase().includes('one-time pass')) {\n return {\n ...options,\n otp: await question(text),\n }\n }\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Give it a key, and it'll return the buffer of that header value
2
+ * Give it a key, and it'll return the value of that header as a Uint8Array
3
3
  */
4
- export declare const getRawHeader: (headers: Buffer[], k: string) => Buffer<ArrayBufferLike> | undefined;
4
+ export declare const getRawHeader: (headers: Uint8Array[], key: string) => Uint8Array | undefined;
5
5
  /**
6
6
  * Give it a key and value, and it'll overwrite or add the header entry
7
7
  */
8
- export declare const setRawHeader: (headers: Buffer[], k: string, v: Buffer | string) => Buffer[];
8
+ export declare const setRawHeader: (headers: Uint8Array[], key: string, value: Uint8Array | string) => Uint8Array[];
9
9
  //# sourceMappingURL=raw-header.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-header.d.ts","sourceRoot":"","sources":["../../src/raw-header.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,YAAY,YAAa,MAAM,EAAE,KAAK,MAAM,wCAYxD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,YACd,MAAM,EAAE,KACd,MAAM,KACN,MAAM,GAAG,MAAM,KACjB,MAAM,EAkBR,CAAA"}
1
+ {"version":3,"file":"raw-header.d.ts","sourceRoot":"","sources":["../../src/raw-header.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,eAAO,MAAM,YAAY,YACd,UAAU,EAAE,OAChB,MAAM,KACV,UAAU,GAAG,SAYf,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,YACd,UAAU,EAAE,OAChB,MAAM,SACJ,UAAU,GAAG,MAAM,KACzB,UAAU,EAmBZ,CAAA"}
@@ -1,13 +1,14 @@
1
+ import { getDecodedValue, getEncondedValue, } from "./string-encoding.js";
1
2
  /**
2
- * Give it a key, and it'll return the buffer of that header value
3
+ * Give it a key, and it'll return the value of that header as a Uint8Array
3
4
  */
4
- export const getRawHeader = (headers, k) => {
5
- k = k.toLowerCase();
5
+ export const getRawHeader = (headers, key) => {
6
+ const k = key.toLowerCase();
6
7
  for (let i = 0; i < headers.length; i += 2) {
7
8
  const name = headers[i];
8
9
  if (name &&
9
- name.length === k.length &&
10
- name.toString().toLowerCase() === k) {
10
+ name.length === key.length &&
11
+ getDecodedValue(name).toLowerCase() === k) {
11
12
  return headers[i + 1];
12
13
  }
13
14
  }
@@ -15,21 +16,21 @@ export const getRawHeader = (headers, k) => {
15
16
  /**
16
17
  * Give it a key and value, and it'll overwrite or add the header entry
17
18
  */
18
- export const setRawHeader = (headers, k, v) => {
19
- k = k.toLowerCase();
20
- const value = typeof v === 'string' ? Buffer.from(v) : v;
19
+ export const setRawHeader = (headers, key, value) => {
20
+ const k = key.toLowerCase();
21
+ const encVal = typeof value === 'string' ? getEncondedValue(value) : value;
21
22
  for (let i = 0; i < headers.length; i += 2) {
22
23
  const name = headers[i];
23
24
  if (name &&
24
25
  name.length === k.length &&
25
- name.toString().toLowerCase() === k) {
26
+ getDecodedValue(name).toLowerCase() === k) {
26
27
  return [
27
28
  ...headers.slice(0, i + 1),
28
- value,
29
+ encVal,
29
30
  ...headers.slice(i + 2),
30
31
  ];
31
32
  }
32
33
  }
33
- return [...headers, Buffer.from(k), value];
34
+ return [...headers, getEncondedValue(k), encVal];
34
35
  };
35
36
  //# sourceMappingURL=raw-header.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-header.js","sourceRoot":"","sources":["../../src/raw-header.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAiB,EAAE,CAAS,EAAE,EAAE;IAC3D,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACvB,IACE,IAAI;YACJ,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YACxB,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,EACnC,CAAC;YACD,OAAO,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAiB,EACjB,CAAS,EACT,CAAkB,EACR,EAAE;IACZ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;IACnB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACxD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACvB,IACE,IAAI;YACJ,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YACxB,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,EACnC,CAAC;YACD,OAAO;gBACL,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gBAC1B,KAAK;gBACL,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACxB,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AAC5C,CAAC,CAAA","sourcesContent":["/**\n * Give it a key, and it'll return the buffer of that header value\n */\nexport const getRawHeader = (headers: Buffer[], k: string) => {\n k = k.toLowerCase()\n for (let i = 0; i < headers.length; i += 2) {\n const name = headers[i]\n if (\n name &&\n name.length === k.length &&\n name.toString().toLowerCase() === k\n ) {\n return headers[i + 1]\n }\n }\n}\n\n/**\n * Give it a key and value, and it'll overwrite or add the header entry\n */\nexport const setRawHeader = (\n headers: Buffer[],\n k: string,\n v: Buffer | string,\n): Buffer[] => {\n k = k.toLowerCase()\n const value = typeof v === 'string' ? Buffer.from(v) : v\n for (let i = 0; i < headers.length; i += 2) {\n const name = headers[i]\n if (\n name &&\n name.length === k.length &&\n name.toString().toLowerCase() === k\n ) {\n return [\n ...headers.slice(0, i + 1),\n value,\n ...headers.slice(i + 2),\n ]\n }\n }\n return [...headers, Buffer.from(k), value]\n}\n"]}
1
+ {"version":3,"file":"raw-header.js","sourceRoot":"","sources":["../../src/raw-header.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,gBAAgB,GACjB,MAAM,sBAAsB,CAAA;AAE7B;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAqB,EACrB,GAAW,EACa,EAAE;IAC1B,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACvB,IACE,IAAI;YACJ,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM;YAC1B,eAAe,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,EACzC,CAAC;YACD,OAAO,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAqB,EACrB,GAAW,EACX,KAA0B,EACZ,EAAE;IAChB,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAA;IAC3B,MAAM,MAAM,GACV,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACvB,IACE,IAAI;YACJ,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YACxB,eAAe,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,EACzC,CAAC;YACD,OAAO;gBACL,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gBAC1B,MAAM;gBACN,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;aACxB,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AAClD,CAAC,CAAA","sourcesContent":["import {\n getDecodedValue,\n getEncondedValue,\n} from './string-encoding.ts'\n\n/**\n * Give it a key, and it'll return the value of that header as a Uint8Array\n */\nexport const getRawHeader = (\n headers: Uint8Array[],\n key: string,\n): Uint8Array | undefined => {\n const k = key.toLowerCase()\n for (let i = 0; i < headers.length; i += 2) {\n const name = headers[i]\n if (\n name &&\n name.length === key.length &&\n getDecodedValue(name).toLowerCase() === k\n ) {\n return headers[i + 1]\n }\n }\n}\n\n/**\n * Give it a key and value, and it'll overwrite or add the header entry\n */\nexport const setRawHeader = (\n headers: Uint8Array[],\n key: string,\n value: Uint8Array | string,\n): Uint8Array[] => {\n const k = key.toLowerCase()\n const encVal =\n typeof value === 'string' ? getEncondedValue(value) : value\n for (let i = 0; i < headers.length; i += 2) {\n const name = headers[i]\n if (\n name &&\n name.length === k.length &&\n getDecodedValue(name).toLowerCase() === k\n ) {\n return [\n ...headers.slice(0, i + 1),\n encVal,\n ...headers.slice(i + 2),\n ]\n }\n }\n return [...headers, getEncondedValue(k), encVal]\n}\n"]}
@@ -3,7 +3,7 @@ import type { RegistryClientRequestOptions } from './index.ts';
3
3
  export type RedirectStatus = 301 | 302 | 303 | 307 | 308;
4
4
  export type RedirectResponse = CacheEntry & {
5
5
  statusCode: RedirectStatus;
6
- getHeader(key: 'location'): Buffer;
6
+ getHeader(key: 'location'): Uint8Array | undefined;
7
7
  };
8
8
  export declare const isRedirect: (response: CacheEntry) => response is RedirectResponse;
9
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../../src/redirect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAA;AAE9D,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAIxD,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAC1C,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAAA;CACnC,CAAA;AAED,eAAO,MAAM,UAAU,aACX,UAAU,KACnB,QAAQ,IAAI,gBAE2B,CAAA;AAE1C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,YACV,4BAA4B,YAC3B,gBAAgB,QACpB,GAAG,KACR,EAAE,GAAG,CAAC,GAAG,EAAE,4BAA4B,CAyCzC,CAAA"}
1
+ {"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../../src/redirect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAA;AAE9D,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAIxD,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG;IAC1C,UAAU,EAAE,cAAc,CAAA;IAC1B,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAA;CACnD,CAAA;AAED,eAAO,MAAM,UAAU,aACX,UAAU,KACnB,QAAQ,IAAI,gBAE2B,CAAA;AAE1C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,YACV,4BAA4B,YAC3B,gBAAgB,QACpB,GAAG,KACR,EAAE,GAAG,CAAC,GAAG,EAAE,4BAA4B,CA6CzC,CAAA"}
@@ -27,7 +27,11 @@ export const redirect = (options, response, from) => {
27
27
  url: from,
28
28
  });
29
29
  }
30
- const location = String(response.getHeader('location'));
30
+ const location = response.getHeaderString('location');
31
+ /* c8 ignore start */
32
+ if (!location)
33
+ throw error('Location header missing from redirect response');
34
+ /* c8 ignore stop */
31
35
  const nextURL = new URL(location, from);
32
36
  if (redirections.has(String(nextURL))) {
33
37
  throw error('Redirection cycle detected', {
@@ -1 +1 @@
1
- {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../../src/redirect.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAM3C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAO3D,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,QAAoB,EACU,EAAE,CAChC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;IACzC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;AAE1C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,OAAqC,EACrC,QAA0B,EAC1B,IAAS,EACiC,EAAE;IAC5C,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,EAAU,EAAE,eAAe,GAAG,EAAE,EAAE,GAC9D,OAAO,CAAA;IACT,IAAI,eAAe,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,IAAI,YAAY,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,CAAC,+BAA+B,EAAE;YAC3C,GAAG,EAAE,eAAe;YACpB,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC;YACxB,GAAG,EAAE,IAAI;SACV,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAA;IACvD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACvC,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,KAAK,CAAC,4BAA4B,EAAE;YACxC,GAAG,EAAE,eAAe;YACpB,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC;YACxB,GAAG,EAAE,IAAI;SACV,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,WAAW,GAAiC;QAChD,GAAG,OAAO;QACV,YAAY;KACb,CAAA;IACD,4FAA4F;IAC5F,OAAO,WAAW,CAAC,IAAI,CAAA;IACvB,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;IACjC,QAAQ,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC5B,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,kCAAkC;YAClC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAA;YAC1B,WAAW,CAAC,IAAI,GAAG,SAAS,CAAA;YAC5B,cAAc;QAChB,CAAC;QACD,KAAK,GAAG,CAAC;QACT,KAAK,GAAG,CAAC,CAAC,mDAAmD;QAC7D,KAAK,GAAG,CAAC;QACT,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;AACH,CAAC,CAAA","sourcesContent":["// given a RegistryClientOptions object, and a redirection response,\n\nimport { error } from '@vltpkg/error-cause'\nimport type { CacheEntry } from './cache-entry.ts'\nimport type { RegistryClientRequestOptions } from './index.ts'\n\nexport type RedirectStatus = 301 | 302 | 303 | 307 | 308\n\nconst redirectStatuses = new Set([301, 302, 303, 307, 308])\n\nexport type RedirectResponse = CacheEntry & {\n statusCode: RedirectStatus\n getHeader(key: 'location'): Buffer\n}\n\nexport const isRedirect = (\n response: CacheEntry,\n): response is RedirectResponse =>\n redirectStatuses.has(response.statusCode) &&\n !!response.getHeader('location')?.length\n\n/**\n * If this response is allowed to follow the redirect (because max has not\n * been hit, and the new location has not been seen already), then return\n * the [url, options] to use for the subsequent request.\n *\n * Return [] if the response should be returned as-is.\n *\n * Throws an error if maxRedirections is hit or the redirections set already\n * contains the new location.\n *\n * Ensure that the response is in fact a redirection first, by calling\n * {@link isRedirect} on it.\n */\nexport const redirect = (\n options: RegistryClientRequestOptions,\n response: RedirectResponse,\n from: URL,\n): [] | [URL, RegistryClientRequestOptions] => {\n const { redirections = new Set<string>(), maxRedirections = 10 } =\n options\n if (maxRedirections <= 0) return []\n if (redirections.size >= maxRedirections) {\n throw error('Maximum redirections exceeded', {\n max: maxRedirections,\n found: [...redirections],\n url: from,\n })\n }\n const location = String(response.getHeader('location'))\n const nextURL = new URL(location, from)\n if (redirections.has(String(nextURL))) {\n throw error('Redirection cycle detected', {\n max: maxRedirections,\n found: [...redirections],\n url: from,\n })\n }\n const nextOptions: RegistryClientRequestOptions = {\n ...options,\n redirections,\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- thats why we are deleting it\n delete nextOptions.path\n redirections.add(String(nextURL))\n switch (response.statusCode) {\n case 303: {\n // drop body, change method to GET\n nextOptions.method = 'GET'\n nextOptions.body = undefined\n // fallthrough\n }\n case 301:\n case 302: // some user agents treat as 303, but they're wrong\n case 307:\n case 308: {\n return [nextURL, nextOptions]\n }\n }\n}\n"]}
1
+ {"version":3,"file":"redirect.js","sourceRoot":"","sources":["../../src/redirect.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAM3C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;AAO3D,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,QAAoB,EACU,EAAE,CAChC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;IACzC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;AAE1C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,OAAqC,EACrC,QAA0B,EAC1B,IAAS,EACiC,EAAE;IAC5C,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,EAAU,EAAE,eAAe,GAAG,EAAE,EAAE,GAC9D,OAAO,CAAA;IACT,IAAI,eAAe,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,IAAI,YAAY,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,CAAC,+BAA+B,EAAE;YAC3C,GAAG,EAAE,eAAe;YACpB,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC;YACxB,GAAG,EAAE,IAAI;SACV,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;IACrD,qBAAqB;IACrB,IAAI,CAAC,QAAQ;QACX,MAAM,KAAK,CAAC,gDAAgD,CAAC,CAAA;IAC/D,oBAAoB;IACpB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACvC,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,KAAK,CAAC,4BAA4B,EAAE;YACxC,GAAG,EAAE,eAAe;YACpB,KAAK,EAAE,CAAC,GAAG,YAAY,CAAC;YACxB,GAAG,EAAE,IAAI;SACV,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,WAAW,GAAiC;QAChD,GAAG,OAAO;QACV,YAAY;KACb,CAAA;IACD,4FAA4F;IAC5F,OAAO,WAAW,CAAC,IAAI,CAAA;IACvB,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;IACjC,QAAQ,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC5B,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,kCAAkC;YAClC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAA;YAC1B,WAAW,CAAC,IAAI,GAAG,SAAS,CAAA;YAC5B,cAAc;QAChB,CAAC;QACD,KAAK,GAAG,CAAC;QACT,KAAK,GAAG,CAAC,CAAC,mDAAmD;QAC7D,KAAK,GAAG,CAAC;QACT,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;AACH,CAAC,CAAA","sourcesContent":["// given a RegistryClientOptions object, and a redirection response,\n\nimport { error } from '@vltpkg/error-cause'\nimport type { CacheEntry } from './cache-entry.ts'\nimport type { RegistryClientRequestOptions } from './index.ts'\n\nexport type RedirectStatus = 301 | 302 | 303 | 307 | 308\n\nconst redirectStatuses = new Set([301, 302, 303, 307, 308])\n\nexport type RedirectResponse = CacheEntry & {\n statusCode: RedirectStatus\n getHeader(key: 'location'): Uint8Array | undefined\n}\n\nexport const isRedirect = (\n response: CacheEntry,\n): response is RedirectResponse =>\n redirectStatuses.has(response.statusCode) &&\n !!response.getHeader('location')?.length\n\n/**\n * If this response is allowed to follow the redirect (because max has not\n * been hit, and the new location has not been seen already), then return\n * the [url, options] to use for the subsequent request.\n *\n * Return [] if the response should be returned as-is.\n *\n * Throws an error if maxRedirections is hit or the redirections set already\n * contains the new location.\n *\n * Ensure that the response is in fact a redirection first, by calling\n * {@link isRedirect} on it.\n */\nexport const redirect = (\n options: RegistryClientRequestOptions,\n response: RedirectResponse,\n from: URL,\n): [] | [URL, RegistryClientRequestOptions] => {\n const { redirections = new Set<string>(), maxRedirections = 10 } =\n options\n if (maxRedirections <= 0) return []\n if (redirections.size >= maxRedirections) {\n throw error('Maximum redirections exceeded', {\n max: maxRedirections,\n found: [...redirections],\n url: from,\n })\n }\n const location = response.getHeaderString('location')\n /* c8 ignore start */\n if (!location)\n throw error('Location header missing from redirect response')\n /* c8 ignore stop */\n const nextURL = new URL(location, from)\n if (redirections.has(String(nextURL))) {\n throw error('Redirection cycle detected', {\n max: maxRedirections,\n found: [...redirections],\n url: from,\n })\n }\n const nextOptions: RegistryClientRequestOptions = {\n ...options,\n redirections,\n }\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- thats why we are deleting it\n delete nextOptions.path\n redirections.add(String(nextURL))\n switch (response.statusCode) {\n case 303: {\n // drop body, change method to GET\n nextOptions.method = 'GET'\n nextOptions.body = undefined\n // fallthrough\n }\n case 301:\n case 302: // some user agents treat as 303, but they're wrong\n case 307:\n case 308: {\n return [nextURL, nextOptions]\n }\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  export declare const __CODE_SPLIT_SCRIPT_NAME: string;
2
2
  export declare const main: (cache?: string, input?: NodeJS.ReadStream & {
3
3
  fd: 0;
4
- }) => Promise<void>;
4
+ }) => Promise<boolean>;
5
5
  //# sourceMappingURL=revalidate.d.ts.map