@qumra/cli 2.4.18 → 2.4.21

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/cli.js +66 -137
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -35,7 +35,7 @@ var fs$k = require('node:fs');
35
35
  var require$$0$g = require('http');
36
36
  var require$$1$b = require('https');
37
37
  var zlib$3 = require('zlib');
38
- var net$4 = require('net');
38
+ var require$$3$4 = require('net');
39
39
  var require$$4$5 = require('tls');
40
40
  var process$5 = require('node:process');
41
41
  var require$$0$i = require('node:buffer');
@@ -57,7 +57,7 @@ var require$$2$b = require('node:http');
57
57
  var require$$5$6 = require('node:querystring');
58
58
  var require$$0$q = require('node:diagnostics_channel');
59
59
  var require$$4$6 = require('node:tls');
60
- var require$$3$4 = require('node:zlib');
60
+ var require$$3$5 = require('node:zlib');
61
61
  var require$$5$7 = require('node:perf_hooks');
62
62
  var require$$8$1 = require('node:util/types');
63
63
  var require$$1$d = require('node:sqlite');
@@ -110,7 +110,7 @@ var fs__namespace$1 = /*#__PURE__*/_interopNamespaceDefault(fs$j);
110
110
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path$d);
111
111
  var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs$i);
112
112
  var blessed__namespace = /*#__PURE__*/_interopNamespaceDefault(blessed);
113
- var net__namespace = /*#__PURE__*/_interopNamespaceDefault(net$4);
113
+ var require$$3__namespace = /*#__PURE__*/_interopNamespaceDefault(require$$3$4);
114
114
  var readline__namespace = /*#__PURE__*/_interopNamespaceDefault(readline$4);
115
115
 
116
116
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -304366,7 +304366,7 @@ class SectionBuilder {
304366
304366
  }
304367
304367
  }
304368
304368
 
304369
- var version$2 = "2.4.18";
304369
+ var version$2 = "2.4.21";
304370
304370
  var pkg = {
304371
304371
  version: version$2};
304372
304372
 
@@ -315027,7 +315027,7 @@ var extension$1 = { format: format$5, parse: parse$o };
315027
315027
  const EventEmitter$6 = require$$2$7;
315028
315028
  const https$3 = require$$1$b;
315029
315029
  const http$8 = require$$0$g;
315030
- const net$3 = net$4;
315030
+ const net$3 = require$$3$4;
315031
315031
  const tls$1 = require$$4$5;
315032
315032
  const { randomBytes, createHash: createHash$1 } = require$$0$d;
315033
315033
  const { Duplex: Duplex$3, Readable: Readable$8 } = require$$0$b;
