@qpfai/pf-gate-cli 1.0.14 → 1.0.16
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.
|
Binary file
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-02-16T22:
|
|
3
|
+
"generatedAt": "2026-02-16T22:39:32.770Z",
|
|
4
4
|
"pythonPackage": "persons-field",
|
|
5
5
|
"pythonPackageVersion": "1.0.0",
|
|
6
6
|
"wheel": "persons_field-1.0.0-py3-none-any.whl",
|
|
7
|
-
"sha256": "
|
|
7
|
+
"sha256": "10cbc5c716202bace88f1b20f3a671030cca7c3bbc45b470ba5f52e64e188833"
|
|
8
8
|
}
|
package/lib/main.mjs
CHANGED
|
@@ -16,6 +16,8 @@ const INSTALL_STATE_NAME = "install-state.json";
|
|
|
16
16
|
const PYTHON_CANDIDATES = ["python3.13", "python3", "python"];
|
|
17
17
|
const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
|
|
18
18
|
const UPDATE_CHECK_TIMEOUT_MS = 6000;
|
|
19
|
+
const UPDATE_INSTALL_MAX_RETRIES = 10;
|
|
20
|
+
const UPDATE_INSTALL_RETRY_MS = 3000;
|
|
19
21
|
const SPHERE_FRAMES = ["🌐", "🌍", "🌎", "🌏"];
|
|
20
22
|
|
|
21
23
|
function isWindows() {
|
|
@@ -117,6 +119,10 @@ function runCapture(command, args) {
|
|
|
117
119
|
};
|
|
118
120
|
}
|
|
119
121
|
|
|
122
|
+
function sleep(ms) {
|
|
123
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
124
|
+
}
|
|
125
|
+
|
|
120
126
|
function startSphereSpinner(message) {
|
|
121
127
|
if (!process.stdout.isTTY) {
|
|
122
128
|
return (_doneMessage) => {};
|
|
@@ -327,11 +333,14 @@ function canPrompt() {
|
|
|
327
333
|
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
328
334
|
}
|
|
329
335
|
|
|
330
|
-
async function promptYesNo(question, defaultYes = true) {
|
|
336
|
+
async function promptYesNo(question, defaultYes = true, promptSuffix = null) {
|
|
331
337
|
if (!canPrompt()) {
|
|
332
338
|
return false;
|
|
333
339
|
}
|
|
334
|
-
|
|
340
|
+
let prompt = defaultYes ? `${question} [Y/n] ` : `${question} [y/N] `;
|
|
341
|
+
if (typeof promptSuffix === "string" && promptSuffix.trim()) {
|
|
342
|
+
prompt = `${question} ${promptSuffix.trim()} `;
|
|
343
|
+
}
|
|
335
344
|
const rl = readline.createInterface({
|
|
336
345
|
input: process.stdin,
|
|
337
346
|
output: process.stdout,
|
|
@@ -347,6 +356,17 @@ async function promptYesNo(question, defaultYes = true) {
|
|
|
347
356
|
}
|
|
348
357
|
}
|
|
349
358
|
|
|
359
|
+
async function promptCliUpdate(metadata, latestVersion) {
|
|
360
|
+
if (!canPrompt()) {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
console.clear();
|
|
364
|
+
console.log(
|
|
365
|
+
`Update available: ${metadata.name} ${metadata.version} -> ${latestVersion}`
|
|
366
|
+
);
|
|
367
|
+
return promptYesNo("Install update now?", false, "[Y/N]");
|
|
368
|
+
}
|
|
369
|
+
|
|
350
370
|
function npmGlobalBinDir() {
|
|
351
371
|
const prefix = runCapture("npm", ["prefix", "-g"]);
|
|
352
372
|
if (!prefix.ok) {
|
|
@@ -386,8 +406,26 @@ function maybeHealBinCollision(output) {
|
|
|
386
406
|
return removed;
|
|
387
407
|
}
|
|
388
408
|
|
|
389
|
-
|
|
390
|
-
const
|
|
409
|
+
function isEtargetPublishRace(output) {
|
|
410
|
+
const text = String(output || "").toLowerCase();
|
|
411
|
+
return text.includes("code etarget") || text.includes("notarget no matching version");
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async function npmVersionExists(packageName, version, registry) {
|
|
415
|
+
const result = await spawnCapture(
|
|
416
|
+
"npm",
|
|
417
|
+
["view", `${packageName}@${version}`, "version", "--json", "--registry", registry],
|
|
418
|
+
{ encoding: "utf-8" }
|
|
419
|
+
);
|
|
420
|
+
if (result.error || (result.status ?? 1) !== 0) {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
const parsed = parseNpmViewVersion(String(result.stdout || "").trim());
|
|
424
|
+
return parsed === String(version || "").trim();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
async function installLatestCliPackage(packageName, targetVersion, registry) {
|
|
428
|
+
const args = ["i", "-g", `${packageName}@${targetVersion}`, "--registry", registry];
|
|
391
429
|
const runOnce = async () => {
|
|
392
430
|
const stop = startSphereSpinner("Installing PF Gate update...");
|
|
393
431
|
const result = await spawnCapture("npm", args, { encoding: "utf-8" });
|
|
@@ -399,22 +437,55 @@ async function installLatestCliPackage(packageName, registry) {
|
|
|
399
437
|
return result;
|
|
400
438
|
};
|
|
401
439
|
|
|
402
|
-
let
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
440
|
+
let attempts = 0;
|
|
441
|
+
let healedCollision = false;
|
|
442
|
+
let result = null;
|
|
443
|
+
|
|
444
|
+
while (attempts < UPDATE_INSTALL_MAX_RETRIES) {
|
|
445
|
+
attempts += 1;
|
|
446
|
+
const versionReady = await npmVersionExists(packageName, targetVersion, registry);
|
|
447
|
+
if (!versionReady) {
|
|
448
|
+
if (attempts < UPDATE_INSTALL_MAX_RETRIES) {
|
|
449
|
+
const delayMs = UPDATE_INSTALL_RETRY_MS * attempts;
|
|
450
|
+
const seconds = Math.ceil(delayMs / 1000);
|
|
451
|
+
const stopWait = startSphereSpinner(
|
|
452
|
+
`Waiting for ${packageName}@${targetVersion} to be available (${seconds}s)...`
|
|
453
|
+
);
|
|
454
|
+
await sleep(delayMs);
|
|
455
|
+
stopWait("✓ Retrying update install...");
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
406
460
|
|
|
407
|
-
const combined = `${String(result.stdout || "")}\n${String(result.stderr || "")}`;
|
|
408
|
-
if (maybeHealBinCollision(combined)) {
|
|
409
461
|
result = await runOnce();
|
|
410
462
|
if (!result.error && (result.status ?? 1) === 0) {
|
|
411
463
|
return true;
|
|
412
464
|
}
|
|
465
|
+
|
|
466
|
+
const combined = `${String(result.stdout || "")}\n${String(result.stderr || "")}`;
|
|
467
|
+
if (!healedCollision && maybeHealBinCollision(combined)) {
|
|
468
|
+
healedCollision = true;
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
if (attempts < UPDATE_INSTALL_MAX_RETRIES && isEtargetPublishRace(combined)) {
|
|
473
|
+
const delayMs = UPDATE_INSTALL_RETRY_MS * attempts;
|
|
474
|
+
const seconds = Math.ceil(delayMs / 1000);
|
|
475
|
+
const stopWait = startSphereSpinner(
|
|
476
|
+
`Waiting for npm registry propagation (${seconds}s)...`
|
|
477
|
+
);
|
|
478
|
+
await sleep(delayMs);
|
|
479
|
+
stopWait("✓ Retrying update install...");
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
break;
|
|
413
483
|
}
|
|
414
|
-
|
|
484
|
+
|
|
485
|
+
if (result && result.stdout) {
|
|
415
486
|
process.stdout.write(String(result.stdout));
|
|
416
487
|
}
|
|
417
|
-
if (result.stderr) {
|
|
488
|
+
if (result && result.stderr) {
|
|
418
489
|
process.stderr.write(String(result.stderr));
|
|
419
490
|
}
|
|
420
491
|
return false;
|
|
@@ -438,16 +509,13 @@ async function maybeOfferCliUpdate(metadata) {
|
|
|
438
509
|
debugUpdate(`up-to-date (latest=${latestVersion})`);
|
|
439
510
|
return false;
|
|
440
511
|
}
|
|
441
|
-
|
|
442
|
-
`Update available: ${metadata.name} ${metadata.version} -> ${latestVersion}`
|
|
443
|
-
);
|
|
444
|
-
const wantsUpdate = await promptYesNo("Install update now?", true);
|
|
512
|
+
const wantsUpdate = await promptCliUpdate(metadata, latestVersion);
|
|
445
513
|
if (!wantsUpdate) {
|
|
446
514
|
console.log(`Continue with ${metadata.version}.`);
|
|
447
515
|
return false;
|
|
448
516
|
}
|
|
449
517
|
console.log(`Updating ${metadata.name}...`);
|
|
450
|
-
const installed = await installLatestCliPackage(metadata.name, registry);
|
|
518
|
+
const installed = await installLatestCliPackage(metadata.name, latestVersion, registry);
|
|
451
519
|
if (!installed) {
|
|
452
520
|
console.log("Update failed. Continuing with current version.");
|
|
453
521
|
return false;
|