@pnpm/network.fetch 1100.1.4 → 1100.1.6

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.
@@ -1,129 +0,0 @@
1
- import { URL } from 'node:url';
2
- import { getDispatcher } from './dispatcher.js';
3
- import { fetch, isRedirect } from './fetch.js';
4
- const USER_AGENT = 'pnpm'; // or maybe make it `${pkg.name}/${pkg.version} (+https://npm.im/${pkg.name})`
5
- const FULL_DOC = 'application/json';
6
- const ACCEPT_FULL_DOC = `${FULL_DOC}; q=1.0, */*`;
7
- const ABBREVIATED_DOC = 'application/vnd.npm.install-v1+json';
8
- const ACCEPT_ABBREVIATED_DOC = `${ABBREVIATED_DOC}; q=1.0, ${FULL_DOC}; q=0.8, */*`;
9
- const MAX_FOLLOWED_REDIRECTS = 20;
10
- export function fetchWithDispatcher(url, opts) {
11
- const dispatcher = getDispatcher(url.toString(), {
12
- ...opts.dispatcherOptions,
13
- strictSsl: opts.dispatcherOptions.strictSsl ?? true,
14
- });
15
- return fetch(url, {
16
- ...opts,
17
- dispatcher,
18
- });
19
- }
20
- /**
21
- * Returns a {@link fetch} pre-bound to the given dispatcher options, so callers
22
- * that need a fetch function (rather than a one-shot call) can route their
23
- * requests through the configured proxy / TLS / local-address settings.
24
- */
25
- export function createDispatchedFetch(opts) {
26
- const dispatcherOptions = {
27
- ...opts,
28
- clientCertificates: opts.clientCertificates ?? extractTlsConfigs(opts.configByUri),
29
- };
30
- return (url, fetchOpts) => fetchWithDispatcher(url, { ...fetchOpts, dispatcherOptions });
31
- }
32
- export function createFetchFromRegistry(defaultOpts) {
33
- const clientCertificates = extractTlsConfigs(defaultOpts.configByUri);
34
- return async (url, opts) => {
35
- const headers = {
36
- 'user-agent': USER_AGENT,
37
- ...getHeaders({
38
- auth: opts?.authHeaderValue,
39
- fullMetadata: opts?.fullMetadata,
40
- method: opts?.method,
41
- userAgent: defaultOpts.userAgent,
42
- }),
43
- };
44
- if (opts?.ifNoneMatch) {
45
- headers['if-none-match'] = opts.ifNoneMatch;
46
- }
47
- if (opts?.ifModifiedSince) {
48
- headers['if-modified-since'] = opts.ifModifiedSince;
49
- }
50
- // Merge caller-provided headers (e.g. content-type, npm-otp) on top
51
- if (opts?.headers) {
52
- const optsHeaders = opts.headers instanceof Headers
53
- ? Object.fromEntries(opts.headers.entries())
54
- : Array.isArray(opts.headers)
55
- ? Object.fromEntries(opts.headers)
56
- : opts.headers;
57
- Object.assign(headers, optsHeaders);
58
- }
59
- let redirects = 0;
60
- let urlObject = new URL(url);
61
- const originalHost = urlObject.host;
62
- /* eslint-disable no-await-in-loop */
63
- while (true) {
64
- const dispatcherOptions = {
65
- ...defaultOpts,
66
- ...opts,
67
- strictSsl: defaultOpts.strictSsl ?? true,
68
- clientCertificates,
69
- };
70
- const response = await fetchWithDispatcher(urlObject, {
71
- dispatcherOptions,
72
- body: opts?.body,
73
- // if verifying integrity, native fetch must not decompress
74
- headers,
75
- method: opts?.method,
76
- redirect: 'manual',
77
- retry: opts?.retry,
78
- timeout: opts?.timeout ?? 60000,
79
- });
80
- if (!isRedirect(response.status) || redirects >= MAX_FOLLOWED_REDIRECTS) {
81
- return response;
82
- }
83
- redirects++;
84
- // This is a workaround to remove authorization headers on redirect.
85
- // Related pnpm issue: https://github.com/pnpm/pnpm/issues/1815
86
- urlObject = resolveRedirectUrl(response, urlObject);
87
- if (!headers['authorization'] || originalHost === urlObject.host)
88
- continue;
89
- delete headers.authorization;
90
- }
91
- /* eslint-enable no-await-in-loop */
92
- };
93
- }
94
- function getHeaders(opts) {
95
- const headers = {};
96
- // The abbreviated/full-metadata Accept header is meaningful only on package
97
- // metadata reads. Setting it on writes (PUT/POST/DELETE) breaks npmjs.org's
98
- // dist-tag endpoint, which rejects the request with a generic 400.
99
- if (!opts.method || opts.method === 'GET' || opts.method === 'HEAD') {
100
- headers.accept = opts.fullMetadata === true ? ACCEPT_FULL_DOC : ACCEPT_ABBREVIATED_DOC;
101
- }
102
- if (opts.auth) {
103
- headers['authorization'] = opts.auth;
104
- }
105
- if (opts.userAgent) {
106
- headers['user-agent'] = opts.userAgent;
107
- }
108
- return headers;
109
- }
110
- function extractTlsConfigs(configByUri) {
111
- if (!configByUri)
112
- return undefined;
113
- let result;
114
- for (const [uri, config] of Object.entries(configByUri)) {
115
- if (config.tls) {
116
- result ??= {};
117
- result[uri] = config.tls;
118
- }
119
- }
120
- return result;
121
- }
122
- function resolveRedirectUrl(response, currentUrl) {
123
- const location = response.headers.get('location');
124
- if (!location) {
125
- throw new Error(`Redirect location header missing for ${currentUrl.toString()}`);
126
- }
127
- return new URL(location, currentUrl);
128
- }
129
- //# sourceMappingURL=fetchFromRegistry.js.map
package/lib/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export { clearDispatcherCache, destroyDispatchers, getDispatcher } from './dispatcher.js';
2
- export { fetch, isRedirect, type RetryTimeoutOptions } from './fetch.js';
3
- export { createDispatchedFetch, type CreateDispatchedFetchOptions, createFetchFromRegistry, type CreateFetchFromRegistryOptions, type DispatcherOptions, fetchWithDispatcher } from './fetchFromRegistry.js';
4
- export type { FetchFromRegistry } from '@pnpm/fetching.types';