diff --git a/src/cli/domain/ocConfig.ts b/src/cli/domain/ocConfig.ts index 93ed681e..65cfdc0e 100644 --- a/src/cli/domain/ocConfig.ts +++ b/src/cli/domain/ocConfig.ts @@ -9,6 +9,10 @@ export interface OpenComponentsConfig { registries?: string[]; /** Development-specific configuration settings */ development?: { + /** JavaScript code to be included in the preview HTML's section. + * Can be either a filepath to a JS script or inline JavaScript code. + */ + preload?: string; /** Fallback configuration for when components cannot be found locally */ fallback?: { /** URL of the fallback registry to use when components cannot be found locally */ @@ -41,6 +45,7 @@ type ParsedConfig = { sourcePath?: string; registries: string[]; development: { + preload?: string; plugins: { dynamic?: Record; static?: Record; @@ -84,6 +89,7 @@ function parseConfig(config: OpenComponentsConfig): ParsedConfig { ...config, registries: config.registries || [], development: { + preload: config.development?.preload, plugins, fallback: config.development?.fallback } diff --git a/src/cli/facade/dev.ts b/src/cli/facade/dev.ts index d20717a0..5275ad64 100644 --- a/src/cli/facade/dev.ts +++ b/src/cli/facade/dev.ts @@ -43,9 +43,9 @@ const dev = ({ local, logger }: { logger: Logger; local: Local }) => let fallbackRegistryUrl = opts.fallbackRegistryUrl; let fallbackClient = false; + const localConfig = getOcConfig(componentsDir); if (!fallbackRegistryUrl) { try { - const localConfig = getOcConfig(componentsDir); if ( !fallbackRegistryUrl && typeof localConfig.development?.fallback?.url === 'string' @@ -207,7 +207,8 @@ const dev = ({ local, logger }: { logger: Logger; local: Local }) => path: path.resolve(componentsDir), port, templates: dependencies.templates, - verbosity: 1 + verbosity: 1, + preload: localConfig.development?.preload }); registerPlugins(registry); diff --git a/src/registry/domain/options-sanitiser.ts b/src/registry/domain/options-sanitiser.ts index ee005420..2b5238fe 100644 --- a/src/registry/domain/options-sanitiser.ts +++ b/src/registry/domain/options-sanitiser.ts @@ -113,6 +113,31 @@ export default function optionsSanitiser(input: RegistryOptions): Config { options.templates = []; } + // Handle preload script - if it's a filepath, read the file content + if ( + options.preload && + !options.preload.includes(';') && + !options.preload.includes('{') + ) { + try { + const fs = require('node:fs'); + const path = require('node:path'); + const preloadPath = path.isAbsolute(options.preload) + ? options.preload + : path.resolve(process.cwd(), options.preload); + + if (fs.existsSync(preloadPath)) { + options.preload = fs.readFileSync(preloadPath, 'utf8'); + } + } catch (error) { + // If file reading fails, keep the original value (might be inline JS) + console.warn( + `Warning: Could not read preload file "${options.preload}":`, + (error as Error).message + ); + } + } + if (options.compileClient || options.compileClient !== false) { const clientOptions = typeof options.compileClient === 'boolean' diff --git a/src/registry/routes/component-preview.ts b/src/registry/routes/component-preview.ts index f18c842a..b9118632 100644 --- a/src/registry/routes/component-preview.ts +++ b/src/registry/routes/component-preview.ts @@ -37,6 +37,7 @@ function componentPreview( : undefined, href: res.conf.baseUrl, liveReload, + preload: res.conf.preload, qs: urlBuilder.queryString(req.query as any), templates }) diff --git a/src/registry/views/preview.ts b/src/registry/views/preview.ts index a881e7f1..68d2343d 100644 --- a/src/registry/views/preview.ts +++ b/src/registry/views/preview.ts @@ -7,6 +7,7 @@ export default function preview(vm: { qs: string; liveReload: string; templates: TemplateInfo[]; + preload?: string; }): string { const baseUrl = vm.href.replace('http://', '//').replace('https://', '//'); const { name, version } = vm.component; @@ -18,6 +19,7 @@ export default function preview(vm: { return ` + ${vm.preload ? `` : ''}