@stim-cli/core 1.23.0 → 1.23.1
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/dist/{core-BTsCO1nW.mjs → core-B23eUZZp.mjs} +11 -5
- package/dist/index.d.mts +7 -3
- package/dist/index.mjs +1 -1
- package/dist/state.mjs +1 -1
- package/dist/toolchain.d.mts +22 -7
- package/dist/toolchain.mjs +93 -32
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { C as quotedPath, S as tryAcquireClaim, _ as releaseClaim, r as ClaimRefusedError, x as sleepSync } from "./ownership-claim-DHUs_Dir.mjs";
|
|
2
|
+
import { projectNodeBin } from "./toolchain.mjs";
|
|
2
3
|
import fs, { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, utimesSync, writeFileSync } from "node:fs";
|
|
3
4
|
import os from "node:os";
|
|
4
5
|
import path, { basename, dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
@@ -566,8 +567,12 @@ async function compiledHelper({ dir, name, inputs, version, compile, prune = tru
|
|
|
566
567
|
}
|
|
567
568
|
//#endregion
|
|
568
569
|
//#region dependency-install.ts
|
|
569
|
-
/**
|
|
570
|
-
|
|
570
|
+
/**
|
|
571
|
+
* The existing worker install command and marker identity for a repository's selected lockfile. The marker identity
|
|
572
|
+
* also names the major of the Node `projectNodeBin` picks for the pin of the project at `project`, or `path` when it
|
|
573
|
+
* picks none, so that native addons are rebuilt when the pinned Node changes major.
|
|
574
|
+
*/
|
|
575
|
+
function dependencyInstall(root, packageName, project = ".", env = process.env) {
|
|
571
576
|
const file = [
|
|
572
577
|
"pnpm-lock.yaml",
|
|
573
578
|
"yarn.lock",
|
|
@@ -581,21 +586,22 @@ function dependencyInstall(root, packageName) {
|
|
|
581
586
|
...packageName ? ["--filter", `${packageName}...`] : []
|
|
582
587
|
] : command === "yarn" ? ["install", "--frozen-lockfile"] : ["ci"];
|
|
583
588
|
const bytes = readFileSync(join(root, file));
|
|
589
|
+
const node = projectNodeBin(join(root, project), env, void 0, root)?.version.split(".")[0] ?? "path";
|
|
584
590
|
return {
|
|
585
591
|
command,
|
|
586
592
|
args,
|
|
587
593
|
lockfile: createHash("sha256").update(bytes).digest("hex"),
|
|
588
|
-
digest: createHash("sha256").update(bytes).update(JSON.stringify(args)).digest("hex")
|
|
594
|
+
digest: createHash("sha256").update(bytes).update(JSON.stringify(args)).update(`node ${node}`).digest("hex")
|
|
589
595
|
};
|
|
590
596
|
}
|
|
591
597
|
/** Whether the worker can reuse this project's dependency install without running the package manager. */
|
|
592
|
-
function reusableDependencies(area, project, packageName, lockfile) {
|
|
598
|
+
function reusableDependencies(area, project, packageName, lockfile, env = process.env) {
|
|
593
599
|
try {
|
|
594
600
|
const root = realpathSync(join(area, "src"));
|
|
595
601
|
const selected = realpathSync(join(root, project));
|
|
596
602
|
const path = relative(root, selected);
|
|
597
603
|
if (path === ".." || path.startsWith(`..${sep}`) || isAbsolute(path)) return false;
|
|
598
|
-
const install = dependencyInstall(root, packageName);
|
|
604
|
+
const install = dependencyInstall(root, packageName, path, env);
|
|
599
605
|
return install?.lockfile === lockfile && existsSync(join(selected, "node_modules")) && readFileSync(join(area, "dependencies"), "utf8") === install.digest;
|
|
600
606
|
} catch {
|
|
601
607
|
return false;
|
package/dist/index.d.mts
CHANGED
|
@@ -116,15 +116,19 @@ declare function compiledHelper({ dir, name, inputs, version, compile, prune }:
|
|
|
116
116
|
}): Promise<string>;
|
|
117
117
|
//#endregion
|
|
118
118
|
//#region dependency-install.d.ts
|
|
119
|
-
/**
|
|
120
|
-
|
|
119
|
+
/**
|
|
120
|
+
* The existing worker install command and marker identity for a repository's selected lockfile. The marker identity
|
|
121
|
+
* also names the major of the Node `projectNodeBin` picks for the pin of the project at `project`, or `path` when it
|
|
122
|
+
* picks none, so that native addons are rebuilt when the pinned Node changes major.
|
|
123
|
+
*/
|
|
124
|
+
declare function dependencyInstall(root: string, packageName: string | null, project?: string, env?: NodeJS.ProcessEnv): {
|
|
121
125
|
command: "pnpm" | "yarn" | "npm";
|
|
122
126
|
args: string[];
|
|
123
127
|
lockfile: string;
|
|
124
128
|
digest: string;
|
|
125
129
|
} | null;
|
|
126
130
|
/** Whether the worker can reuse this project's dependency install without running the package manager. */
|
|
127
|
-
declare function reusableDependencies(area: string, project: string, packageName: string | null, lockfile: string): boolean;
|
|
131
|
+
declare function reusableDependencies(area: string, project: string, packageName: string | null, lockfile: string, env?: NodeJS.ProcessEnv): boolean;
|
|
128
132
|
//#endregion
|
|
129
133
|
//#region metro-bridge.d.ts
|
|
130
134
|
interface MetroBridge {
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { C as quotedPath } from "./ownership-claim-DHUs_Dir.mjs";
|
|
2
|
-
import { $ as withDirLockTransaction, A as createMetroGateway, B as unitWords, C as workspaceName, D as reactNativeArtifactIdentity, E as swiftpmArtifactQuery, F as artifactIn, G as withAmbientContext, H as ambientContext, I as resolveArtifact, L as storeArtifact, M as reusableDependencies, N as compiledHelper, O as reactNativeArtifactQuery, P as storeArtifactAsync, Q as withDirLockAsync, R as quoteUnitWord, S as workspaceLogDir, T as workspaceStateDir, U as ambientEnv, V as validMacosResourceDestination, W as ambientWrite, Z as withDirLock, _ as rotatedLogPath, a as buildCacheRoot, b as updateCacheManifest, c as cacheNameSegment, d as ensurePrivateDir, f as hostSimulatorArch, g as rotateLog, h as registerCache, i as buildCacheKey, j as dependencyInstall, k as createMetroBridge, l as cachePathSetting, m as readCacheManifest, n as METRO_NAMED_CACHE_LAYOUT, o as cacheDirRefusal, p as metroCacheRoot, r as STORE_ROOT_TAG, s as cacheManifestLockPath, t as LOG_ROTATE_BYTES, u as configDir, v as sharedStoreRoot, w as workspaceSlug, x as workspaceId, y as tagSharedStore, z as unitLines } from "./core-
|
|
2
|
+
import { $ as withDirLockTransaction, A as createMetroGateway, B as unitWords, C as workspaceName, D as reactNativeArtifactIdentity, E as swiftpmArtifactQuery, F as artifactIn, G as withAmbientContext, H as ambientContext, I as resolveArtifact, L as storeArtifact, M as reusableDependencies, N as compiledHelper, O as reactNativeArtifactQuery, P as storeArtifactAsync, Q as withDirLockAsync, R as quoteUnitWord, S as workspaceLogDir, T as workspaceStateDir, U as ambientEnv, V as validMacosResourceDestination, W as ambientWrite, Z as withDirLock, _ as rotatedLogPath, a as buildCacheRoot, b as updateCacheManifest, c as cacheNameSegment, d as ensurePrivateDir, f as hostSimulatorArch, g as rotateLog, h as registerCache, i as buildCacheKey, j as dependencyInstall, k as createMetroBridge, l as cachePathSetting, m as readCacheManifest, n as METRO_NAMED_CACHE_LAYOUT, o as cacheDirRefusal, p as metroCacheRoot, r as STORE_ROOT_TAG, s as cacheManifestLockPath, t as LOG_ROTATE_BYTES, u as configDir, v as sharedStoreRoot, w as workspaceSlug, x as workspaceId, y as tagSharedStore, z as unitLines } from "./core-B23eUZZp.mjs";
|
|
3
3
|
export { LOG_ROTATE_BYTES, METRO_NAMED_CACHE_LAYOUT, STORE_ROOT_TAG, ambientContext, ambientEnv, ambientWrite, artifactIn, buildCacheKey, buildCacheRoot, cacheDirRefusal, cacheManifestLockPath, cacheNameSegment, cachePathSetting, compiledHelper, configDir, createMetroBridge, createMetroGateway, dependencyInstall, ensurePrivateDir, hostSimulatorArch, metroCacheRoot, quoteUnitWord, quotedPath, reactNativeArtifactIdentity, reactNativeArtifactQuery, readCacheManifest, registerCache, resolveArtifact, reusableDependencies, rotateLog, rotatedLogPath, sharedStoreRoot, storeArtifact, storeArtifactAsync, swiftpmArtifactQuery, tagSharedStore, unitLines, unitWords, updateCacheManifest, validMacosResourceDestination, withAmbientContext, withDirLock, withDirLockAsync, withDirLockTransaction, workspaceId, workspaceLogDir, workspaceName, workspaceSlug, workspaceStateDir };
|
package/dist/state.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { S as tryAcquireClaim, _ as releaseClaim, f as isClaimRefusal, g as readClaimSet } from "./ownership-claim-DHUs_Dir.mjs";
|
|
2
2
|
import { inspectProcessIdentity } from "./process-identity.mjs";
|
|
3
|
-
import { C as workspaceName, H as ambientContext, J as readJsonObject, K as isJsonObject, Q as withDirLockAsync, T as workspaceStateDir, U as ambientEnv, X as withStateReadCache, Y as readStateFile, Z as withDirLock, _ as rotatedLogPath, d as ensurePrivateDir, g as rotateLog, q as readJsonFile, t as LOG_ROTATE_BYTES, u as configDir } from "./core-
|
|
3
|
+
import { C as workspaceName, H as ambientContext, J as readJsonObject, K as isJsonObject, Q as withDirLockAsync, T as workspaceStateDir, U as ambientEnv, X as withStateReadCache, Y as readStateFile, Z as withDirLock, _ as rotatedLogPath, d as ensurePrivateDir, g as rotateLog, q as readJsonFile, t as LOG_ROTATE_BYTES, u as configDir } from "./core-B23eUZZp.mjs";
|
|
4
4
|
import { readOrCreateKeyFile } from "./noise-session.mjs";
|
|
5
5
|
import { validHomeId } from "./workspace-link.mjs";
|
|
6
6
|
import { a as workspaceSummary, i as statusViews, n as applyKeyedDelta, o as withDerivedFacts, r as SUMMARY_ARCHIVES, s as withGitChip, t as KeyedEntities } from "./keyed-delta-BBoOeR2J.mjs";
|
package/dist/toolchain.d.mts
CHANGED
|
@@ -8,6 +8,8 @@ interface ToolchainProbe {
|
|
|
8
8
|
isFile(path: string): boolean;
|
|
9
9
|
read(path: string): string | null;
|
|
10
10
|
list(path: string): string[];
|
|
11
|
+
/** The target of the symbolic link at `path`, or null when it is not one. */
|
|
12
|
+
link(path: string): string | null;
|
|
11
13
|
}
|
|
12
14
|
declare function defaultToolchainProbe(): ToolchainProbe;
|
|
13
15
|
/**
|
|
@@ -27,6 +29,11 @@ interface Toolchain {
|
|
|
27
29
|
}
|
|
28
30
|
/** Whether Node `version`, such as `22.12.0`, satisfies a pin such as `22`, `v22.12` or `22.12.0`. */
|
|
29
31
|
declare function satisfiesNodePin(version: string, spec: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Whether Node `version` is an acceptable stand-in for a pin no install matches: the pin's major, and not older than
|
|
34
|
+
* the version the pin names.
|
|
35
|
+
*/
|
|
36
|
+
declare function meetsNodePinMajor(version: string, spec: string): boolean;
|
|
30
37
|
/** The `bin` directory of the Node a version manager makes the default in new shells, and where that came from. */
|
|
31
38
|
declare function defaultNodeBin(env: NodeJS.ProcessEnv, probe: ToolchainProbe): {
|
|
32
39
|
bin: string;
|
|
@@ -44,21 +51,29 @@ declare function discoverToolchain(base: NodeJS.ProcessEnv, probe?: ToolchainPro
|
|
|
44
51
|
runningNode?: boolean;
|
|
45
52
|
platform?: NodeJS.Platform;
|
|
46
53
|
}): Toolchain;
|
|
47
|
-
/**
|
|
48
|
-
|
|
54
|
+
/**
|
|
55
|
+
* The Node version pinned by `.nvmrc`, `.node-version`, `.tool-versions` or `package.json`'s `volta.node` in `root`,
|
|
56
|
+
* or else in the nearest directory above it up to `top`.
|
|
57
|
+
*/
|
|
58
|
+
declare function projectNodePin(root: string, probe?: ToolchainProbe, top?: string): {
|
|
49
59
|
spec: string;
|
|
50
60
|
file: string;
|
|
51
61
|
} | null;
|
|
62
|
+
/** A pin's version spec, with an `lts/...` pin resolved through nvm's aliases, or null when nvm cannot resolve it. */
|
|
63
|
+
declare function resolveNodePinSpec(spec: string, env: NodeJS.ProcessEnv, probe?: ToolchainProbe): string | null;
|
|
52
64
|
/**
|
|
53
|
-
* The `bin` directory of an installed Node
|
|
54
|
-
*
|
|
55
|
-
*
|
|
65
|
+
* The `bin` directory of an installed Node for the pin `projectNodePin` finds, from nvm, fnm, Volta, asdf, mise or a
|
|
66
|
+
* linked Homebrew `node` or `node@NN`, or null when the project pins none or no install fits. `match` is `exact` for an
|
|
67
|
+
* install the pin names. When none is, it is `major` for the newest install of the pinned major that is not older than
|
|
68
|
+
* the pinned version, since Homebrew cannot install a chosen patch release. An `lts/...` pin resolves through
|
|
69
|
+
* `resolveNodePinSpec`.
|
|
56
70
|
*/
|
|
57
|
-
declare function projectNodeBin(root: string, env: NodeJS.ProcessEnv, probe?: ToolchainProbe): {
|
|
71
|
+
declare function projectNodeBin(root: string, env: NodeJS.ProcessEnv, probe?: ToolchainProbe, top?: string): {
|
|
58
72
|
bin: string;
|
|
59
73
|
version: string;
|
|
60
74
|
pin: string;
|
|
61
75
|
spec: string;
|
|
76
|
+
match: "exact" | "major";
|
|
62
77
|
} | null;
|
|
63
78
|
//#endregion
|
|
64
|
-
export { Toolchain, ToolchainEntry, ToolchainProbe, defaultNodeBin, defaultToolchainProbe, discoverToolchain, projectNodeBin, projectNodePin, satisfiesNodePin };
|
|
79
|
+
export { Toolchain, ToolchainEntry, ToolchainProbe, defaultNodeBin, defaultToolchainProbe, discoverToolchain, meetsNodePinMajor, projectNodeBin, projectNodePin, resolveNodePinSpec, satisfiesNodePin };
|
package/dist/toolchain.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
1
|
+
import { readFileSync, readdirSync, readlinkSync, statSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
|
-
import { delimiter, dirname, join } from "node:path";
|
|
3
|
+
import { basename, delimiter, dirname, join } from "node:path";
|
|
4
4
|
//#region toolchain.ts
|
|
5
5
|
const stat = (path) => statSync(path, { throwIfNoEntry: false });
|
|
6
6
|
function defaultToolchainProbe() {
|
|
@@ -22,6 +22,13 @@ function defaultToolchainProbe() {
|
|
|
22
22
|
} catch {
|
|
23
23
|
return [];
|
|
24
24
|
}
|
|
25
|
+
},
|
|
26
|
+
link: (path) => {
|
|
27
|
+
try {
|
|
28
|
+
return readlinkSync(path);
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
25
32
|
}
|
|
26
33
|
};
|
|
27
34
|
}
|
|
@@ -38,8 +45,9 @@ function jdkRank(name) {
|
|
|
38
45
|
return major === 17 ? 0 : major === 21 ? 1 : 1e4 - major;
|
|
39
46
|
}
|
|
40
47
|
const ANDROID_STUDIOS = ["/Applications/Android Studio.app", "/Applications/Android Studio Preview.app"];
|
|
48
|
+
/** Accepts Homebrew's Cellar names too, such as `22.23.2_1`, whose `_1` is the formula revision. */
|
|
41
49
|
function parseVersion(text) {
|
|
42
|
-
const match = /^v?(\d+)\.(\d+)\.(\d+)
|
|
50
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:_\d+)?$/.exec(text.trim());
|
|
43
51
|
return match ? [
|
|
44
52
|
Number(match[1]),
|
|
45
53
|
Number(match[2]),
|
|
@@ -69,6 +77,24 @@ function newestMatching(names, wanted) {
|
|
|
69
77
|
function satisfiesNodePin(version, spec) {
|
|
70
78
|
return newestMatching([version], spec) !== null;
|
|
71
79
|
}
|
|
80
|
+
/** The lowest version a pin such as `22.22` or `v22.22.0` names, or null for a pin that names only a major or no number. */
|
|
81
|
+
function pinFloor(spec) {
|
|
82
|
+
const match = /^v?(\d+)\.(\d+)(?:\.(\d+))?$/.exec(spec.trim());
|
|
83
|
+
return match ? [
|
|
84
|
+
Number(match[1]),
|
|
85
|
+
Number(match[2]),
|
|
86
|
+
Number(match[3] ?? 0)
|
|
87
|
+
] : null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Whether Node `version` is an acceptable stand-in for a pin no install matches: the pin's major, and not older than
|
|
91
|
+
* the version the pin names.
|
|
92
|
+
*/
|
|
93
|
+
function meetsNodePinMajor(version, spec) {
|
|
94
|
+
const parsed = parseVersion(version);
|
|
95
|
+
const floor = pinFloor(spec);
|
|
96
|
+
return !!parsed && !!floor && parsed[0] === floor[0] && compareVersions(parsed, floor) >= 0;
|
|
97
|
+
}
|
|
72
98
|
function matchesPrefix(version, spec) {
|
|
73
99
|
if (spec === "" || spec === "node" || spec === "stable") return true;
|
|
74
100
|
const parts = spec.split(".");
|
|
@@ -254,8 +280,17 @@ function javaEntry(env, probe) {
|
|
|
254
280
|
source: "missing"
|
|
255
281
|
};
|
|
256
282
|
}
|
|
257
|
-
/**
|
|
258
|
-
|
|
283
|
+
/**
|
|
284
|
+
* The Node version pinned by `.nvmrc`, `.node-version`, `.tool-versions` or `package.json`'s `volta.node` in `root`,
|
|
285
|
+
* or else in the nearest directory above it up to `top`.
|
|
286
|
+
*/
|
|
287
|
+
function projectNodePin(root, probe = defaultToolchainProbe(), top = root) {
|
|
288
|
+
for (let dir = root;; dir = dirname(dir)) {
|
|
289
|
+
const pin = nodePinIn(dir, probe);
|
|
290
|
+
if (pin || dir === top || dirname(dir) === dir) return pin;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function nodePinIn(root, probe) {
|
|
259
294
|
for (const file of [".nvmrc", ".node-version"]) {
|
|
260
295
|
const line = probe.read(join(root, file))?.split("\n").map((text) => text.trim()).find((text) => text && !text.startsWith("#"));
|
|
261
296
|
if (line) return {
|
|
@@ -275,52 +310,78 @@ function projectNodePin(root, probe = defaultToolchainProbe()) {
|
|
|
275
310
|
file: "package.json"
|
|
276
311
|
} : null;
|
|
277
312
|
}
|
|
313
|
+
/** A pin's version spec, with an `lts/...` pin resolved through nvm's aliases, or null when nvm cannot resolve it. */
|
|
314
|
+
function resolveNodePinSpec(spec, env, probe = defaultToolchainProbe()) {
|
|
315
|
+
if (!spec.startsWith("lts/")) return spec;
|
|
316
|
+
const resolved = nvmAlias(nvmDir(env, probe), spec, probe);
|
|
317
|
+
return resolved.startsWith("lts/") ? null : resolved;
|
|
318
|
+
}
|
|
278
319
|
/**
|
|
279
|
-
* The `bin` directory of an installed Node
|
|
280
|
-
*
|
|
281
|
-
*
|
|
320
|
+
* The `bin` directory of an installed Node for the pin `projectNodePin` finds, from nvm, fnm, Volta, asdf, mise or a
|
|
321
|
+
* linked Homebrew `node` or `node@NN`, or null when the project pins none or no install fits. `match` is `exact` for an
|
|
322
|
+
* install the pin names. When none is, it is `major` for the newest install of the pinned major that is not older than
|
|
323
|
+
* the pinned version, since Homebrew cannot install a chosen patch release. An `lts/...` pin resolves through
|
|
324
|
+
* `resolveNodePinSpec`.
|
|
282
325
|
*/
|
|
283
|
-
function projectNodeBin(root, env, probe = defaultToolchainProbe()) {
|
|
284
|
-
const pin = projectNodePin(root, probe);
|
|
326
|
+
function projectNodeBin(root, env, probe = defaultToolchainProbe(), top = root) {
|
|
327
|
+
const pin = projectNodePin(root, probe, top);
|
|
285
328
|
if (!pin) return null;
|
|
329
|
+
const spec = resolveNodePinSpec(pin.spec, env, probe);
|
|
330
|
+
if (!spec) return null;
|
|
286
331
|
const nvm = nvmDir(env, probe);
|
|
287
|
-
const
|
|
288
|
-
const
|
|
332
|
+
const asdf = join(env.ASDF_DATA_DIR || join(probe.home, ".asdf"), "installs", "nodejs");
|
|
333
|
+
const groups = [
|
|
289
334
|
{
|
|
290
335
|
dir: join(nvm, "versions", "node"),
|
|
291
336
|
bin: (name) => join(nvm, "versions", "node", name, "bin")
|
|
292
337
|
},
|
|
293
|
-
{
|
|
294
|
-
dir: join(
|
|
295
|
-
bin: (name) => join(
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
dir: join(probe.home, "Library", "Application Support", "fnm", "node-versions"),
|
|
299
|
-
bin: (name) => join(probe.home, "Library", "Application Support", "fnm", "node-versions", name, "installation", "bin")
|
|
300
|
-
},
|
|
338
|
+
...[join(probe.home, ".local", "share", "fnm"), join(probe.home, "Library", "Application Support", "fnm")].map((fnm) => ({
|
|
339
|
+
dir: join(fnm, "node-versions"),
|
|
340
|
+
bin: (name) => join(fnm, "node-versions", name, "installation", "bin")
|
|
341
|
+
})),
|
|
301
342
|
{
|
|
302
343
|
dir: join(probe.home, ".volta", "tools", "image", "node"),
|
|
303
344
|
bin: (name) => join(probe.home, ".volta", "tools", "image", "node", name, "bin")
|
|
304
345
|
},
|
|
305
346
|
{
|
|
306
|
-
dir:
|
|
307
|
-
bin: (name) => join(
|
|
347
|
+
dir: asdf,
|
|
348
|
+
bin: (name) => join(asdf, name, "bin")
|
|
308
349
|
},
|
|
309
350
|
{
|
|
310
351
|
dir: join(probe.home, ".local", "share", "mise", "installs", "node"),
|
|
311
352
|
bin: (name) => join(probe.home, ".local", "share", "mise", "installs", "node", name, "bin")
|
|
312
353
|
}
|
|
313
|
-
]
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
354
|
+
].map(({ dir, bin }) => probe.list(dir).map((name) => ({
|
|
355
|
+
name,
|
|
356
|
+
bin: bin(name)
|
|
357
|
+
})));
|
|
358
|
+
groups.push(HOMEBREW_PREFIXES.flatMap((prefix) => probe.list(join(prefix, "opt")).filter((keg) => /^node(@\d+)?$/.test(keg)).map((keg) => ({
|
|
359
|
+
name: basename(probe.link(join(prefix, "opt", keg)) ?? ""),
|
|
360
|
+
bin: join(prefix, "opt", keg, "bin")
|
|
361
|
+
}))));
|
|
362
|
+
const installs = groups.map((group) => group.filter(({ bin }) => probe.isFile(join(bin, "node"))));
|
|
363
|
+
const found = (install, match) => ({
|
|
364
|
+
bin: install.bin,
|
|
365
|
+
version: install.name.replace(/^v/, "").replace(/_\d+$/, ""),
|
|
366
|
+
pin: pin.file,
|
|
367
|
+
spec,
|
|
368
|
+
match
|
|
369
|
+
});
|
|
370
|
+
for (const group of installs) {
|
|
371
|
+
const name = newestMatching(group.map((install) => install.name), spec);
|
|
372
|
+
const install = group.find((candidate) => candidate.name === name);
|
|
373
|
+
if (install) return found(install, "exact");
|
|
374
|
+
}
|
|
375
|
+
let fallback = null;
|
|
376
|
+
for (const install of installs.flat()) {
|
|
377
|
+
const version = parseVersion(install.name);
|
|
378
|
+
if (!version || !meetsNodePinMajor(install.name, spec)) continue;
|
|
379
|
+
if (!fallback || compareVersions(version, fallback.version) > 0) fallback = {
|
|
380
|
+
install,
|
|
381
|
+
version
|
|
321
382
|
};
|
|
322
383
|
}
|
|
323
|
-
return null;
|
|
384
|
+
return fallback ? found(fallback.install, "major") : null;
|
|
324
385
|
}
|
|
325
386
|
//#endregion
|
|
326
|
-
export { defaultNodeBin, defaultToolchainProbe, discoverToolchain, projectNodeBin, projectNodePin, satisfiesNodePin };
|
|
387
|
+
export { defaultNodeBin, defaultToolchainProbe, discoverToolchain, meetsNodePinMajor, projectNodeBin, projectNodePin, resolveNodePinSpec, satisfiesNodePin };
|