@timurproko/a1-install 0.2.4-dev.663 → 0.2.4-dev.664

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 (2) hide show
  1. package/bin/a1-install.js +36 -20
  2. package/package.json +1 -1
package/bin/a1-install.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { spawn } from "node:child_process";
4
4
  import { access, lstat, readFile, realpath } from "node:fs/promises";
5
- import { existsSync, realpathSync } from "node:fs";
5
+ import { lstatSync, realpathSync } from "node:fs";
6
6
  import { delimiter, dirname, isAbsolute, join, resolve } from "node:path";
7
7
  import { fileURLToPath, pathToFileURL } from "node:url";
8
8
 
@@ -197,29 +197,37 @@ class ProgressDisplay {
197
197
  }
198
198
  }
199
199
 
200
- function createDefaultProcessRunner(environment, platform) {
201
- const npmCli = resolveNpmCli(environment);
200
+ function createDefaultProcessRunner(environment) {
201
+ const npmCli = resolveInstallerNpmCli(environment);
202
202
  return {
203
+ npmCli,
203
204
  npm: async (args, callbacks = {}) => await runChild(process.execPath, [npmCli, ...args], { environment, ...callbacks }),
204
205
  node: async (entry, args, callbacks = {}) => await runChild(process.execPath, [entry, ...args], { environment, ...callbacks }),
205
206
  };
207
+ }
206
208
 
207
- function resolveNpmCli(env) {
208
- const declared = env.npm_execpath;
209
- if (declared) {
210
- const candidate = /npx-cli\.js$/iu.test(declared) ? resolve(dirname(declared), "npm-cli.js") : declared;
211
- if (existsSync(candidate)) return candidate;
212
- }
213
- for (const directory of String(env.PATH ?? "").split(delimiter)) {
214
- if (!directory) continue;
215
- const candidates = [
216
- resolve(directory, "node_modules", "npm", "bin", "npm-cli.js"),
217
- resolve(directory, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
218
- ];
219
- for (const candidate of candidates) if (existsSync(candidate)) return candidate;
220
- }
221
- throw new InstallationFailure("npm is unavailable");
209
+ /** Resolve one immutable npm JavaScript entry for installer work and delegated A1 recovery. */
210
+ export function resolveInstallerNpmCli(environment) {
211
+ const candidates = [];
212
+ const npmExecPathKey = Object.hasOwn(environment, "npm_execpath")
213
+ ? "npm_execpath"
214
+ : Object.keys(environment).find(key => key.toLowerCase() === "npm_execpath");
215
+ const declared = npmExecPathKey === undefined ? undefined : environment[npmExecPathKey];
216
+ if (declared) candidates.push(/npx-cli\.js$/iu.test(declared) ? resolve(dirname(declared), "npm-cli.js") : declared);
217
+ for (const directory of String(environment.PATH ?? "").split(delimiter)) {
218
+ if (!directory) continue;
219
+ candidates.push(
220
+ resolve(directory, "node_modules", "npm", "bin", "npm-cli.js"),
221
+ resolve(directory, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
222
+ );
222
223
  }
224
+ for (const candidate of candidates) {
225
+ try {
226
+ const canonical = realpathSync(candidate);
227
+ if (lstatSync(canonical).isFile()) return canonical;
228
+ } catch { /* Rationale: bounded candidates continue; no searched or shell fallback is accepted. */ }
229
+ }
230
+ throw new InstallationFailure("npm is unavailable");
223
231
  }
224
232
 
225
233
  export function consumeProcessLines(pending, chunk, callback) {
@@ -491,7 +499,7 @@ export async function runInstaller(argv, options = {}) {
491
499
  }
492
500
 
493
501
  const progress = options.progress ?? new ProgressDisplay(stdout, options.tty ?? stdout.isTTY === true, options.progressOptions);
494
- const runner = options.runner ?? createDefaultProcessRunner(environment, platform);
502
+ const runner = options.runner ?? createDefaultProcessRunner(environment);
495
503
  let activeChild = null;
496
504
  let killTimer = null;
497
505
  let cancelled = options.signal?.aborted === true;
@@ -558,7 +566,15 @@ export async function runInstaller(argv, options = {}) {
558
566
  throw new InstallationFailure("existing installation ownership could not be verified", error instanceof Error ? error.message : String(error));
559
567
  }
560
568
  progress.set(24, "Installing", 90);
561
- const updateResult = await runner.node(cli, updateArguments(parsed.target, targetVersion), { onChild: setActiveChild });
569
+ const npmCli = typeof runner.npmCli === "string" ? runner.npmCli : null;
570
+ const delegatedEnvironment = npmCli === null ? environment : {
571
+ ...Object.fromEntries(Object.entries(environment).filter(([key]) => key.toLowerCase() !== "npm_execpath")),
572
+ npm_execpath: npmCli,
573
+ };
574
+ const updateResult = await runner.node(cli, updateArguments(parsed.target, targetVersion), {
575
+ onChild: setActiveChild,
576
+ environment: delegatedEnvironment,
577
+ });
562
578
  setActiveChild(null);
563
579
  if (cancelled) throw new InstallationCancelled();
564
580
  if (updateResult.code !== 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurproko/a1-install",
3
- "version": "0.2.4-dev.663",
3
+ "version": "0.2.4-dev.664",
4
4
  "description": "Dependency-free installer for a1",
5
5
  "type": "module",
6
6
  "bin": {