@@ -358635,7 +358635,7 @@ function requireNode$5 () {
358635
358635
 
358636
358636
  case 'PIPE':
358637
358637
  case 'TCP':
358638
- var net = net$4;
358638
+ var net = require$$3$4;
358639
358639
  stream = new net.Socket({
358640
358640
  fd: fd,
358641
358641
  readable: false,
@@ -434482,7 +434482,7 @@ function validMime (type) {
434482
434482
 
434483
434483
  var accepts$2 = accepts$3;
434484
434484
  var deprecate$1 = depd_1('express');
434485
- var isIP$1 = net$4.isIP;
434485
+ var isIP$1 = require$$3$4.isIP;
434486
434486
  var typeis = typeIsExports;
434487
434487
  var http$3 = require$$0$g;
434488
434488
  var fresh = fresh_1;
@@ -490388,7 +490388,7 @@ const lazyLoaders = {
490388
490388
  'node:crypto': () => require$$2$8,
490389
490389
  'node:sqlite': () => require$$1$d,
490390
490390
  'node:worker_threads': () => require$$2$c,
490391
- 'node:zlib': () => require$$3$4
490391
+ 'node:zlib': () => require$$3$5
490392
490392
  };
490393
490393
 
490394
490394
  /**
@@ -491470,7 +491470,7 @@ function requireUtil$4 () {
491470
491470
  hasRequiredUtil$4 = 1;
491471
491471
 
491472
491472
  const { Transform } = require$$0$k;
491473
- const zlib = require$$3$4;
491473
+ const zlib = require$$3$5;
491474
491474
  const { redirectStatusSet, referrerPolicyTokens, badPortsSet } = requireConstants$2();
491475
491475
  const { getGlobalOrigin } = requireGlobal();
491476
491476
  const { collectAnHTTPQuotedString, parseMIMEType } = requireDataUrl();
@@ -506922,7 +506922,7 @@ var cache$2 = (opts = {}) => {
506922
506922
  }
506923
506923
  };
506924
506924
 
506925
- const { createInflate, createGunzip, createBrotliDecompress, createZstdDecompress } = require$$3$4;
506925
+ const { createInflate, createGunzip, createBrotliDecompress, createZstdDecompress } = require$$3$5;
506926
506926
  const { pipeline } = require$$0$k;
506927
506927
  const DecoratorHandler = decoratorHandler;
506928
506928
  const { runtimeFeatures } = runtimeFeatures$2;
@@ -510794,7 +510794,7 @@ function requireFetch () {
510794
510794
  } = requireResponse();
510795
510795
  const { HeadersList } = requireHeaders();
510796
510796
  const { Request, cloneRequest, getRequestDispatcher, getRequestState } = requireRequest();
510797
- const zlib = require$$3$4;
510797
+ const zlib = require$$3$5;
510798
510798
  const {
510799
510799
  makePolicyContainer,
510800
510800
  clonePolicyContainer,
@@ -516300,7 +516300,7 @@ function requirePermessageDeflate () {
516300
516300
  if (hasRequiredPermessageDeflate) return permessageDeflate;
516301
516301
  hasRequiredPermessageDeflate = 1;
516302
516302
 
516303
- const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = require$$3$4;
516303
+ const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = require$$3$5;
516304
516304
  const { isValidClientWindowBits } = requireUtil$1();
516305
516305
 
516306
516306
  const tail = Buffer.from([0x00, 0x00, 0xff, 0xff]);
@@ -533297,7 +533297,7 @@ let ThemeProxyService = class ThemeProxyService {
533297
533297
  */
533298
533298
  isPortAvailable(port) {
533299
533299
  return new Promise((resolve) => {
533300
- const server = net__namespace.createServer();
533300
+ const server = require$$3__namespace.createServer();
533301
533301
  server.once('error', (err) => {
533302
533302
  if (err.code === 'EADDRINUSE') {
533303
533303
  resolve(false);
@@ -534476,56 +534476,9 @@ let AppDevServerService = class AppDevServerService {
534476
534476
  this.logger = logger;
534477
534477
  this.childProcess = null;
534478
534478
  }
534479
- async start(options) {
534480
- const { env, cwd = process.cwd() } = options;
534481
- this.logger.componentLog('React Router', 'Starting development server...');
534482
- return new Promise((resolve, reject) => {
534483
- var _a, _b;
534484
- const child = require$$1$7.spawn('npx', ['react-router', 'dev'], {
534485
- cwd,
534486
- env: { ...process.env, ...env },
534487
- shell: true,
534488
- detached: true,
534489
- });
534490
- this.childProcess = child;
534491
- (_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
534492
- const lines = data.toString().trim().split('\n');
534493
- for (const line of lines) {
534494
- if (line.trim()) {
534495
- this.logger.componentLog('React Router', line.trim());
534496
- }
534497
- }
534498
- });
534499
- (_b = child.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
534500
- const lines = data.toString().trim().split('\n');
534501
- for (const line of lines) {
534502
- if (line.trim()) {
534503
- // Check if it's a warning (npm warn) or actual error
534504
- if (line.includes('warn')) {
534505
- this.logger.componentLog('React Router', line.trim(), 'warn');
534506
- }
534507
- else {
534508
- this.logger.componentLog('React Router', line.trim(), 'error');
534509
- }
534510
- }
534511
- }
534512
- });
534513
- child.on('error', (err) => {
534514
- reject(new Error(`Server failed to start: ${err.message}`));
534515
- });
534516
- // Consider server started after small delay
534517
- setTimeout(resolve, 2000);
534518
- // Handle exit
534519
- child.on('exit', (code) => {
534520
- this.childProcess = null;
534521
- if (code !== 0) {
534522
- this.logger.componentLog('React Router', `Server exited with code ${code}`, 'error');
534523
- }
534524
- });
534525
- });
534526
- }
534527
534479
  /**
534528
- * Start dev server with DevUI logging
534480
+ * Start dev server with DevUI logging.
534481
+ * Returns the actual port the server is listening on (parsed from Vite output).
534529
534482
  */
534530
534483
  async startWithUI(devUI, options) {
534531
534484
  const { env, cwd = process.cwd() } = options;
@@ -534536,14 +534489,23 @@ let AppDevServerService = class AppDevServerService {
534536
534489
  cwd,
534537
534490
  env: { ...process.env, ...env },
534538
534491
  shell: true,
534539
- detached: true,
534492
+ stdio: ['pipe', 'pipe', 'pipe'],
534540
534493
  });
534541
534494
  this.childProcess = child;
534495
+ let resolved = false;
534542
534496
  (_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
534543
534497
  const lines = data.toString().trim().split('\n');
534544
534498
  for (const line of lines) {
534545
534499
  if (line.trim()) {
534546
534500
  devUI.log('React Router', line.trim());
534501
+ // Parse actual port from Vite output: "➜ Local: http://localhost:4002/"
534502
+ if (!resolved) {
534503
+ const match = line.match(/Local:\s+https?:\/\/[^:]+:(\d+)/);
534504
+ if (match) {
534505
+ resolved = true;
534506
+ resolve(Number(match[1]));
534507
+ }
534508
+ }
534547
534509
  }
534548
534510
  }
534549
534511
  });
@@ -534562,64 +534524,43 @@ let AppDevServerService = class AppDevServerService {
534562
534524
  });
534563
534525
  child.on('error', (err) => {
534564
534526
  devUI.log('React Router', `Failed to start: ${err.message}`, 'error');
534565
- reject(new Error(`Server failed to start: ${err.message}`));
534527
+ if (!resolved) {
534528
+ resolved = true;
534529
+ reject(new Error(`Server failed to start: ${err.message}`));
534530
+ }
534566
534531
  });
534567
- // Consider server started after small delay
534568
- setTimeout(resolve, 2000);
534569
534532
  // Handle exit
534570
534533
  child.on('exit', (code) => {
534571
534534
  this.childProcess = null;
534572
534535
  if (code !== 0) {
534573
534536
  devUI.log('React Router', `Server exited with code ${code}`, 'error');
534574
534537
  }
534538
+ if (!resolved) {
534539
+ resolved = true;
534540
+ reject(new Error(`Server exited with code ${code}`));
534541
+ }
534575
534542
  });
534543
+ // Timeout fallback
534544
+ setTimeout(() => {
534545
+ if (!resolved) {
534546
+ resolved = true;
534547
+ // Fallback to the PORT env if we couldn't parse the actual port
534548
+ resolve(Number(env.PORT) || 3000);
534549
+ }
534550
+ }, 30000);
534576
534551
  });
534577
534552
  }
534578
534553
  stop() {
534579
- if (this.childProcess && !this.childProcess.killed) {
534580
- // Kill the process tree (shell: true spawns a shell + child)
534581
- if (this.childProcess.pid) {
534582
- try {
534583
- process.kill(-this.childProcess.pid, 'SIGTERM');
534584
- }
534585
- catch {
534586
- // Fallback if process group kill fails
534587
- this.childProcess.kill('SIGTERM');
534588
- }
534554
+ if (this.childProcess && !this.childProcess.killed && this.childProcess.pid) {
534555
+ try {
534556
+ process.kill(this.childProcess.pid, 'SIGTERM');
534589
534557
  }
534590
- else {
534591
- this.childProcess.kill('SIGTERM');
534558
+ catch {
534559
+ // Process already exited
534592
534560
  }
534593
534561
  this.childProcess = null;
534594
534562
  }
534595
534563
  }
534596
- async getAvailablePort(startPort = 4000) {
534597
- let port = startPort;
534598
- while (true) {
534599
- const isAvailable = await this.isPortAvailable(port);
534600
- if (isAvailable) {
534601
- return port;
534602
- }
534603
- port++;
534604
- }
534605
- }
534606
- isPortAvailable(port) {
534607
- return new Promise((resolve) => {
534608
- const server = net__namespace.createServer();
534609
- server.once('error', (err) => {
534610
- if (err.code === 'EADDRINUSE') {
534611
- resolve(false);
534612
- }
534613
- else {
534614
- throw err;
534615
- }
534616
- });
534617
- server.once('listening', () => {
534618
- server.close(() => resolve(true));
534619
- });
534620
- server.listen(port);
534621
- });
534622
- }
534623
534564
  };
534624
534565
  AppDevServerService = __decorate$5([
534625
534566
  commonExports.Injectable(),
@@ -534678,19 +534619,11 @@ let AppService = class AppService {
534678
534619
  devStore = await this.getOrCreateDevStore(app.organization.handle);
534679
534620
  await this.config.update({ devStore });
534680
534621
  }
534681
- // Get available port
534682
- const port = await this.devServer.getAvailablePort();
534683
- // Create tunnel (before UI starts)
534684
- this.logger.componentLog('tunnel', 'Creating tunnel...');
534685
- const localUrl = `http://localhost:${port}`;
534686
- const developmentUrl = await this.tunnel.createTunnel(localUrl);
534687
- // Update dev data
534688
- await this.appApi.updateDevData(developmentUrl, qumraConfig.clientId);
534689
- // URLs
534622
+ // URLs will be updated after tunnel is created
534623
+ let developmentUrl = '';
534690
534624
  const installUrl = `https://${devStore}/admin/oauth/cli-install-app?client_id=${qumraConfig.clientId}`;
534691
- // Create BlessedUI with separate log panels
534625
+ // Create BlessedUI first for all logging
534692
534626
  const devUI = new BlessedUI();
534693
- // Start BlessedUI
534694
534627
  devUI.start({
534695
534628
  title: 'Qumra App Dev',
534696
534629
  subtitle: 'Using qumra.config.json for default values:',
@@ -534700,10 +534633,7 @@ let AppService = class AppService {
534700
534633
  { key: 'App', value: app.title },
534701
534634
  { key: 'Dev store', value: devStore },
534702
534635
  ],
534703
- urls: [
534704
- { label: 'Preview URL', url: developmentUrl },
534705
- { label: 'Install URL', url: installUrl },
534706
- ],
534636
+ urls: [],
534707
534637
  shortcuts: [
534708
534638
  {
534709
534639
  key: 'q', label: 'Quit', handler: () => {
@@ -534713,32 +534643,31 @@ let AppService = class AppService {
534713
534643
  process.exit(0);
534714
534644
  }
534715
534645
  },
534716
- { key: 'p', label: 'Preview', handler: () => open(developmentUrl) },
534646
+ { key: 'p', label: 'Preview', handler: () => { if (developmentUrl)
534647
+ open(developmentUrl); } },
534717
534648
  { key: 'o', label: 'Open Store', handler: () => open(installUrl) },
534718
534649
  ],
534719
534650
  logPanels: ['All', 'Server', 'Tunnel', 'Prisma'],
534720
534651
  });
534721
- // Log initial steps
534722
- // devUI.log('prisma', 'Running migrations...');
534723
- // execSync('npx prisma db push && npx prisma generate', {
534724
- // cwd: process.cwd(),
534725
- // stdio: 'ignore',
534726
- // });
534727
- // devUI.log('prisma', 'Migrations complete', 'success');
534728
- devUI.log('tunnel', `Tunnel ready: ${developmentUrl}`, 'success');
534729
- devUI.log('app-preview', 'Dev preview ready', 'success');
534730
- // Open install URL in browser
534731
- await open(installUrl);
534732
- // Start dev server with DevUI logging
534733
- await this.devServer.startWithUI(devUI, {
534652
+ // Start dev server FIRST - returns the actual port Vite chose
534653
+ const actualPort = await this.devServer.startWithUI(devUI, {
534734
534654
  env: {
534735
- QUMRA_APP_URL: developmentUrl,
534736
534655
  QUMRA_API_KEY: qumraConfig.clientId,
534737
534656
  QUMRA_API_SECRET: app.secretKey,
534738
- PORT: String(port),
534739
- SOCKET_PORT: String(port),
534657
+ PORT: '3000',
534658
+ SOCKET_PORT: '3000',
534740
534659
  },
534741
534660
  });
534661
+ devUI.log('server', `Server running on port ${actualPort}`, 'success');
534662
+ // Create tunnel AFTER server is running, using the actual port
534663
+ devUI.log('tunnel', 'Creating tunnel...');
534664
+ developmentUrl = await this.tunnel.createTunnel(`http://127.0.0.1:${actualPort}`);
534665
+ devUI.log('tunnel', `Tunnel ready: ${developmentUrl}`, 'success');
534666
+ // Update dev data
534667
+ await this.appApi.updateDevData(developmentUrl, qumraConfig.clientId);
534668
+ devUI.log('app-preview', 'Dev preview ready', 'success');
534669
+ // Open install URL only after everything is running
534670
+ await open(installUrl);
534742
534671
  }
534743
534672
  async deploy() {
534744
534673
  const qumraConfig = await this.config.load();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qumra/cli",
3
- "version": "2.4.18",
3
+ "version": "2.4.21",
4
4
  "description": "Official CLI for Qumra Cloud e-commerce platform. Build, develop, and deploy themes and apps.",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {