From 193331544d46b2581d221e5a4ee07ec9c5ef2a7c Mon Sep 17 00:00:00 2001 From: "jason.woltje" Date: Fri, 10 Jul 2026 01:30:10 +0000 Subject: [PATCH] =?UTF-8?q?fix(wizard):=20honor=20MOSAIC=5FGATEWAY=5FSKIP?= =?UTF-8?q?=5FNPM=5FINSTALL=20=E2=80=94=20unblock=20install.sh=20--dev=20g?= =?UTF-8?q?ateway=20testing=20(#698)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mosaic/src/stages/gateway-config.spec.ts | 31 +++++++++++++++++++ packages/mosaic/src/stages/gateway-config.ts | 7 ++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/packages/mosaic/src/stages/gateway-config.spec.ts b/packages/mosaic/src/stages/gateway-config.spec.ts index 52554ac..befc5d2 100644 --- a/packages/mosaic/src/stages/gateway-config.spec.ts +++ b/packages/mosaic/src/stages/gateway-config.spec.ts @@ -136,6 +136,7 @@ describe('gatewayConfigStage', () => { delete process.env['MOSAIC_STORAGE_TIER']; delete process.env['MOSAIC_DATABASE_URL']; delete process.env['MOSAIC_VALKEY_URL']; + delete process.env['MOSAIC_GATEWAY_SKIP_NPM_INSTALL']; }); afterEach(() => { @@ -167,6 +168,36 @@ describe('gatewayConfigStage', () => { expect(state.gateway?.regeneratedConfig).toBe(true); }); + it('installs the gateway package on fresh install when skipInstall is not set', async () => { + const p = buildPrompter(); + const state = makeState('/home/user/.config/mosaic'); + + const result = await gatewayConfigStage(p, state, { + host: 'localhost', + defaultPort: 14242, + skipInstall: false, + }); + + expect(result.ready).toBe(true); + expect(daemonState.installPkgCalled).toBe(1); + }); + + it('honors MOSAIC_GATEWAY_SKIP_NPM_INSTALL=1 and skips the registry install (dev/offline installs)', async () => { + process.env['MOSAIC_GATEWAY_SKIP_NPM_INSTALL'] = '1'; + const p = buildPrompter(); + const state = makeState('/home/user/.config/mosaic'); + + const result = await gatewayConfigStage(p, state, { + host: 'localhost', + defaultPort: 14242, + skipInstall: false, + }); + + // The source-built global gateway must NOT be overwritten by @latest. + expect(result.ready).toBe(true); + expect(daemonState.installPkgCalled).toBe(0); + }); + it('does not ask for a gateway API key when provider setup was completed with no key', async () => { delete process.env['MOSAIC_ASSUME_YES']; const originalIsTTY = process.stdin.isTTY; diff --git a/packages/mosaic/src/stages/gateway-config.ts b/packages/mosaic/src/stages/gateway-config.ts index b6abde3..38bd85d 100644 --- a/packages/mosaic/src/stages/gateway-config.ts +++ b/packages/mosaic/src/stages/gateway-config.ts @@ -294,7 +294,12 @@ export async function gatewayConfigStage( } // Install the gateway npm package on first install or after failure. - if (!opts.skipInstall && !daemonRunning) { + // MOSAIC_GATEWAY_SKIP_NPM_INSTALL=1 forces a skip even without opts.skipInstall: + // used by dev/offline installs where @mosaicstack/gateway is already present + // globally (e.g. a build-from-source `install.sh --dev`) and must not be + // overwritten by the registry @latest build. + const skipNpmInstall = opts.skipInstall || process.env['MOSAIC_GATEWAY_SKIP_NPM_INSTALL'] === '1'; + if (!skipNpmInstall && !daemonRunning) { installGatewayPackage(); }