@superblocksteam/sdk 2.0.123-next.0 → 2.0.124-next.0
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/.turbo/turbo-build.log +1 -1
- package/dist/cli-replacement/automatic-upgrades.d.ts +37 -1
- package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.js +162 -10
- package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.test.js +377 -8
- package/dist/cli-replacement/automatic-upgrades.test.js.map +1 -1
- package/dist/cli-replacement/dependency-install-classifier.d.mts +21 -0
- package/dist/cli-replacement/dependency-install-classifier.d.mts.map +1 -0
- package/dist/cli-replacement/dependency-install-classifier.mjs +83 -0
- package/dist/cli-replacement/dependency-install-classifier.mjs.map +1 -0
- package/dist/cli-replacement/dependency-install-classifier.test.d.mts +2 -0
- package/dist/cli-replacement/dependency-install-classifier.test.d.mts.map +1 -0
- package/dist/cli-replacement/dependency-install-classifier.test.mjs +51 -0
- package/dist/cli-replacement/dependency-install-classifier.test.mjs.map +1 -0
- package/dist/cli-replacement/dev-s3-restore.test.mjs +170 -14
- package/dist/cli-replacement/dev-s3-restore.test.mjs.map +1 -1
- package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs +33 -2
- package/dist/cli-replacement/dev-startup-git-before-dbfs-order.test.mjs.map +1 -1
- package/dist/cli-replacement/dev-token-priming.test.d.mts +31 -0
- package/dist/cli-replacement/dev-token-priming.test.d.mts.map +1 -0
- package/dist/cli-replacement/dev-token-priming.test.mjs +87 -0
- package/dist/cli-replacement/dev-token-priming.test.mjs.map +1 -0
- package/dist/cli-replacement/dev.d.mts +36 -0
- package/dist/cli-replacement/dev.d.mts.map +1 -1
- package/dist/cli-replacement/dev.interception.test.d.mts +2 -0
- package/dist/cli-replacement/dev.interception.test.d.mts.map +1 -0
- package/dist/cli-replacement/dev.interception.test.mjs +68 -0
- package/dist/cli-replacement/dev.interception.test.mjs.map +1 -0
- package/dist/cli-replacement/dev.mjs +396 -62
- package/dist/cli-replacement/dev.mjs.map +1 -1
- package/dist/cli-replacement/home-npmrc.d.mts +180 -0
- package/dist/cli-replacement/home-npmrc.d.mts.map +1 -0
- package/dist/cli-replacement/home-npmrc.mjs +283 -0
- package/dist/cli-replacement/home-npmrc.mjs.map +1 -0
- package/dist/cli-replacement/home-npmrc.test.d.mts +10 -0
- package/dist/cli-replacement/home-npmrc.test.d.mts.map +1 -0
- package/dist/cli-replacement/home-npmrc.test.mjs +582 -0
- package/dist/cli-replacement/home-npmrc.test.mjs.map +1 -0
- package/dist/cli-replacement/install-packages.classify.test.d.mts +2 -0
- package/dist/cli-replacement/install-packages.classify.test.d.mts.map +1 -0
- package/dist/cli-replacement/install-packages.classify.test.mjs +125 -0
- package/dist/cli-replacement/install-packages.classify.test.mjs.map +1 -0
- package/dist/cli-replacement/install-packages.npm-registry.test.d.mts +2 -0
- package/dist/cli-replacement/install-packages.npm-registry.test.d.mts.map +1 -0
- package/dist/cli-replacement/install-packages.npm-registry.test.mjs +260 -0
- package/dist/cli-replacement/install-packages.npm-registry.test.mjs.map +1 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.d.mts +58 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.d.mts.map +1 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.mjs +224 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.mjs.map +1 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.test.d.mts +11 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.test.d.mts.map +1 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.test.mjs +317 -0
- package/dist/cli-replacement/post-upgrade-lockfile-strip.test.mjs.map +1 -0
- package/dist/cli-replacement/userconfig-env.integration.test.d.mts +26 -0
- package/dist/cli-replacement/userconfig-env.integration.test.d.mts.map +1 -0
- package/dist/cli-replacement/userconfig-env.integration.test.mjs +148 -0
- package/dist/cli-replacement/userconfig-env.integration.test.mjs.map +1 -0
- package/dist/dev-utils/dev-server-metrics.d.mts +25 -0
- package/dist/dev-utils/dev-server-metrics.d.mts.map +1 -1
- package/dist/dev-utils/dev-server-metrics.mjs +84 -0
- package/dist/dev-utils/dev-server-metrics.mjs.map +1 -1
- package/dist/dev-utils/dev-server-metrics.test.d.mts +2 -0
- package/dist/dev-utils/dev-server-metrics.test.d.mts.map +1 -0
- package/dist/dev-utils/dev-server-metrics.test.mjs +26 -0
- package/dist/dev-utils/dev-server-metrics.test.mjs.map +1 -0
- package/dist/dev-utils/dev-server.d.mts +23 -1
- package/dist/dev-utils/dev-server.d.mts.map +1 -1
- package/dist/dev-utils/dev-server.mjs +21 -9
- package/dist/dev-utils/dev-server.mjs.map +1 -1
- package/dist/dev-utils/dev-server.status.test.d.mts +2 -0
- package/dist/dev-utils/dev-server.status.test.d.mts.map +1 -0
- package/dist/dev-utils/dev-server.status.test.mjs +41 -0
- package/dist/dev-utils/dev-server.status.test.mjs.map +1 -0
- package/dist/dev-utils/token-manager.d.ts +31 -0
- package/dist/dev-utils/token-manager.d.ts.map +1 -1
- package/dist/dev-utils/token-manager.js +34 -0
- package/dist/dev-utils/token-manager.js.map +1 -1
- package/dist/telemetry/local-obs.js +1 -1
- package/dist/telemetry/local-obs.js.map +1 -1
- package/dist/telemetry/util.js +1 -1
- package/dist/types/scoped-jwt-token-payload.d.ts +1 -0
- package/dist/types/scoped-jwt-token-payload.d.ts.map +1 -1
- package/dist/version-control.d.mts.map +1 -1
- package/dist/version-control.mjs +6 -7
- package/dist/version-control.mjs.map +1 -1
- package/package.json +12 -12
- package/src/cli-replacement/automatic-upgrades.test.ts +530 -8
- package/src/cli-replacement/automatic-upgrades.ts +179 -7
- package/src/cli-replacement/dependency-install-classifier.mts +118 -0
- package/src/cli-replacement/dependency-install-classifier.test.mts +72 -0
- package/src/cli-replacement/dev-s3-restore.test.mts +210 -14
- package/src/cli-replacement/dev-startup-git-before-dbfs-order.test.mts +35 -2
- package/src/cli-replacement/dev-token-priming.test.mts +103 -0
- package/src/cli-replacement/dev.interception.test.mts +80 -0
- package/src/cli-replacement/dev.mts +495 -92
- package/src/cli-replacement/home-npmrc.mts +409 -0
- package/src/cli-replacement/home-npmrc.test.mts +757 -0
- package/src/cli-replacement/install-packages.classify.test.mts +168 -0
- package/src/cli-replacement/install-packages.npm-registry.test.mts +345 -0
- package/src/cli-replacement/post-upgrade-lockfile-strip.mts +296 -0
- package/src/cli-replacement/post-upgrade-lockfile-strip.test.mts +482 -0
- package/src/cli-replacement/userconfig-env.integration.test.mts +189 -0
- package/src/dev-utils/dev-server-metrics.mts +96 -0
- package/src/dev-utils/dev-server-metrics.test.mts +38 -0
- package/src/dev-utils/dev-server.mts +48 -8
- package/src/dev-utils/dev-server.status.test.mts +58 -0
- package/src/dev-utils/token-manager.ts +36 -0
- package/src/telemetry/local-obs.ts +1 -1
- package/src/telemetry/util.ts +1 -1
- package/src/types/scoped-jwt-token-payload.ts +1 -0
- package/src/version-control.mts +8 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/.turbo/turbo-publish-package.log +0 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-CLI-upgrade lockfile normalization for the dev-server pod's globally
|
|
3
|
+
* installed Superblocks CLI.
|
|
4
|
+
*
|
|
5
|
+
* npm honors `resolved` URLs verbatim, so a tarball whose bundled lockfile
|
|
6
|
+
* entries point at `registry.npmjs.org` keeps fetching from public npm even
|
|
7
|
+
* after we've written a private `.npmrc`. This module strips those URLs
|
|
8
|
+
* post-upgrade so subsequent installs re-resolve through the active registry.
|
|
9
|
+
*
|
|
10
|
+
* The walk from the resolved `superblocks` binary up to the CLI package root
|
|
11
|
+
* is bounded so a misconfigured layout can never mutate arbitrary lockfiles
|
|
12
|
+
* on the filesystem.
|
|
13
|
+
*
|
|
14
|
+
* All failures are logged and swallowed — a failed post-strip must not crash
|
|
15
|
+
* the pod after a working upgrade. The next dev startup repeats the strip
|
|
16
|
+
* idempotently.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import * as child_process from "node:child_process";
|
|
20
|
+
import fs from "node:fs/promises";
|
|
21
|
+
import * as path from "node:path";
|
|
22
|
+
import { promisify } from "node:util";
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
stripResolvedFromLockfile,
|
|
26
|
+
stripResolvedFromLockfilePath,
|
|
27
|
+
} from "@superblocksteam/vite-plugin-file-sync/npm-registry";
|
|
28
|
+
|
|
29
|
+
import { getErrorMeta, type Logger } from "../telemetry/logging.js";
|
|
30
|
+
|
|
31
|
+
const exec = promisify(child_process.exec);
|
|
32
|
+
|
|
33
|
+
const LOG_PREFIX = "[post-upgrade-lockfile-strip]";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Upper bound on the post-upgrade strip. The I/O is local and small, but the
|
|
37
|
+
* CLI install can live on a network-mounted prefix (custom `npm prefix`,
|
|
38
|
+
* Volta cache, etc.) where a hung `fs.realpath` or `fs.readFile` would
|
|
39
|
+
* otherwise extend `cliUpgradePromise` and block dev-server startup. A
|
|
40
|
+
* timeout keeps the boot path bounded; the underlying I/O is left to settle
|
|
41
|
+
* in the background since every step is idempotent and individually error-
|
|
42
|
+
* swallowing.
|
|
43
|
+
*/
|
|
44
|
+
const STRIP_TIMEOUT_MS = 5_000;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Upper bound on `package.json` lookups when walking up from the resolved
|
|
48
|
+
* `superblocks` binary. The expected path depth is 3 levels
|
|
49
|
+
* (`<prefix>/lib/node_modules/@superblocksteam/cli/bin/run.js` ->
|
|
50
|
+
* `<prefix>/lib/node_modules/@superblocksteam/cli`); 8 leaves headroom for
|
|
51
|
+
* non-standard layouts (Volta, nvm, custom prefixes) without ever climbing
|
|
52
|
+
* out of the install tree.
|
|
53
|
+
*/
|
|
54
|
+
const MAX_PACKAGE_ROOT_WALK_DEPTH = 8;
|
|
55
|
+
|
|
56
|
+
// Both names are valid CLI install roots: `cli-ephemeral` is the alias used
|
|
57
|
+
// for snapshot builds (see the alias detection in `version-detection.ts`),
|
|
58
|
+
// and either may appear in the global install depending on which channel the
|
|
59
|
+
// pod was provisioned against.
|
|
60
|
+
const CLI_PACKAGE_NAMES = new Set<string>([
|
|
61
|
+
"@superblocksteam/cli",
|
|
62
|
+
"@superblocksteam/cli-ephemeral",
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Injectable subset of `child_process.exec` so tests can stub the
|
|
67
|
+
* `which`/`where` lookup without spawning a real subprocess.
|
|
68
|
+
*/
|
|
69
|
+
export type WhichRunner = (binary: string) => Promise<string>;
|
|
70
|
+
|
|
71
|
+
const defaultWhichRunner: WhichRunner = async (binary) => {
|
|
72
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
73
|
+
const { stdout } = await exec(`${cmd} ${binary}`);
|
|
74
|
+
return stdout;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Discovers the absolute path of the `@superblocksteam/cli` install root
|
|
79
|
+
* (the directory containing the CLI's `package.json`), or returns `undefined`
|
|
80
|
+
* if discovery fails. Discovery failures are non-fatal — the caller logs and
|
|
81
|
+
* skips the strip rather than aborting.
|
|
82
|
+
*/
|
|
83
|
+
export async function findGlobalCliInstallDir(
|
|
84
|
+
logger: Logger,
|
|
85
|
+
whichRunner: WhichRunner = defaultWhichRunner,
|
|
86
|
+
): Promise<string | undefined> {
|
|
87
|
+
let binStdout: string;
|
|
88
|
+
try {
|
|
89
|
+
binStdout = await whichRunner("superblocks");
|
|
90
|
+
} catch (error) {
|
|
91
|
+
logger.warn(
|
|
92
|
+
`${LOG_PREFIX} which/where superblocks failed; skipping strip`,
|
|
93
|
+
{
|
|
94
|
+
...getErrorMeta(error),
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// `which`/`where` may emit multiple lines (e.g. shim + real path on
|
|
101
|
+
// Windows). The first line wins; matches the existing pattern in
|
|
102
|
+
// `version-detection.ts`.
|
|
103
|
+
const binPath = binStdout.trim().split(/\r?\n/)[0]?.trim();
|
|
104
|
+
if (!binPath) {
|
|
105
|
+
logger.warn(
|
|
106
|
+
`${LOG_PREFIX} superblocks binary not found in PATH; skipping strip`,
|
|
107
|
+
);
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let realBinPath: string;
|
|
112
|
+
try {
|
|
113
|
+
realBinPath = await fs.realpath(binPath);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
logger.warn(
|
|
116
|
+
`${LOG_PREFIX} realpath failed for superblocks binary; skipping strip`,
|
|
117
|
+
{
|
|
118
|
+
binPath,
|
|
119
|
+
...getErrorMeta(error),
|
|
120
|
+
},
|
|
121
|
+
);
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let dir = path.dirname(realBinPath);
|
|
126
|
+
for (let i = 0; i < MAX_PACKAGE_ROOT_WALK_DEPTH; i++) {
|
|
127
|
+
const candidate = path.join(dir, "package.json");
|
|
128
|
+
let raw: string;
|
|
129
|
+
try {
|
|
130
|
+
raw = await fs.readFile(candidate, "utf-8");
|
|
131
|
+
} catch (error: unknown) {
|
|
132
|
+
const code = (error as NodeJS.ErrnoException | undefined)?.code;
|
|
133
|
+
if (code === "ENOENT") {
|
|
134
|
+
const parent = path.dirname(dir);
|
|
135
|
+
if (parent === dir) {
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
dir = parent;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
logger.warn(
|
|
142
|
+
`${LOG_PREFIX} failed to read candidate package.json; skipping strip`,
|
|
143
|
+
{
|
|
144
|
+
candidate,
|
|
145
|
+
code,
|
|
146
|
+
...getErrorMeta(error),
|
|
147
|
+
},
|
|
148
|
+
);
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let parsed: { name?: unknown } | undefined;
|
|
153
|
+
try {
|
|
154
|
+
parsed = JSON.parse(raw) as { name?: unknown };
|
|
155
|
+
} catch (error) {
|
|
156
|
+
logger.warn(
|
|
157
|
+
`${LOG_PREFIX} candidate package.json is not valid JSON; skipping strip`,
|
|
158
|
+
{
|
|
159
|
+
candidate,
|
|
160
|
+
...getErrorMeta(error),
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (typeof parsed.name === "string" && CLI_PACKAGE_NAMES.has(parsed.name)) {
|
|
167
|
+
return dir;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Found a `package.json` that isn't the CLI's — keep walking up. Some
|
|
171
|
+
// layouts (oclif's update channel) nest the binary under a wrapper
|
|
172
|
+
// package; we don't want to bail on the first unrelated manifest.
|
|
173
|
+
const parent = path.dirname(dir);
|
|
174
|
+
if (parent === dir) {
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
dir = parent;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
logger.warn(
|
|
181
|
+
`${LOG_PREFIX} could not locate @superblocksteam/cli install root; skipping strip`,
|
|
182
|
+
{
|
|
183
|
+
startedAt: realBinPath,
|
|
184
|
+
},
|
|
185
|
+
);
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface StripUpgradedCliLockfilesOptions {
|
|
190
|
+
/**
|
|
191
|
+
* Pre-resolved install root. If omitted, `findGlobalCliInstallDir` is used.
|
|
192
|
+
* Tests pass this directly to avoid stubbing `which`.
|
|
193
|
+
*/
|
|
194
|
+
installDir?: string;
|
|
195
|
+
whichRunner?: WhichRunner;
|
|
196
|
+
/**
|
|
197
|
+
* Override the strip timeout (ms). Tests use a tight value to exercise the
|
|
198
|
+
* timeout branch without sleeping for the real bound.
|
|
199
|
+
*/
|
|
200
|
+
timeoutMs?: number;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Strips public-host `resolved` URLs from every lockfile under the global
|
|
205
|
+
* CLI install that the auto-upgrade could have refreshed. Returns the
|
|
206
|
+
* resolved install root on success, or `undefined` when discovery failed.
|
|
207
|
+
*
|
|
208
|
+
* Non-fatal: every individual strip already swallows lockfile-level errors
|
|
209
|
+
* (logged in `stripResolvedFromLockfilePath`); this wrapper additionally
|
|
210
|
+
* swallows discovery failures and any unexpected throw from the inner
|
|
211
|
+
* helpers so a successful upgrade is never demoted to a crash by a post-step
|
|
212
|
+
* problem.
|
|
213
|
+
*/
|
|
214
|
+
export async function stripUpgradedCliLockfiles(
|
|
215
|
+
logger: Logger,
|
|
216
|
+
options: StripUpgradedCliLockfilesOptions = {},
|
|
217
|
+
): Promise<{ installDir?: string }> {
|
|
218
|
+
const installDir =
|
|
219
|
+
options.installDir ??
|
|
220
|
+
(await findGlobalCliInstallDir(logger, options.whichRunner));
|
|
221
|
+
if (!installDir) {
|
|
222
|
+
return {};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const timeoutMs = options.timeoutMs ?? STRIP_TIMEOUT_MS;
|
|
226
|
+
const start = Date.now();
|
|
227
|
+
// The hidden lockfile listing the CLI itself lives two levels up from
|
|
228
|
+
// installDir under the npm-global layout
|
|
229
|
+
// (<prefix>/lib/node_modules/.package-lock.json).
|
|
230
|
+
const globalHiddenLockfile = path.join(
|
|
231
|
+
path.dirname(path.dirname(installDir)),
|
|
232
|
+
".package-lock.json",
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
const STRIP_TIMED_OUT = Symbol("STRIP_TIMED_OUT");
|
|
236
|
+
let timeoutHandle: NodeJS.Timeout | undefined;
|
|
237
|
+
const timeoutPromise = new Promise<typeof STRIP_TIMED_OUT>((resolve) => {
|
|
238
|
+
timeoutHandle = setTimeout(() => resolve(STRIP_TIMED_OUT), timeoutMs);
|
|
239
|
+
});
|
|
240
|
+
try {
|
|
241
|
+
const stripWork = Promise.all([
|
|
242
|
+
stripResolvedFromLockfile(installDir),
|
|
243
|
+
stripResolvedFromLockfilePath(globalHiddenLockfile),
|
|
244
|
+
]);
|
|
245
|
+
const outcome = await Promise.race([stripWork, timeoutPromise]);
|
|
246
|
+
if (outcome === STRIP_TIMED_OUT) {
|
|
247
|
+
logger.warn(
|
|
248
|
+
`${LOG_PREFIX} strip exceeded timeout; continuing without waiting`,
|
|
249
|
+
{
|
|
250
|
+
installDir,
|
|
251
|
+
timeoutMs,
|
|
252
|
+
elapsedMs: Date.now() - start,
|
|
253
|
+
},
|
|
254
|
+
);
|
|
255
|
+
// We're abandoning `stripWork` after the timeout won the race. The
|
|
256
|
+
// inner helpers swallow per-file errors, but their atomic `writeFile`
|
|
257
|
+
// / `rename` calls can still throw (EACCES, EXDEV, ENOSPC, …) — and
|
|
258
|
+
// with no subscriber left on `stripWork`, a late rejection would
|
|
259
|
+
// surface as an unhandled rejection and crash the pod under Node's
|
|
260
|
+
// default policy. Attach a tail handler to keep the post-step
|
|
261
|
+
// non-fatal even when the timeout path is taken.
|
|
262
|
+
stripWork.catch((error) => {
|
|
263
|
+
logger.warn(
|
|
264
|
+
`${LOG_PREFIX} background strip rejected after timeout; ignoring`,
|
|
265
|
+
{
|
|
266
|
+
...getErrorMeta(error),
|
|
267
|
+
installDir,
|
|
268
|
+
},
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
} else {
|
|
272
|
+
logger.info(
|
|
273
|
+
`${LOG_PREFIX} stripped resolved URLs from upgraded CLI lockfiles`,
|
|
274
|
+
{
|
|
275
|
+
installDir,
|
|
276
|
+
elapsedMs: Date.now() - start,
|
|
277
|
+
},
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
} catch (error) {
|
|
281
|
+
// The lower-level helpers already swallow per-file errors; this catches
|
|
282
|
+
// any unexpected throw so a post-step problem never surfaces as a failed
|
|
283
|
+
// upgrade.
|
|
284
|
+
logger.warn(`${LOG_PREFIX} unexpected error during strip; continuing`, {
|
|
285
|
+
...getErrorMeta(error),
|
|
286
|
+
installDir,
|
|
287
|
+
elapsedMs: Date.now() - start,
|
|
288
|
+
});
|
|
289
|
+
} finally {
|
|
290
|
+
if (timeoutHandle) {
|
|
291
|
+
clearTimeout(timeoutHandle);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return { installDir };
|
|
296
|
+
}
|