@pnpm/fetching.tarball-fetcher 1102.1.5 → 1102.1.7

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @pnpm/tarball-fetcher
2
2
 
3
+ ## 1102.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies:
8
+ - @pnpm/core-loggers@1101.0.2
9
+ - @pnpm/exec.prepare-package@1100.0.41
10
+ - @pnpm/fs.packlist@1100.0.7
11
+ - @pnpm/network.fetch@1100.1.21
12
+
13
+ ## 1102.1.6
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies:
18
+ - @pnpm/exec.prepare-package@1100.0.40
19
+ - @pnpm/network.fetch@1100.1.20
20
+ - @pnpm/store.index@1101.0.0
21
+
3
22
  ## 1102.1.5
4
23
 
5
24
  ### Patch Changes
@@ -45,6 +45,58 @@ export function createGitHostedTarballFetcher(fetchRemoteTarball, fetcherOpts) {
45
45
  });
46
46
  }
47
47
  async function prepareGitHostedPkg(filesMap, cafs, rawFilesIndexFile, filesIndexFile, opts, fetcherOpts, resolution) {
48
+ const { shouldBeBuilt, pkgDir, ignoredBuild } = await unpackAndPreparePackage(cafs, filesMap, opts, fetcherOpts, resolution);
49
+ filesIndexFile = resolveGitHostedIndexFile({
50
+ filesIndexFile,
51
+ ignoredBuild,
52
+ ignoreScripts: opts.ignoreScripts,
53
+ pkgResolutionId: fetcherOpts.pkgResolutionId ?? createGitHostedTarballPkgResolutionId(resolution),
54
+ shouldBeBuilt,
55
+ });
56
+ const files = await packlist(pkgDir);
57
+ const isUnchanged = !resolution.path && files.length === filesMap.size && (!shouldBeBuilt || ignoredBuild);
58
+ if (isUnchanged) {
59
+ return handleUnchangedGitPkg({
60
+ filesIndexFile,
61
+ filesMap,
62
+ ignoredBuild,
63
+ ignoreScripts: opts.ignoreScripts,
64
+ rawFilesIndexFile,
65
+ shouldBeBuilt,
66
+ storeIndex: opts.storeIndex,
67
+ });
68
+ }
69
+ return reindexAndAddGitPkgFiles({
70
+ cafs,
71
+ fetcherOpts,
72
+ files,
73
+ filesIndexFile,
74
+ ignoredBuild,
75
+ opts,
76
+ pkgDir,
77
+ rawFilesIndexFile,
78
+ shouldBeBuilt,
79
+ });
80
+ }
81
+ async function reindexAndAddGitPkgFiles(opts) {
82
+ opts.opts.storeIndex.delete(opts.rawFilesIndexFile);
83
+ return {
84
+ filesIndexFile: opts.filesIndexFile,
85
+ ...await addFilesFromDir({
86
+ storeDir: opts.cafs.storeDir,
87
+ storeIndex: opts.opts.storeIndex,
88
+ dir: opts.pkgDir,
89
+ files: opts.files,
90
+ filesIndexFile: opts.filesIndexFile,
91
+ pkg: opts.fetcherOpts.pkg,
92
+ readManifest: opts.fetcherOpts.readManifest,
93
+ requiresPrepare: opts.shouldBeBuilt,
94
+ }),
95
+ ignoredBuild: opts.ignoredBuild,
96
+ requiresPrepare: opts.shouldBeBuilt,
97
+ };
98
+ }
99
+ async function unpackAndPreparePackage(cafs, filesMap, opts, fetcherOpts, resolution) {
48
100
  const tempLocation = await cafs.tempDir();
49
101
  cafs.importPackage(tempLocation, {
50
102
  filesResponse: {
@@ -59,47 +111,30 @@ async function prepareGitHostedPkg(filesMap, cafs, rawFilesIndexFile, filesIndex
59
111
  allowBuild: fetcherOpts.allowBuild,
60
112
  pkgResolutionId: fetcherOpts.pkgResolutionId ?? createGitHostedTarballPkgResolutionId(resolution),
61
113
  }, tempLocation, resolution.path ?? '');
62
- if (shouldBeBuilt && ((ignoredBuild && !opts.ignoreScripts) || (!ignoredBuild && filesIndexFile.endsWith('\tnot-built')))) {
63
- filesIndexFile = gitHostedStoreIndexKey(fetcherOpts.pkgResolutionId ?? createGitHostedTarballPkgResolutionId(resolution), { built: !ignoredBuild });
114
+ return { shouldBeBuilt, pkgDir, ignoredBuild };
115
+ }
116
+ function resolveGitHostedIndexFile(opts) {
117
+ const shouldReindex = opts.shouldBeBuilt &&
118
+ ((opts.ignoredBuild && !opts.ignoreScripts) || (!opts.ignoredBuild && opts.filesIndexFile.endsWith('\tnot-built')));
119
+ if (shouldReindex) {
120
+ return gitHostedStoreIndexKey(opts.pkgResolutionId, { built: !opts.ignoredBuild });
64
121
  }
65
- const files = await packlist(pkgDir);
66
- const { storeIndex } = opts;
67
- if (!resolution.path && files.length === filesMap.size) {
68
- if (!shouldBeBuilt || ignoredBuild) {
69
- if (!ignoredBuild || !opts.ignoreScripts) {
70
- const data = storeIndex.get(rawFilesIndexFile);
71
- if (data) {
72
- data.requiresPrepare = shouldBeBuilt;
73
- storeIndex.set(filesIndexFile, data);
74
- }
75
- }
76
- storeIndex.delete(rawFilesIndexFile);
77
- return {
78
- filesIndexFile,
79
- filesMap,
80
- ignoredBuild,
81
- requiresPrepare: shouldBeBuilt,
82
- };
122
+ return opts.filesIndexFile;
123
+ }
124
+ function handleUnchangedGitPkg(opts) {
125
+ if (!opts.ignoredBuild || !opts.ignoreScripts) {
126
+ const data = opts.storeIndex.get(opts.rawFilesIndexFile);
127
+ if (data) {
128
+ data.requiresPrepare = opts.shouldBeBuilt;
129
+ opts.storeIndex.set(opts.filesIndexFile, data);
83
130
  }
84
131
  }
85
- storeIndex.delete(rawFilesIndexFile);
86
- // Important! We cannot remove the temp location at this stage.
87
- // Even though we have the index of the package,
88
- // the linking of files to the store is in progress.
132
+ opts.storeIndex.delete(opts.rawFilesIndexFile);
89
133
  return {
90
- filesIndexFile,
91
- ...await addFilesFromDir({
92
- storeDir: cafs.storeDir,
93
- storeIndex: opts.storeIndex,
94
- dir: pkgDir,
95
- files,
96
- filesIndexFile,
97
- pkg: fetcherOpts.pkg,
98
- readManifest: fetcherOpts.readManifest,
99
- requiresPrepare: shouldBeBuilt,
100
- }),
101
- ignoredBuild,
102
- requiresPrepare: shouldBeBuilt,
134
+ filesIndexFile: opts.filesIndexFile,
135
+ filesMap: opts.filesMap,
136
+ ignoredBuild: opts.ignoredBuild,
137
+ requiresPrepare: opts.shouldBeBuilt,
103
138
  };
104
139
  }
105
140
  function createGitHostedTarballPkgResolutionId(resolution) {
@@ -9,7 +9,7 @@ import throttle from 'lodash.throttle';
9
9
  import { BadTarballError } from './errorTypes/index.js';
10
10
  const BIG_TARBALL_SIZE = 1024 * 1024 * 5; // 5 MB
11
11
  export function createDownloader(fetchFromRegistry, gotOpts) {
12
- const retryOpts = {
12
+ const defaultRetryOpts = {
13
13
  factor: 10,
14
14
  maxTimeout: 6e4, // 1 minute
15
15
  minTimeout: 1e4, // 10 seconds
@@ -19,164 +19,212 @@ export function createDownloader(fetchFromRegistry, gotOpts) {
19
19
  const fetchMinSpeedKiBps = gotOpts.fetchMinSpeedKiBps ?? 50; // 50 KiB/s
20
20
  return async function download(url, opts) {
21
21
  const authHeaderValue = getSecureNodeMirrorAuthHeader(opts.getAuthHeaderByURI(url, { pkgName: opts.pkg?.name }), url, opts.appendManifest?.name);
22
- const downloadRetryOpts = { ...retryOpts, ...opts.retry };
22
+ const downloadRetryOpts = { ...defaultRetryOpts, ...opts.retry };
23
23
  const op = retry.operation(downloadRetryOpts);
24
24
  return new Promise((resolve, reject) => {
25
- op.attempt(async (attempt) => {
26
- try {
27
- resolve(await fetch(attempt));
28
- }
29
- catch (error) { // eslint-disable-line
30
- if ((opts.redirect === 'manual' && error.response?.status >= 300 && error.response.status < 400) ||
31
- error.response?.status === 401 ||
32
- error.response?.status === 403 ||
33
- error.response?.status === 404 ||
34
- error.code === 'ERR_PNPM_PREPARE_PKG_FAILURE' ||
35
- isNonRetryableError(error)) {
36
- reject(error);
37
- return;
38
- }
39
- const timeout = op.retry(error);
40
- if (timeout === false) {
41
- reject(op.mainError());
42
- return;
43
- }
44
- // Extract error properties into a plain object because Error properties
45
- // are non-enumerable and don't serialize well through the logging system
46
- const errorInfo = {
47
- name: error.name,
48
- message: error.message,
49
- code: error.code,
50
- errno: error.errno,
51
- // For HTTP errors from our ResponseError class
52
- status: error.status,
53
- statusCode: error.statusCode,
54
- // undici wraps the actual network error in a cause property
55
- cause: error.cause ? {
56
- code: error.cause.code,
57
- errno: error.cause.errno,
58
- } : undefined,
59
- };
60
- requestRetryLogger.debug({
61
- attempt,
62
- error: errorInfo,
63
- maxRetries: downloadRetryOpts.retries,
64
- method: 'GET',
65
- timeout,
66
- url: redactUrlForDisplay(url),
67
- });
68
- }
69
- });
70
- });
71
- async function fetch(currentAttempt) {
72
- let data;
73
- try {
74
- const res = await fetchFromRegistry(url, {
25
+ op.attempt((attempt) => {
26
+ void executeDownloadAttempt({
27
+ attempt,
75
28
  authHeaderValue,
76
- // Tarballs are already compressed; ask the server not to apply an additional
77
- // Content-Encoding so Content-Length matches the body we receive and we don't
78
- // waste CPU on round-trip re-compression. See https://github.com/pnpm/pnpm/issues/11506
79
- headers: { 'accept-encoding': 'identity' },
80
- // The fetch library can retry requests on bad HTTP responses.
81
- // However, it is not enough to retry on bad HTTP responses only.
82
- // Requests should also be retried when the tarball's integrity check fails.
83
- // Hence, we tell fetch to not retry,
84
- // and we perform the retries from this function instead.
85
- retry: { retries: 0 },
86
- redirect: opts.redirect,
87
- timeout: gotOpts.timeout,
88
- });
89
- if (res.status !== 200) {
90
- throw new FetchError({ url, authHeaderValue }, res);
91
- }
92
- // When Content-Encoding is present, Content-Length refers to the encoded form
93
- // of the data, not the decoded bytes that the fetch implementation yields.
94
- // See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Encoding
95
- const isEncoded = isContentEncoded(res.headers.get('content-encoding'));
96
- const contentLength = !isEncoded && res.headers.has('content-length') && res.headers.get('content-length');
97
- const parsedLength = typeof contentLength === 'string' ? parseInt(contentLength, 10) : NaN;
98
- const size = Number.isFinite(parsedLength) && parsedLength >= 0 ? parsedLength : null;
99
- if (opts.onStart != null) {
100
- opts.onStart(size, currentAttempt);
101
- }
102
- // In order to reduce the amount of logs, we only report the download progress of big tarballs
103
- const onProgress = (size != null && size >= BIG_TARBALL_SIZE && opts.onProgress)
104
- ? throttle(opts.onProgress, 500)
105
- : undefined;
106
- const startTime = Date.now();
107
- let downloaded = 0;
108
- if (size !== null) {
109
- // Known size: pre-allocate and copy directly (avoids intermediate array + second copy pass)
110
- data = Buffer.from(new SharedArrayBuffer(size));
111
- for await (const chunk of res.body) {
112
- const c = chunk;
113
- const nextDownloaded = downloaded + c.byteLength;
114
- if (nextDownloaded > size) {
115
- throw new BadTarballError({
116
- expectedSize: size,
117
- receivedSize: nextDownloaded,
118
- tarballUrl: url,
119
- });
120
- }
121
- data.set(c, downloaded);
122
- downloaded = nextDownloaded;
123
- onProgress?.(downloaded);
124
- }
125
- if (size !== downloaded) {
126
- throw new BadTarballError({
127
- expectedSize: size,
128
- receivedSize: downloaded,
129
- tarballUrl: url,
130
- });
131
- }
132
- }
133
- else {
134
- const chunks = [];
135
- for await (const chunk of res.body) {
136
- const c = chunk;
137
- chunks.push(c);
138
- downloaded += c.byteLength;
139
- onProgress?.(downloaded);
140
- }
141
- data = Buffer.from(new SharedArrayBuffer(downloaded));
142
- let offset = 0;
143
- for (const chunk of chunks) {
144
- data.set(chunk, offset);
145
- offset += chunk.byteLength;
146
- }
147
- }
148
- const elapsedSec = (Date.now() - startTime) / 1000;
149
- const avgKiBps = Math.floor((downloaded / elapsedSec) / 1024);
150
- if (downloaded > 0 && elapsedSec > 1 && avgKiBps < fetchMinSpeedKiBps) {
151
- const sizeKb = Math.floor(downloaded / 1024);
152
- globalWarn(`Tarball download average speed ${avgKiBps} KiB/s (size ${sizeKb} KiB) is below ${fetchMinSpeedKiBps} KiB/s: ${redactUrlForDisplay(url)} (GET)`);
153
- }
154
- }
155
- catch (err) {
156
- const error = isFetchTimeoutError(err)
157
- ? new FetchTimeoutError('FETCH_TIMEOUT', url, gotOpts.timeout, { cause: err })
158
- : isError(err) ? err : new Error(String(err), { cause: err });
159
- Object.assign(error, {
160
- attempts: currentAttempt,
161
- resource: url,
29
+ downloadRetryOpts,
30
+ fetchFromRegistry,
31
+ fetchMinSpeedKiBps,
32
+ gotOpts,
33
+ op,
34
+ opts,
35
+ reject,
36
+ resolve,
37
+ url,
162
38
  });
163
- throw error;
164
- }
165
- return addFilesFromTarball({
166
- buffer: data,
167
- storeDir: opts.cafs.storeDir,
168
- storeIndex: opts.storeIndex,
169
- readManifest: opts.readManifest,
170
- integrity: opts.integrity,
171
- filesIndexFile: opts.filesIndexFile,
172
- pkgId: opts.pkgId,
173
- url,
174
- pkg: opts.pkg,
175
- appendManifest: opts.appendManifest,
176
- ignoreFilePattern: opts.ignoreFilePattern,
177
39
  });
40
+ });
41
+ };
42
+ }
43
+ async function executeDownloadAttempt(ctx) {
44
+ try {
45
+ const result = await fetchTarball({
46
+ attempt: ctx.attempt,
47
+ authHeaderValue: ctx.authHeaderValue,
48
+ fetchFromRegistry: ctx.fetchFromRegistry,
49
+ fetchMinSpeedKiBps: ctx.fetchMinSpeedKiBps,
50
+ gotOpts: ctx.gotOpts,
51
+ opts: ctx.opts,
52
+ url: ctx.url,
53
+ });
54
+ ctx.resolve(result);
55
+ }
56
+ catch (error) { // eslint-disable-line
57
+ handleDownloadRetry({
58
+ attempt: ctx.attempt,
59
+ downloadRetryOpts: ctx.downloadRetryOpts,
60
+ error,
61
+ op: ctx.op,
62
+ opts: ctx.opts,
63
+ reject: ctx.reject,
64
+ url: ctx.url,
65
+ });
66
+ }
67
+ }
68
+ async function fetchTarball(ctx) {
69
+ let data;
70
+ try {
71
+ const res = await ctx.fetchFromRegistry(ctx.url, {
72
+ authHeaderValue: ctx.authHeaderValue,
73
+ headers: { 'accept-encoding': 'identity' },
74
+ retry: { retries: 0 },
75
+ redirect: ctx.opts.redirect,
76
+ timeout: ctx.gotOpts.timeout,
77
+ });
78
+ if (res.status !== 200) {
79
+ throw new FetchError({ url: ctx.url, authHeaderValue: ctx.authHeaderValue }, res);
178
80
  }
81
+ const size = parseTarballContentLength(res);
82
+ ctx.opts.onStart?.(size, ctx.attempt);
83
+ const onProgress = (size != null && size >= BIG_TARBALL_SIZE && ctx.opts.onProgress)
84
+ ? throttle(ctx.opts.onProgress, 500)
85
+ : undefined;
86
+ data = await readResponseBody({
87
+ body: res.body,
88
+ fetchMinSpeedKiBps: ctx.fetchMinSpeedKiBps,
89
+ onProgress,
90
+ size,
91
+ url: ctx.url,
92
+ });
93
+ }
94
+ catch (err) {
95
+ throw wrapFetchError(err, ctx.url, ctx.attempt, ctx.gotOpts.timeout);
96
+ }
97
+ return addFilesFromTarball({
98
+ buffer: data,
99
+ storeDir: ctx.opts.cafs.storeDir,
100
+ storeIndex: ctx.opts.storeIndex,
101
+ readManifest: ctx.opts.readManifest,
102
+ integrity: ctx.opts.integrity,
103
+ filesIndexFile: ctx.opts.filesIndexFile,
104
+ pkgId: ctx.opts.pkgId,
105
+ url: ctx.url,
106
+ pkg: ctx.opts.pkg,
107
+ appendManifest: ctx.opts.appendManifest,
108
+ ignoreFilePattern: ctx.opts.ignoreFilePattern,
109
+ });
110
+ }
111
+ function parseTarballContentLength(res) {
112
+ const isEncoded = isContentEncoded(res.headers.get('content-encoding'));
113
+ const contentLength = !isEncoded && res.headers.has('content-length') && res.headers.get('content-length');
114
+ const parsedLength = typeof contentLength === 'string' ? parseInt(contentLength, 10) : NaN;
115
+ return Number.isFinite(parsedLength) && parsedLength >= 0 ? parsedLength : null;
116
+ }
117
+ async function readResponseBody(opts) {
118
+ const startTime = Date.now();
119
+ let downloaded = 0;
120
+ let data;
121
+ if (opts.size !== null) {
122
+ data = await readKnownSizeBody(opts.body, opts.size, opts.url, opts.onProgress);
123
+ downloaded = opts.size;
124
+ }
125
+ else {
126
+ const result = await readChunkedBody(opts.body, opts.onProgress);
127
+ data = result.data;
128
+ downloaded = result.downloaded;
129
+ }
130
+ checkDownloadSpeed(downloaded, startTime, opts.fetchMinSpeedKiBps, opts.url);
131
+ return data;
132
+ }
133
+ async function readKnownSizeBody(body, size, url, onProgress) {
134
+ const data = Buffer.from(new SharedArrayBuffer(size));
135
+ let downloaded = 0;
136
+ for await (const chunk of body) {
137
+ const bytes = chunk;
138
+ const nextDownloaded = downloaded + bytes.byteLength;
139
+ if (nextDownloaded > size) {
140
+ throw new BadTarballError({ expectedSize: size, receivedSize: nextDownloaded, tarballUrl: url });
141
+ }
142
+ data.set(bytes, downloaded);
143
+ downloaded = nextDownloaded;
144
+ onProgress?.(downloaded);
145
+ }
146
+ if (size !== downloaded) {
147
+ throw new BadTarballError({ expectedSize: size, receivedSize: downloaded, tarballUrl: url });
148
+ }
149
+ return data;
150
+ }
151
+ async function readChunkedBody(body, onProgress) {
152
+ const chunks = [];
153
+ let downloaded = 0;
154
+ for await (const chunk of body) {
155
+ const bytes = chunk;
156
+ chunks.push(bytes);
157
+ downloaded += bytes.byteLength;
158
+ onProgress?.(downloaded);
159
+ }
160
+ const data = Buffer.from(new SharedArrayBuffer(downloaded));
161
+ let offset = 0;
162
+ for (const chunk of chunks) {
163
+ data.set(chunk, offset);
164
+ offset += chunk.byteLength;
165
+ }
166
+ return { data, downloaded };
167
+ }
168
+ function checkDownloadSpeed(downloaded, startTime, fetchMinSpeedKiBps, url) {
169
+ const elapsedSec = (Date.now() - startTime) / 1000;
170
+ const avgKiBps = Math.floor((downloaded / elapsedSec) / 1024);
171
+ if (downloaded > 0 && elapsedSec > 1 && avgKiBps < fetchMinSpeedKiBps) {
172
+ const sizeKb = Math.floor(downloaded / 1024);
173
+ globalWarn(`Tarball download average speed ${avgKiBps} KiB/s (size ${sizeKb} KiB) is below ${fetchMinSpeedKiBps} KiB/s: ${redactUrlForDisplay(url)} (GET)`);
174
+ }
175
+ }
176
+ function wrapFetchError(err, url, attempt, timeout) {
177
+ const error = isFetchTimeoutError(err)
178
+ ? new FetchTimeoutError('FETCH_TIMEOUT', url, timeout, { cause: err })
179
+ : isError(err) ? err : new Error(String(err), { cause: err });
180
+ Object.assign(error, {
181
+ attempts: attempt,
182
+ resource: url,
183
+ });
184
+ return error;
185
+ }
186
+ function handleDownloadRetry(opts) {
187
+ const status = opts.error.response?.status;
188
+ const isManualRedirect = opts.opts.redirect === 'manual' && status >= 300 && status < 400;
189
+ const isFatal = isManualRedirect ||
190
+ status === 401 ||
191
+ status === 403 ||
192
+ status === 404 ||
193
+ opts.error.code === 'ERR_PNPM_PREPARE_PKG_FAILURE' ||
194
+ isNonRetryableError(opts.error);
195
+ if (isFatal) {
196
+ opts.reject(opts.error);
197
+ return;
198
+ }
199
+ const timeout = opts.op.retry(opts.error);
200
+ if (timeout === false) {
201
+ opts.reject(opts.op.mainError());
202
+ return;
203
+ }
204
+ logRetryAttempt(opts.attempt, opts.error, opts.downloadRetryOpts.retries ?? 0, timeout, opts.url);
205
+ }
206
+ function logRetryAttempt(attempt, error, // eslint-disable-line
207
+ maxRetries, timeout, url) {
208
+ const errorInfo = {
209
+ name: error.name,
210
+ message: error.message,
211
+ code: error.code,
212
+ errno: error.errno,
213
+ status: error.status,
214
+ statusCode: error.statusCode,
215
+ cause: error.cause ? {
216
+ code: error.cause.code,
217
+ errno: error.cause.errno,
218
+ } : undefined,
179
219
  };
220
+ requestRetryLogger.debug({
221
+ attempt,
222
+ error: errorInfo,
223
+ maxRetries,
224
+ method: 'GET',
225
+ timeout,
226
+ url: redactUrlForDisplay(url),
227
+ });
180
228
  }
181
229
  function getSecureNodeMirrorAuthHeader(authHeaderValue, url, appendedPackageName) {
182
230
  if (authHeaderValue == null || appendedPackageName !== 'node')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/fetching.tarball-fetcher",
3
- "version": "1102.1.5",
3
+ "version": "1102.1.7",
4
4
  "description": "Fetcher for packages hosted as tarballs",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -29,15 +29,15 @@
29
29
  "!*.map"
30
30
  ],
31
31
  "dependencies": {
32
- "@pnpm/core-loggers": "1101.0.1",
32
+ "@pnpm/core-loggers": "1101.0.2",
33
33
  "@pnpm/error": "1100.2.1",
34
- "@pnpm/exec.prepare-package": "1100.0.39",
34
+ "@pnpm/exec.prepare-package": "1100.0.41",
35
35
  "@pnpm/fetching.fetcher-base": "1100.2.12",
36
36
  "@pnpm/fetching.types": "1100.0.3",
37
37
  "@pnpm/fs.graceful-fs": "1100.2.4",
38
- "@pnpm/fs.packlist": "1100.0.6",
39
- "@pnpm/network.fetch": "1100.1.19",
40
- "@pnpm/store.index": "1100.3.3",
38
+ "@pnpm/fs.packlist": "1100.0.7",
39
+ "@pnpm/network.fetch": "1100.1.21",
40
+ "@pnpm/store.index": "1101.0.0",
41
41
  "@pnpm/types": "1102.1.1",
42
42
  "@zkochan/retry": "^0.2.0",
43
43
  "lodash.throttle": "4.1.1",
@@ -45,14 +45,14 @@
45
45
  },
46
46
  "peerDependencies": {
47
47
  "@pnpm/logger": "^1100.0.0",
48
- "@pnpm/worker": "^1100.4.5"
48
+ "@pnpm/worker": "^1100.4.7"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@jest/globals": "30.4.1",
52
- "@pnpm/fetching.tarball-fetcher": "1102.1.5",
52
+ "@pnpm/fetching.tarball-fetcher": "1102.1.7",
53
53
  "@pnpm/logger": "1100.0.0",
54
54
  "@pnpm/store.cafs-types": "1100.1.1",
55
- "@pnpm/store.create-cafs-store": "1100.0.32",
55
+ "@pnpm/store.create-cafs-store": "1100.0.33",
56
56
  "@pnpm/test-fixtures": "1100.0.1",
57
57
  "@pnpm/text.ordinal-comparator": "1100.0.0",
58
58
  "@pnpm/types": "1102.1.1",
@@ -62,7 +62,7 @@
62
62
  "@types/ssri": "^7.1.5",
63
63
  "ssri": "13.0.1",
64
64
  "tempy": "3.0.0",
65
- "undici": "^7.29.0"
65
+ "undici": "^7.29.1"
66
66
  },
67
67
  "engines": {
68
68
  "node": ">=22.13"