@4pm/cli 0.2.1 → 0.3.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/dist/index.js +95 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3930,7 +3930,7 @@ MCowBQYDK2VwAyEARlfzjaFhe5bhRrMp/ZuH6sVqg/S7f8B1dliuF21iDTw=
|
|
|
3930
3930
|
`;
|
|
3931
3931
|
|
|
3932
3932
|
// src/version.ts
|
|
3933
|
-
var CLI_VERSION = "0.
|
|
3933
|
+
var CLI_VERSION = "0.3.0";
|
|
3934
3934
|
|
|
3935
3935
|
// src/core/update.ts
|
|
3936
3936
|
function compareSemver(a, b) {
|
|
@@ -3978,6 +3978,27 @@ async function updateViaDownload(tarballUrl, checksum, signature) {
|
|
|
3978
3978
|
stdio: "inherit"
|
|
3979
3979
|
});
|
|
3980
3980
|
}
|
|
3981
|
+
async function updateToLatest(serverUrl) {
|
|
3982
|
+
const meta = await fetchCliVersion(serverUrl);
|
|
3983
|
+
if (compareSemver(CLI_VERSION, meta.latest) >= 0) {
|
|
3984
|
+
return { action: "already-latest", version: CLI_VERSION };
|
|
3985
|
+
}
|
|
3986
|
+
console.log(`Updating ${CLI_VERSION} \u2192 ${meta.latest}\u2026`);
|
|
3987
|
+
try {
|
|
3988
|
+
if (installedViaNpm()) {
|
|
3989
|
+
updateViaNpm(meta.latest);
|
|
3990
|
+
} else {
|
|
3991
|
+
await updateViaDownload(
|
|
3992
|
+
meta.source.tarballUrl,
|
|
3993
|
+
meta.source.checksum,
|
|
3994
|
+
meta.source.signature
|
|
3995
|
+
);
|
|
3996
|
+
}
|
|
3997
|
+
return { action: "updated", version: meta.latest };
|
|
3998
|
+
} catch (err) {
|
|
3999
|
+
return { action: "failed", error: String(err) };
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
3981
4002
|
async function checkAndUpdate(serverUrl, autoUpdate) {
|
|
3982
4003
|
let meta;
|
|
3983
4004
|
try {
|
|
@@ -4814,6 +4835,7 @@ async function addProject(payload, onProgress) {
|
|
|
4814
4835
|
|
|
4815
4836
|
// src/core/ws-client.ts
|
|
4816
4837
|
var HEARTBEAT_MS = 3e4;
|
|
4838
|
+
var MAX_HASHCODE_INVALID_RETRIES = 5;
|
|
4817
4839
|
var CLOSE_DRAINING = 4001;
|
|
4818
4840
|
var OFFLINE_BUFFER_MAX_BYTES = 512 * 1024;
|
|
4819
4841
|
var WsClient = class {
|
|
@@ -4838,16 +4860,32 @@ var WsClient = class {
|
|
|
4838
4860
|
* Main lifecycle: connect + reconnect backoff until revoked.
|
|
4839
4861
|
*/
|
|
4840
4862
|
async run() {
|
|
4863
|
+
let hashcodeInvalidStreak = 0;
|
|
4841
4864
|
for (let attempt = 0; !this.stopped; attempt++) {
|
|
4842
4865
|
try {
|
|
4843
4866
|
await this.connectOnce();
|
|
4844
4867
|
attempt = 0;
|
|
4868
|
+
hashcodeInvalidStreak = 0;
|
|
4845
4869
|
} catch (err) {
|
|
4846
|
-
if (err instanceof CliApiError
|
|
4847
|
-
|
|
4848
|
-
|
|
4870
|
+
if (err instanceof CliApiError) {
|
|
4871
|
+
if (["HASHCODE_EXPIRED", "LINK_REVOKED"].includes(err.errorCode)) {
|
|
4872
|
+
this.logout(err.errorCode);
|
|
4873
|
+
return;
|
|
4874
|
+
}
|
|
4875
|
+
if (err.errorCode === "HASHCODE_INVALID") {
|
|
4876
|
+
if (++hashcodeInvalidStreak > MAX_HASHCODE_INVALID_RETRIES) {
|
|
4877
|
+
this.logout(err.errorCode);
|
|
4878
|
+
return;
|
|
4879
|
+
}
|
|
4880
|
+
console.warn(
|
|
4881
|
+
`Token request rejected (HASHCODE_INVALID) \u2014 retrying (${hashcodeInvalidStreak}/${MAX_HASHCODE_INVALID_RETRIES}).`
|
|
4882
|
+
);
|
|
4883
|
+
} else {
|
|
4884
|
+
console.error(`Connection error: ${err}`);
|
|
4885
|
+
}
|
|
4886
|
+
} else {
|
|
4887
|
+
console.error(`Connection error: ${err}`);
|
|
4849
4888
|
}
|
|
4850
|
-
console.error(`Connection error: ${err}`);
|
|
4851
4889
|
}
|
|
4852
4890
|
if (this.stopped) return;
|
|
4853
4891
|
const wait = backoffJitterMs(Math.min(attempt, 6), 1e3, 6e4);
|
|
@@ -5176,6 +5214,47 @@ function runUnlink(profileDir2, profileName) {
|
|
|
5176
5214
|
console.log("\u2714 Deleted .cre \u2014 revoke the server-side link at web /machines.");
|
|
5177
5215
|
}
|
|
5178
5216
|
|
|
5217
|
+
// src/commands/update.ts
|
|
5218
|
+
async function runUpdate(profileDir2, profileName, serverUrlFlag) {
|
|
5219
|
+
const serverUrl = (serverUrlFlag ?? readCredential(profileDir2, profileName)?.serverUrl ?? process.env.FOURPM_SERVER ?? "http://localhost:3001").replace(/\/$/, "");
|
|
5220
|
+
let result;
|
|
5221
|
+
try {
|
|
5222
|
+
result = await updateToLatest(serverUrl);
|
|
5223
|
+
} catch (err) {
|
|
5224
|
+
console.error(`Could not check for updates: ${err}`);
|
|
5225
|
+
process.exitCode = 1;
|
|
5226
|
+
return;
|
|
5227
|
+
}
|
|
5228
|
+
switch (result.action) {
|
|
5229
|
+
case "already-latest":
|
|
5230
|
+
console.log(`Already up to date (${result.version}).`);
|
|
5231
|
+
break;
|
|
5232
|
+
case "updated":
|
|
5233
|
+
console.log(`\u2714 Updated to ${result.version}. Run \`4pm start\` to reconnect.`);
|
|
5234
|
+
break;
|
|
5235
|
+
case "failed":
|
|
5236
|
+
console.error(`Update failed: ${result.error}`);
|
|
5237
|
+
process.exitCode = 1;
|
|
5238
|
+
break;
|
|
5239
|
+
}
|
|
5240
|
+
}
|
|
5241
|
+
|
|
5242
|
+
// src/commands/version.ts
|
|
5243
|
+
async function runVersion(profileDir2, profileName, serverUrlFlag) {
|
|
5244
|
+
console.log(`4pm cli ${CLI_VERSION}`);
|
|
5245
|
+
const serverUrl = serverUrlFlag ?? readCredential(profileDir2, profileName)?.serverUrl ?? process.env.FOURPM_SERVER;
|
|
5246
|
+
if (!serverUrl) return;
|
|
5247
|
+
try {
|
|
5248
|
+
const meta = await fetchCliVersion(serverUrl.replace(/\/$/, ""));
|
|
5249
|
+
const outdated = compareSemver(CLI_VERSION, meta.latest) < 0;
|
|
5250
|
+
const hint = outdated ? " (update available \u2014 run `4pm update`)" : " (up to date)";
|
|
5251
|
+
console.log(`latest: ${meta.latest}${hint}`);
|
|
5252
|
+
console.log(`minSupported: ${meta.minSupported}`);
|
|
5253
|
+
} catch (err) {
|
|
5254
|
+
console.warn(`Could not reach the server for the latest version: ${err}`);
|
|
5255
|
+
}
|
|
5256
|
+
}
|
|
5257
|
+
|
|
5179
5258
|
// src/index.ts
|
|
5180
5259
|
function flagValue(args, name) {
|
|
5181
5260
|
const index = args.indexOf(`--${name}`);
|
|
@@ -5197,6 +5276,15 @@ async function main() {
|
|
|
5197
5276
|
case "unlink":
|
|
5198
5277
|
runUnlink(dir, profileName);
|
|
5199
5278
|
break;
|
|
5279
|
+
case "version":
|
|
5280
|
+
case "--version":
|
|
5281
|
+
case "-v":
|
|
5282
|
+
await runVersion(dir, profileName, flagValue(rest, "server"));
|
|
5283
|
+
break;
|
|
5284
|
+
case "update":
|
|
5285
|
+
case "upgrade":
|
|
5286
|
+
await runUpdate(dir, profileName, flagValue(rest, "server"));
|
|
5287
|
+
break;
|
|
5200
5288
|
default:
|
|
5201
5289
|
console.log(
|
|
5202
5290
|
[
|
|
@@ -5206,6 +5294,8 @@ async function main() {
|
|
|
5206
5294
|
" 4pm [--profile <name>] link [--server URL] Pair with the server (hashcode 1\u21922\u21923)",
|
|
5207
5295
|
" 4pm [--profile <name>] start Connect WS, receive commands from the server",
|
|
5208
5296
|
" 4pm [--profile <name>] unlink Delete the local credential (.cre)",
|
|
5297
|
+
" 4pm version [--server URL] Show the installed version (+ latest from the server)",
|
|
5298
|
+
" 4pm update [--server URL] Update to the latest version now",
|
|
5209
5299
|
"",
|
|
5210
5300
|
"Without --profile \u21D2 the `default` profile (ADR-0014)."
|
|
5211
5301
|
].join("\n")
|