@rudderhq/cli 0.2.1-canary.3 → 0.2.1-canary.5
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 +128 -17
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6178,6 +6178,70 @@ var DESKTOP_APP_NAME = "Rudder";
|
|
|
6178
6178
|
var DESKTOP_METADATA_FILE = ".rudder-desktop-install.json";
|
|
6179
6179
|
var DESKTOP_CHECKSUM_ASSET_NAME = "SHASUMS256.txt";
|
|
6180
6180
|
var GITHUB_ASSET_DOWNLOAD_ACCEPT = "application/octet-stream";
|
|
6181
|
+
function normalizeProgressTotal(totalBytes) {
|
|
6182
|
+
return typeof totalBytes === "number" && Number.isFinite(totalBytes) && totalBytes > 0 ? totalBytes : null;
|
|
6183
|
+
}
|
|
6184
|
+
function writeDesktopProgress(event) {
|
|
6185
|
+
const payload = {
|
|
6186
|
+
source: "rudder-desktop-update",
|
|
6187
|
+
...event,
|
|
6188
|
+
at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6189
|
+
};
|
|
6190
|
+
try {
|
|
6191
|
+
process.stdout.write(`${JSON.stringify(payload)}
|
|
6192
|
+
`);
|
|
6193
|
+
} catch (error) {
|
|
6194
|
+
const code = typeof error === "object" && error && "code" in error ? String(error.code) : "";
|
|
6195
|
+
if (code !== "EPIPE") throw error;
|
|
6196
|
+
}
|
|
6197
|
+
}
|
|
6198
|
+
function desktopDownloadPhase(label) {
|
|
6199
|
+
return label.toLowerCase().includes("shasums") ? "downloading_checksums" : "downloading_asset";
|
|
6200
|
+
}
|
|
6201
|
+
function createDesktopProgressFactory() {
|
|
6202
|
+
return (label) => {
|
|
6203
|
+
const phase = desktopDownloadPhase(label);
|
|
6204
|
+
let latestReceivedBytes = 0;
|
|
6205
|
+
let latestTotalBytes = null;
|
|
6206
|
+
function emitByteProgress(message, receivedBytes, totalBytes) {
|
|
6207
|
+
const total = normalizeProgressTotal(totalBytes);
|
|
6208
|
+
writeDesktopProgress({
|
|
6209
|
+
phase,
|
|
6210
|
+
message,
|
|
6211
|
+
transferredBytes: Math.max(0, receivedBytes),
|
|
6212
|
+
...total === null ? {} : {
|
|
6213
|
+
totalBytes: total,
|
|
6214
|
+
percent: Math.max(0, Math.min(100, Math.floor(Math.max(0, receivedBytes) / total * 100)))
|
|
6215
|
+
}
|
|
6216
|
+
});
|
|
6217
|
+
}
|
|
6218
|
+
return {
|
|
6219
|
+
start(totalBytes) {
|
|
6220
|
+
latestReceivedBytes = 0;
|
|
6221
|
+
latestTotalBytes = totalBytes;
|
|
6222
|
+
emitByteProgress(label, 0, totalBytes);
|
|
6223
|
+
},
|
|
6224
|
+
update(receivedBytes, totalBytes) {
|
|
6225
|
+
latestReceivedBytes = receivedBytes;
|
|
6226
|
+
latestTotalBytes = totalBytes;
|
|
6227
|
+
emitByteProgress(label, receivedBytes, totalBytes);
|
|
6228
|
+
},
|
|
6229
|
+
finish(receivedBytes = latestReceivedBytes, totalBytes = latestTotalBytes) {
|
|
6230
|
+
latestReceivedBytes = receivedBytes;
|
|
6231
|
+
latestTotalBytes = totalBytes;
|
|
6232
|
+
emitByteProgress(`${label} complete`, receivedBytes, totalBytes);
|
|
6233
|
+
},
|
|
6234
|
+
fail() {
|
|
6235
|
+
writeDesktopProgress({
|
|
6236
|
+
phase,
|
|
6237
|
+
message: `${label} failed`,
|
|
6238
|
+
transferredBytes: Math.max(0, latestReceivedBytes),
|
|
6239
|
+
error: `${label} failed`
|
|
6240
|
+
});
|
|
6241
|
+
}
|
|
6242
|
+
};
|
|
6243
|
+
};
|
|
6244
|
+
}
|
|
6181
6245
|
function resolveCurrentCliVersion(env = process.env) {
|
|
6182
6246
|
const version = resolveCliVersion(import.meta.url, env);
|
|
6183
6247
|
return version === "0.0.0" ? "latest" : version;
|
|
@@ -6480,9 +6544,25 @@ function runChecked(command, args, options = {}) {
|
|
|
6480
6544
|
const output = [result.stdout, result.stderr].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n").trim();
|
|
6481
6545
|
throw new Error(`${command} ${args.join(" ")} failed${output ? `: ${output}` : ""}`);
|
|
6482
6546
|
}
|
|
6547
|
+
function formatCommandFailure(command, args, stdout, stderr) {
|
|
6548
|
+
const output = [stdout, stderr].filter((value) => typeof value === "string" && value.trim().length > 0).join("\n").trim();
|
|
6549
|
+
return `${command} ${args.join(" ")} failed${output ? `: ${output}` : ""}`;
|
|
6550
|
+
}
|
|
6483
6551
|
function powershellQuote(value) {
|
|
6484
6552
|
return `'${value.replaceAll("'", "''")}'`;
|
|
6485
6553
|
}
|
|
6554
|
+
function buildWindowsZipExtractCommand(zipPath, outputDir) {
|
|
6555
|
+
return { command: "tar.exe", args: ["-xf", zipPath, "-C", outputDir] };
|
|
6556
|
+
}
|
|
6557
|
+
function buildWindowsRobocopyMirrorCommand(sourcePath, destinationPath) {
|
|
6558
|
+
return {
|
|
6559
|
+
command: "robocopy.exe",
|
|
6560
|
+
args: [sourcePath, destinationPath, "/MIR", "/R:2", "/W:1", "/NFL", "/NDL", "/NJH", "/NJS", "/NP"]
|
|
6561
|
+
};
|
|
6562
|
+
}
|
|
6563
|
+
function isSuccessfulRobocopyExitCode(status) {
|
|
6564
|
+
return typeof status === "number" && status >= 0 && status <= 7;
|
|
6565
|
+
}
|
|
6486
6566
|
async function extractZip(zipPath, outputDir, target) {
|
|
6487
6567
|
await rm(outputDir, { recursive: true, force: true });
|
|
6488
6568
|
await mkdir2(outputDir, { recursive: true });
|
|
@@ -6491,13 +6571,8 @@ async function extractZip(zipPath, outputDir, target) {
|
|
|
6491
6571
|
return;
|
|
6492
6572
|
}
|
|
6493
6573
|
if (target.platform === "windows") {
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
"-ExecutionPolicy",
|
|
6497
|
-
"Bypass",
|
|
6498
|
-
"-Command",
|
|
6499
|
-
`Expand-Archive -LiteralPath ${powershellQuote(zipPath)} -DestinationPath ${powershellQuote(outputDir)} -Force`
|
|
6500
|
-
]);
|
|
6574
|
+
const command = buildWindowsZipExtractCommand(zipPath, outputDir);
|
|
6575
|
+
runChecked(command.command, command.args);
|
|
6501
6576
|
return;
|
|
6502
6577
|
}
|
|
6503
6578
|
throw new Error(`Zip assets are not supported for ${target.platform}.`);
|
|
@@ -6643,6 +6718,16 @@ async function installPortableDesktop(installerPath, paths, target) {
|
|
|
6643
6718
|
}
|
|
6644
6719
|
}
|
|
6645
6720
|
async function copyPortableAppBundle(sourcePath, destinationPath) {
|
|
6721
|
+
if (process.platform === "win32") {
|
|
6722
|
+
await mkdir2(destinationPath, { recursive: true });
|
|
6723
|
+
const command = buildWindowsRobocopyMirrorCommand(sourcePath, destinationPath);
|
|
6724
|
+
const result = spawnSync3(command.command, command.args, {
|
|
6725
|
+
encoding: "utf8",
|
|
6726
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
6727
|
+
});
|
|
6728
|
+
if (isSuccessfulRobocopyExitCode(result.status)) return;
|
|
6729
|
+
throw new Error(formatCommandFailure(command.command, command.args, result.stdout, result.stderr));
|
|
6730
|
+
}
|
|
6646
6731
|
await cp(sourcePath, destinationPath, { recursive: true, verbatimSymlinks: true });
|
|
6647
6732
|
}
|
|
6648
6733
|
async function removeMacQuarantine(paths, target) {
|
|
@@ -6730,15 +6815,28 @@ async function writeInstallMetadata(paths, releaseTag, assetName, assetChecksum)
|
|
|
6730
6815
|
await writeFile2(paths.metadataPath, `${JSON.stringify(metadata, null, 2)}
|
|
6731
6816
|
`, "utf8");
|
|
6732
6817
|
}
|
|
6733
|
-
async function runStartPhase(message, successMessage, task) {
|
|
6818
|
+
async function runStartPhase(message, successMessage, task, progressPhase) {
|
|
6819
|
+
if (progressPhase) {
|
|
6820
|
+
writeDesktopProgress({ phase: progressPhase, message });
|
|
6821
|
+
}
|
|
6734
6822
|
const spinner3 = p13.spinner();
|
|
6735
6823
|
spinner3.start(message);
|
|
6736
6824
|
try {
|
|
6737
6825
|
const result = await task();
|
|
6738
6826
|
spinner3.stop(successMessage);
|
|
6827
|
+
if (progressPhase) {
|
|
6828
|
+
writeDesktopProgress({ phase: progressPhase, message: successMessage });
|
|
6829
|
+
}
|
|
6739
6830
|
return result;
|
|
6740
6831
|
} catch (error) {
|
|
6741
6832
|
spinner3.stop(pc8.red(`${message} failed.`));
|
|
6833
|
+
if (progressPhase) {
|
|
6834
|
+
writeDesktopProgress({
|
|
6835
|
+
phase: "failed",
|
|
6836
|
+
message: `${message} failed.`,
|
|
6837
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6838
|
+
});
|
|
6839
|
+
}
|
|
6742
6840
|
throw error;
|
|
6743
6841
|
}
|
|
6744
6842
|
}
|
|
@@ -6749,6 +6847,12 @@ async function startCommand(opts) {
|
|
|
6749
6847
|
const repo = opts.repo?.trim() || DEFAULT_DESKTOP_RELEASE_REPO;
|
|
6750
6848
|
const version = opts.targetVersion?.trim() || opts.version?.trim() || resolveCurrentCliVersion();
|
|
6751
6849
|
const dryRun = opts.dryRun === true;
|
|
6850
|
+
const desktopProgressJson = opts.desktopProgressJson === true;
|
|
6851
|
+
if (desktopProgressJson) {
|
|
6852
|
+
process.stdout.on("error", (error) => {
|
|
6853
|
+
if (error.code !== "EPIPE") throw error;
|
|
6854
|
+
});
|
|
6855
|
+
}
|
|
6752
6856
|
if (!installCli && !installDesktop && !installRuntime) {
|
|
6753
6857
|
throw new Error("Nothing to start. Remove --no-cli, --no-runtime, or --no-desktop.");
|
|
6754
6858
|
}
|
|
@@ -6822,13 +6926,14 @@ async function startCommand(opts) {
|
|
|
6822
6926
|
return;
|
|
6823
6927
|
}
|
|
6824
6928
|
const directReleaseVersion = resolveDesktopReleaseVersion(tag);
|
|
6825
|
-
const progressFactory = createByteProgress;
|
|
6929
|
+
const progressFactory = desktopProgressJson ? createDesktopProgressFactory() : createByteProgress;
|
|
6826
6930
|
let release = null;
|
|
6827
6931
|
try {
|
|
6828
6932
|
release = await runStartPhase(
|
|
6829
6933
|
"Resolving Desktop release...",
|
|
6830
6934
|
"Desktop release resolved.",
|
|
6831
|
-
() => fetchGithubRelease(repo, tag)
|
|
6935
|
+
() => fetchGithubRelease(repo, tag),
|
|
6936
|
+
desktopProgressJson ? "resolving_release" : null
|
|
6832
6937
|
);
|
|
6833
6938
|
} catch (error) {
|
|
6834
6939
|
if (!directReleaseVersion) throw error;
|
|
@@ -6856,24 +6961,28 @@ async function startCommand(opts) {
|
|
|
6856
6961
|
async () => {
|
|
6857
6962
|
await removeMacQuarantine(installPaths, target);
|
|
6858
6963
|
await createPlatformLaunchers(installPaths, target);
|
|
6859
|
-
}
|
|
6964
|
+
},
|
|
6965
|
+
desktopProgressJson ? "preparing_restart" : null
|
|
6860
6966
|
);
|
|
6861
6967
|
} else {
|
|
6862
6968
|
const installerPath = await downloadAsset(asset, outputDir, progressFactory);
|
|
6863
6969
|
const checksum = await runStartPhase(
|
|
6864
6970
|
"Verifying Desktop checksum...",
|
|
6865
6971
|
`Verified ${pc8.cyan(path11.basename(installerPath))}.`,
|
|
6866
|
-
() => assertChecksumMatch(installerPath, expectedChecksum)
|
|
6972
|
+
() => assertChecksumMatch(installerPath, expectedChecksum),
|
|
6973
|
+
desktopProgressJson ? "verifying_checksum" : null
|
|
6867
6974
|
);
|
|
6868
6975
|
await runStartPhase(
|
|
6869
6976
|
"Replacing existing Rudder Desktop if needed...",
|
|
6870
6977
|
"Existing Desktop install is ready for replacement.",
|
|
6871
|
-
() => prepareForDesktopReplace(installPaths, target, { waitForActiveRuns: opts.waitForActiveRuns === true })
|
|
6978
|
+
() => prepareForDesktopReplace(installPaths, target, { waitForActiveRuns: opts.waitForActiveRuns === true }),
|
|
6979
|
+
desktopProgressJson ? opts.waitForActiveRuns === true ? "waiting_for_active_runs" : "preparing_restart" : null
|
|
6872
6980
|
);
|
|
6873
6981
|
await runStartPhase(
|
|
6874
6982
|
"Installing portable Desktop app...",
|
|
6875
6983
|
`Installed Rudder Desktop to ${pc8.cyan(installPaths.appPath)}.`,
|
|
6876
|
-
() => installPortableDesktop(installerPath, installPaths, target)
|
|
6984
|
+
() => installPortableDesktop(installerPath, installPaths, target),
|
|
6985
|
+
desktopProgressJson ? "preparing_restart" : null
|
|
6877
6986
|
);
|
|
6878
6987
|
await runStartPhase(
|
|
6879
6988
|
"Preparing Desktop launchers...",
|
|
@@ -6881,7 +6990,8 @@ async function startCommand(opts) {
|
|
|
6881
6990
|
async () => {
|
|
6882
6991
|
await removeMacQuarantine(installPaths, target);
|
|
6883
6992
|
await createPlatformLaunchers(installPaths, target);
|
|
6884
|
-
}
|
|
6993
|
+
},
|
|
6994
|
+
desktopProgressJson ? "preparing_restart" : null
|
|
6885
6995
|
);
|
|
6886
6996
|
await writeInstallMetadata(installPaths, releaseTag, asset.name, checksum);
|
|
6887
6997
|
}
|
|
@@ -6889,7 +6999,8 @@ async function startCommand(opts) {
|
|
|
6889
6999
|
await runStartPhase(
|
|
6890
7000
|
"Launching Rudder Desktop...",
|
|
6891
7001
|
"Rudder Desktop launched.",
|
|
6892
|
-
() => launchDesktop(installPaths, target)
|
|
7002
|
+
() => launchDesktop(installPaths, target),
|
|
7003
|
+
desktopProgressJson ? "closing" : null
|
|
6893
7004
|
);
|
|
6894
7005
|
}
|
|
6895
7006
|
}
|
|
@@ -11444,7 +11555,7 @@ function createProgram() {
|
|
|
11444
11555
|
});
|
|
11445
11556
|
loadRudderEnvFile(options.config);
|
|
11446
11557
|
});
|
|
11447
|
-
program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
|
|
11558
|
+
program.command("start").description("Start Rudder Desktop and prepare the matching persistent CLI").option("--no-cli", "Skip persistent CLI installation").option("--no-runtime", "Skip Rudder runtime installation").option("--no-desktop", "Skip desktop app installation").option("--version <version>", "Rudder version to start (default: current CLI version)").option("--target-version <version>", "Rudder version to start; avoids the root CLI version flag").option("--repo <owner/repo>", "GitHub repository that hosts desktop releases").option("--output-dir <path>", "Directory for downloaded desktop release assets").option("--desktop-install-dir <path>", "Directory for the portable Desktop install").option("--no-open", "Install Desktop without launching it").option("--wait-for-active-runs", "Wait for active Rudder runs to finish before replacing Desktop", false).option("--desktop-progress-json", "Emit newline-delimited Desktop update progress events").option("--no-version-check", "Skip checking npm for a newer Rudder CLI version").option("--dry-run", "Print the start actions without changing the machine", false).action(startCommand);
|
|
11448
11559
|
program.command("onboard").description("Interactive first-run setup wizard").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("-y, --yes", "Accept defaults (quickstart + start immediately)", false).option("--run", "Start Rudder immediately after saving config", false).action(onboard);
|
|
11449
11560
|
program.command("doctor").description("Run diagnostic checks on your Rudder setup").option("-c, --config <path>", "Path to config file").option("-d, --data-dir <path>", DATA_DIR_OPTION_HELP).option("--repair", "Attempt to repair issues automatically").alias("--fix").option("-y, --yes", "Skip repair confirmation prompts").action(async (opts) => {
|
|
11450
11561
|
await doctor(opts);
|