@saidulbadhon/jssm-cli 1.9.5 → 1.9.8

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/dist/index.js +167 -10
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -5012,6 +5012,7 @@ async function pushCommand2(args2) {
5012
5012
  let updatedFilesCount = 0;
5013
5013
  let newFilesCount = 0;
5014
5014
  let deletedFilesCount = 0;
5015
+ let deletionEndpointUnavailable = false;
5015
5016
  let totalChangedLines = 0;
5016
5017
  for (const file of selectedFiles) {
5017
5018
  let fileContent = "";
@@ -5036,11 +5037,11 @@ async function pushCommand2(args2) {
5036
5037
  failCount++;
5037
5038
  continue;
5038
5039
  }
5039
- if (fileSize > 8192) {
5040
+ if (fileSize > 65536) {
5040
5041
  console.error(
5041
- `\u274C ${file}: File size (${fileSize} bytes) exceeds maximum (8192 bytes)`
5042
+ `\u274C ${file}: File size (${fileSize} bytes) exceeds maximum (65536 bytes / 64 KB)`
5042
5043
  );
5043
- console.error(" Consider reducing comments or splitting variables");
5044
+ console.error(" Files >4 KB are auto-chunked, but this exceeds the overall cap.");
5044
5045
  failCount++;
5045
5046
  continue;
5046
5047
  }
@@ -5132,6 +5133,19 @@ async function pushCommand2(args2) {
5132
5133
  }
5133
5134
  } catch (error) {
5134
5135
  const message = error instanceof Error ? error.message : String(error);
5136
+ if (message.includes("HTTP 404")) {
5137
+ if (!deletionEndpointUnavailable) {
5138
+ console.error(
5139
+ "\u274C Deletion sync is not supported by this server (missing /files/delete endpoint)."
5140
+ );
5141
+ console.error(
5142
+ " \u{1F4A1} Upgrade/redeploy the backend with the latest files route changes, then run jssm push again."
5143
+ );
5144
+ deletionEndpointUnavailable = true;
5145
+ failCount++;
5146
+ }
5147
+ break;
5148
+ }
5135
5149
  console.error(`\u274C ${remoteFile}: Failed to delete - ${message}`);
5136
5150
  failCount++;
5137
5151
  }
@@ -5601,13 +5615,156 @@ Note:
5601
5615
 
5602
5616
  // src/commands/login.ts
5603
5617
  init_auth();
5604
- async function loginCommand() {
5618
+
5619
+ // src/commands/loginBrowser.ts
5620
+ init_auth();
5621
+ import { hostname, platform } from "os";
5622
+ import { spawn } from "child_process";
5623
+ function openBrowser(url) {
5624
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
5625
+ const args2 = process.platform === "win32" ? ["/c", "start", "", url] : [url];
5626
+ try {
5627
+ const child = spawn(cmd, args2, {
5628
+ detached: true,
5629
+ stdio: "ignore"
5630
+ });
5631
+ child.unref();
5632
+ child.on("error", () => {
5633
+ });
5634
+ return true;
5635
+ } catch {
5636
+ return false;
5637
+ }
5638
+ }
5639
+ function sleep(ms) {
5640
+ return new Promise((resolve) => setTimeout(resolve, ms));
5641
+ }
5642
+ var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
5643
+ async function loginBrowserCommand() {
5644
+ const host = getHost();
5645
+ let init;
5646
+ try {
5647
+ const response = await fetch(`${host}/auth/cli/init`, {
5648
+ method: "POST",
5649
+ headers: { "Content-Type": "application/json" },
5650
+ body: JSON.stringify({
5651
+ deviceInfo: {
5652
+ hostname: hostname(),
5653
+ platform: platform()
5654
+ }
5655
+ })
5656
+ });
5657
+ if (!response.ok) {
5658
+ const body = await response.json().catch(() => ({}));
5659
+ return {
5660
+ success: false,
5661
+ error: body.error || `Failed to start login (HTTP ${response.status})`
5662
+ };
5663
+ }
5664
+ init = await response.json();
5665
+ } catch (err) {
5666
+ return {
5667
+ success: false,
5668
+ error: `Unable to reach JSSM at ${host}: ${err?.message || err}`
5669
+ };
5670
+ }
5671
+ console.log("");
5672
+ console.log("\u{1F510} Sign in to JSSM");
5673
+ console.log("");
5674
+ console.log(` Verification code: \x1B[1m${init.userCode}\x1B[0m`);
5675
+ console.log(` Open this URL: ${init.verificationUrl}`);
5676
+ console.log("");
5677
+ console.log(" Confirm the code matches what's shown in the browser.");
5678
+ console.log("");
5679
+ const opened = openBrowser(init.verificationUrl);
5680
+ if (!opened) {
5681
+ console.log("\u26A0\uFE0F Could not auto-open browser \u2014 open the URL above manually.");
5682
+ }
5683
+ const intervalMs = Math.max(1, init.interval) * 1e3;
5684
+ const deadline = Date.now() + init.expiresIn * 1e3;
5685
+ let frame = 0;
5686
+ const isTty = !!process.stdout.isTTY;
5687
+ while (Date.now() < deadline) {
5688
+ if (isTty) {
5689
+ const spinner = SPINNER_FRAMES[frame++ % SPINNER_FRAMES.length];
5690
+ process.stdout.write(`\r${spinner} Waiting for approval in browser\u2026`);
5691
+ }
5692
+ await sleep(intervalMs);
5693
+ let poll;
5694
+ try {
5695
+ const response = await fetch(`${host}/auth/cli/poll`, {
5696
+ method: "POST",
5697
+ headers: { "Content-Type": "application/json" },
5698
+ body: JSON.stringify({ code: init.code })
5699
+ });
5700
+ if (!response.ok) {
5701
+ continue;
5702
+ }
5703
+ poll = await response.json();
5704
+ } catch {
5705
+ continue;
5706
+ }
5707
+ if (poll.status === "pending")
5708
+ continue;
5709
+ if (isTty)
5710
+ process.stdout.write("\r\x1B[K");
5711
+ if (poll.status === "approved" && poll.token && poll.user) {
5712
+ const expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1e3;
5713
+ await saveAuthData({
5714
+ token: poll.token,
5715
+ user: poll.user,
5716
+ expiresAt
5717
+ });
5718
+ return { success: true };
5719
+ }
5720
+ if (poll.status === "denied") {
5721
+ return { success: false, error: "Sign-in was canceled in the browser." };
5722
+ }
5723
+ if (poll.status === "expired") {
5724
+ return { success: false, error: "Sign-in request expired before approval." };
5725
+ }
5726
+ }
5727
+ if (isTty)
5728
+ process.stdout.write("\r\x1B[K");
5729
+ return {
5730
+ success: false,
5731
+ error: "Sign-in timed out. Run `jssm login` again to retry."
5732
+ };
5733
+ }
5734
+
5735
+ // src/commands/login.ts
5736
+ async function loginCommand(args2 = []) {
5605
5737
  const authData = await loadAuthData();
5606
5738
  if (authData) {
5607
5739
  console.log(`\u2705 Already logged in as ${authData.user.email}`);
5608
5740
  console.log(`\u{1F4A1} Use 'jssm logout' to logout`);
5609
5741
  return;
5610
5742
  }
5743
+ const wantsManual = args2.includes("--manual");
5744
+ const useBrowser = !wantsManual && process.stdout.isTTY;
5745
+ if (useBrowser) {
5746
+ try {
5747
+ const result = await loginBrowserCommand();
5748
+ if (result.success) {
5749
+ const fresh = await loadAuthData();
5750
+ console.log(`\u2705 Successfully logged in as ${fresh?.user.email}`);
5751
+ console.log(`\u{1F464} Name: ${fresh?.user.name}`);
5752
+ console.log(`
5753
+ \u{1F4A1} You can now use 'jssm init' to set up your projects`);
5754
+ return;
5755
+ }
5756
+ console.error(`\u274C ${result.error}`);
5757
+ console.log(`
5758
+ \u{1F4A1} Run 'jssm login --manual' to use email + password.`);
5759
+ process.exit(1);
5760
+ } catch (err) {
5761
+ console.error(`\u274C Error: ${err?.message || err}`);
5762
+ process.exit(1);
5763
+ }
5764
+ }
5765
+ await loginManual();
5766
+ }
5767
+ async function loginManual() {
5611
5768
  const host = getHost();
5612
5769
  console.log("\u{1F510} Login to JSSM\n");
5613
5770
  try {
@@ -5633,10 +5790,10 @@ async function loginCommand() {
5633
5790
  console.log("\n\u{1F504} Logging in...");
5634
5791
  const result = await login(host, email, pass);
5635
5792
  if (result.success) {
5636
- const authData2 = await loadAuthData();
5793
+ const authData = await loadAuthData();
5637
5794
  console.log(`
5638
- \u2705 Successfully logged in as ${authData2?.user.email}`);
5639
- console.log(`\u{1F464} Name: ${authData2?.user.name}`);
5795
+ \u2705 Successfully logged in as ${authData?.user.email}`);
5796
+ console.log(`\u{1F464} Name: ${authData?.user.name}`);
5640
5797
  console.log(`
5641
5798
  \u{1F4A1} You can now use 'jssm init' to set up your projects`);
5642
5799
  } else {
@@ -6027,7 +6184,7 @@ ${import_chalk.default.bold("Usage in Docker:")}
6027
6184
 
6028
6185
  // src/utils/versionCheck.ts
6029
6186
  var PACKAGE_NAME = "@saidulbadhon/jssm-cli";
6030
- var CURRENT_VERSION = "1.9.5";
6187
+ var CURRENT_VERSION = "1.9.8";
6031
6188
  async function getLatestVersion() {
6032
6189
  try {
6033
6190
  const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`);
@@ -6144,7 +6301,7 @@ async function main() {
6144
6301
  await checkVersion(command);
6145
6302
  switch (command) {
6146
6303
  case "login":
6147
- await loginCommand();
6304
+ await loginCommand(args.slice(1));
6148
6305
  break;
6149
6306
  case "register":
6150
6307
  await registerCommand();
@@ -6210,7 +6367,7 @@ Usage:
6210
6367
  jssm <command> [options]
6211
6368
 
6212
6369
  Commands:
6213
- login Login to your JSSM account
6370
+ login Login via your browser (use --manual for email/password prompt)
6214
6371
  register Register a new JSSM account
6215
6372
  logout Logout from your account
6216
6373
  init Initialize current directory (creates .jssm config file)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saidulbadhon/jssm-cli",
3
- "version": "1.9.5",
3
+ "version": "1.9.8",
4
4
  "private": false,
5
5
  "description": "CLI for JSSM - Simple environment variable manager",
6
6
  "author": "Saidul Badhon",
@@ -49,4 +49,4 @@
49
49
  "dependencies": {
50
50
  "@inquirer/prompts": "^8.2.0"
51
51
  }
52
- }
52
+ }