@pixelbyte-software/pixcode 1.33.0 → 1.33.1

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/server/index.js CHANGED
@@ -566,6 +566,75 @@ app.post('/api/system/update', authenticateToken, async (req, res) => {
566
566
  }
567
567
  fs.rmSync(stagingDir, { recursive: true, force: true });
568
568
 
569
+ // 3a. Reconcile node_modules with the NEW package.json.
570
+ // npm tarballs intentionally ship WITHOUT node_modules, so
571
+ // if this release changed `dependencies` (e.g. bcrypt →
572
+ // bcryptjs in 1.32.0) the runtime dir now has new code
573
+ // importing packages that aren't installed. We fix that
574
+ // by running `npm install --production` in-place.
575
+ // Skipped when the NEW package.json's dependency set is
576
+ // identical to the .previous/ one — no need to pay the
577
+ // 10-30 sec cost for pure-code updates.
578
+ const depsChanged = (() => {
579
+ try {
580
+ const prevPkg = JSON.parse(fs.readFileSync(path.join(backupDir, 'package.json'), 'utf8'));
581
+ const nextPkg = JSON.parse(fs.readFileSync(path.join(runtimeDir, 'package.json'), 'utf8'));
582
+ const prevDeps = JSON.stringify(prevPkg.dependencies || {});
583
+ const nextDeps = JSON.stringify(nextPkg.dependencies || {});
584
+ return prevDeps !== nextDeps;
585
+ } catch {
586
+ // Can't read either side — reconcile to be safe.
587
+ return true;
588
+ }
589
+ })();
590
+
591
+ if (depsChanged) {
592
+ send('log', { stream: 'meta', chunk: 'Reconciling node_modules with new package.json…\n' });
593
+ const npmOk = await new Promise((resolveInstall) => {
594
+ const npmChild = spawn('npm', ['install', '--production', '--no-audit', '--no-fund', '--no-save'], {
595
+ cwd: runtimeDir,
596
+ env: process.env,
597
+ shell: true,
598
+ });
599
+ // Stream output so the user sees progress (and so
600
+ // a mid-install hang is obvious rather than silent).
601
+ npmChild.stdout?.on('data', (chunk) => {
602
+ send('log', { stream: 'stdout', chunk: chunk.toString() });
603
+ });
604
+ npmChild.stderr?.on('data', (chunk) => {
605
+ // npm writes warnings to stderr even on success, so
606
+ // we surface them but don't treat them as failure.
607
+ send('log', { stream: 'stderr', chunk: chunk.toString() });
608
+ });
609
+ npmChild.on('error', (err) => {
610
+ send('log', { stream: 'meta', chunk: `npm install spawn failed: ${err.message}\n` });
611
+ resolveInstall(false);
612
+ });
613
+ npmChild.on('close', (code) => {
614
+ if (code === 0) {
615
+ send('log', { stream: 'meta', chunk: 'node_modules reconciled.\n' });
616
+ resolveInstall(true);
617
+ } else {
618
+ send('log', { stream: 'meta', chunk: `npm install exited with code ${code}\n` });
619
+ resolveInstall(false);
620
+ }
621
+ });
622
+ });
623
+ if (!npmOk) {
624
+ // The swap already happened — rolling back is expensive
625
+ // and leaves node_modules in an uncertain state either
626
+ // way. Report failure with a clear remediation hint so
627
+ // the user knows what to do next (quit + run npm install
628
+ // manually, or reinstall from the .exe/.dmg/.deb).
629
+ send('done', {
630
+ success: false,
631
+ error: `Update downloaded to ${latestVersion} but \`npm install\` failed — node_modules may be missing packages. Quit Pixcode and run "npm install --production" in ${runtimeDir}, or reinstall from the latest installer.`,
632
+ });
633
+ endStream();
634
+ return;
635
+ }
636
+ }
637
+
569
638
  send('done', {
570
639
  success: true,
571
640
  version: latestVersion,