From d3d61d4acd5e00cb16af11eb80564129c136298b Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Thu, 11 Jun 2026 14:19:24 +0000 Subject: [PATCH] bundle oauth_connect.json into packaged components (#9535) * fix(frontend): abort publish.sh when package build fails * fix(frontend): bundle oauth_connect.json into packaged components --- frontend/publish.sh | 6 +++ frontend/scripts/fix-svelte-module-imports.js | 49 ++++++++++++++----- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/frontend/publish.sh b/frontend/publish.sh index 9c374f0191..77419bf38b 100755 --- a/frontend/publish.sh +++ b/frontend/publish.sh @@ -1,2 +1,8 @@ +#!/usr/bin/env bash +# Abort if the package build fails — otherwise npm publish ships the stale +# package/ directory left over from the last successful build. +set -euo pipefail +cd "$(dirname "$0")" + npm run package npm publish diff --git a/frontend/scripts/fix-svelte-module-imports.js b/frontend/scripts/fix-svelte-module-imports.js index 2bb7af6b84..9cec6265a0 100644 --- a/frontend/scripts/fix-svelte-module-imports.js +++ b/frontend/scripts/fix-svelte-module-imports.js @@ -1,22 +1,36 @@ -// Rewrite extension-less runes-module imports in the svelte-package output. +// Make the svelte-package output self-contained for consumers. // -// Source files import runes modules (`foo.svelte.ts`) as `$lib/foo.svelte`, -// which Vite resolves inside this repo by appending `.ts`. svelte-package -// emits those modules as `foo.svelte.js` but keeps the import specifier as -// `../foo.svelte`, which consumers of @windmill-labs/components cannot -// resolve (their bundler looks for a `.svelte` component file that does not -// exist). Append `.js` to any relative `.svelte` specifier whose target only -// exists as `.js` in the package output. -import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs' +// 1. Runes-module imports: source files import runes modules (`foo.svelte.ts`) +// as `$lib/foo.svelte`, which Vite resolves inside this repo by appending +// `.ts`. svelte-package emits those modules as `foo.svelte.js` but keeps +// the import specifier as `../foo.svelte`, which consumers of +// @windmill-labs/components cannot resolve (their bundler looks for a +// `.svelte` component file that does not exist). Append `.js` to any +// relative `.svelte` specifier whose target only exists as +// `.js` in the package output. +// +// 2. OAuth connect registry: the `$oauth_connect_registry` alias +// (svelte.config.js) points at `backend/oauth_connect.json`, so the +// packaged output imports `../../../../backend/oauth_connect.json` — a +// path that escapes the package root and does not exist in the published +// tarball. Copy the registry into the package and rewrite those imports +// to point at it (mirrors how package-system-prompts.js bundles +// `$system_prompts`). +import { copyFileSync, existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs' import { fileURLToPath } from 'url' -import { dirname, join, resolve } from 'path' +import { dirname, join, relative, resolve } from 'path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) const packageDir = resolve(__dirname, '..', 'package') +const oauthConnectSrc = resolve(__dirname, '..', '..', 'backend', 'oauth_connect.json') +const oauthConnectDest = join(packageDir, 'oauth_connect.json') -const IMPORT_SPECIFIER_RE = /(\bfrom\s*|\bimport\s*\(?\s*)(['"])(\.\.?\/[^'"]*\.svelte)\2/g +copyFileSync(oauthConnectSrc, oauthConnectDest) + +const IMPORT_SPECIFIER_RE = /(\bfrom\s*|\bimport\s*\(?\s*)(['"])(\.\.?\/[^'"]*\.(?:svelte|json))\2/g +const OAUTH_CONNECT_RE = /^(\.\.\/)+backend\/oauth_connect\.json$/ function* walk(dir) { for (const entry of readdirSync(dir)) { @@ -29,6 +43,11 @@ function* walk(dir) { } } +function relativeSpecifier(fromFile, toFile) { + const spec = relative(dirname(fromFile), toFile).replaceAll('\\', '/') + return spec.startsWith('.') ? spec : `./${spec}` +} + let rewrittenFiles = 0 let rewrittenImports = 0 @@ -36,6 +55,14 @@ for (const file of walk(packageDir)) { const content = readFileSync(file, 'utf-8') let changed = false const updated = content.replace(IMPORT_SPECIFIER_RE, (match, prefix, quote, specifier) => { + if (OAUTH_CONNECT_RE.test(specifier)) { + changed = true + rewrittenImports++ + return `${prefix}${quote}${relativeSpecifier(file, oauthConnectDest)}${quote}` + } + if (!specifier.endsWith('.svelte')) { + return match + } const target = resolve(dirname(file), specifier) // A real `.svelte` component file: leave the import alone. if (existsSync(target)) {