release: WRNexusJS 0.5.0
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
* the running process while the HMR socket morphs fresh HTML into the browser.
|
||||
*/
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve, dirname, isAbsolute, join } from "node:path";
|
||||
import type { Middleware, Mode, SecurityConfig, SeoConfig } from "@wrnexus/core";
|
||||
import { buildRouter, type Router } from "@wrnexus/router";
|
||||
@@ -16,7 +17,7 @@ import {
|
||||
type MobileConfig,
|
||||
type PwaConfig,
|
||||
} from "@wrnexus/styles";
|
||||
import { uiComponentsDir, uiCss } from "@wrnexus/ui";
|
||||
import { uiComponentsDir, uiCssPath } from "@wrnexus/ui";
|
||||
import { renderSchemasScript, type ObjectSchema, type SchemaDescriptor } from "@wrnexus/validation";
|
||||
import { loadLocales, resolveI18n, type I18nConfig } from "@wrnexus/i18n";
|
||||
import { applyMigrations, migrate, setDb, registerDb } from "@wrnexus/db";
|
||||
@@ -46,6 +47,7 @@ export interface ServeOptions {
|
||||
mode?: Mode;
|
||||
/** Inject the live-reload client (defaults to true in development). */
|
||||
hmr?: boolean;
|
||||
appConfig?: Record<string, unknown>;
|
||||
/** Resolved absolute path to the global CSS entry, or null. */
|
||||
styleEntry?: string | null;
|
||||
/** Custom styles config (e.g. a Tailwind/PostCSS processor). */
|
||||
@@ -162,11 +164,14 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
|
||||
const appDir = resolve(opts.appDir);
|
||||
const appRoot = dirname(appDir);
|
||||
const mode: Mode = opts.mode ?? "development";
|
||||
const discoveredPlugins = await discoverPlugins(appRoot, opts.plugins, {
|
||||
const configuredPlugins = opts.plugins ?? (opts.appConfig?.plugins as PluginInput | undefined);
|
||||
|
||||
const discoveredPlugins = await discoverPlugins(appRoot, configuredPlugins, {
|
||||
includeDevDependencies: true,
|
||||
strict: true,
|
||||
warn: (message) => console.warn(`[wrnexus:plugin] ${message}`),
|
||||
});
|
||||
|
||||
const pluginRunner = createPluginRunner(discoveredPlugins, {
|
||||
root: appRoot,
|
||||
mode,
|
||||
@@ -174,11 +179,64 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
|
||||
metadata: new Map(),
|
||||
warn: (message) => console.warn(`[wrnexus:plugin] ${message}`),
|
||||
});
|
||||
await pluginRunner.configure(opts as unknown as Record<string, unknown>);
|
||||
|
||||
/**
|
||||
* Plugins must receive the complete
|
||||
* wrnexus.config.ts object.
|
||||
*
|
||||
* ServeOptions only contains framework-known
|
||||
* properties. Package-specific configuration,
|
||||
* such as `auth`, is stored in appConfig.
|
||||
*/
|
||||
const pluginConfig: Record<string, unknown> = {
|
||||
...(opts.appConfig ?? {}),
|
||||
|
||||
// Resolved runtime values take priority.
|
||||
appDir,
|
||||
port: opts.port,
|
||||
hostname: opts.hostname,
|
||||
mode,
|
||||
hmr: opts.hmr,
|
||||
|
||||
styleEntry: opts.styleEntry,
|
||||
|
||||
styles: opts.stylesConfig ?? (opts.appConfig?.styles as StylesConfig | undefined),
|
||||
|
||||
head: opts.head,
|
||||
seo: opts.seo,
|
||||
security: opts.security,
|
||||
theme: opts.theme,
|
||||
i18n: opts.i18n,
|
||||
db: opts.db,
|
||||
databases: opts.databases,
|
||||
realtime: opts.realtime,
|
||||
storage: opts.storage,
|
||||
mobile: opts.mobile,
|
||||
pwa: opts.pwa,
|
||||
devToolbar: opts.devToolbar,
|
||||
plugins: configuredPlugins,
|
||||
observability: opts.observability,
|
||||
tenancy: opts.tenancy,
|
||||
};
|
||||
|
||||
await pluginRunner.configure(pluginConfig);
|
||||
|
||||
await pluginRunner.configResolved(
|
||||
Object.freeze({ ...opts }) as Readonly<Record<string, unknown>>,
|
||||
Object.freeze({
|
||||
...pluginConfig,
|
||||
}),
|
||||
);
|
||||
|
||||
const pluginContributions = await pluginRunner.contributions();
|
||||
|
||||
console.log(
|
||||
`[wrnexus:plugin] discovered: ${
|
||||
pluginRunner.plugins.map((plugin) => plugin.name).join(", ") || "none"
|
||||
}`,
|
||||
);
|
||||
|
||||
console.log(`[wrnexus:plugin] contributed routes: ${pluginContributions.routes.length}`);
|
||||
|
||||
const pluginToolbarPanels = await pluginRunner.devToolbarPanels();
|
||||
const componentDirs = [uiComponentsDir(), ...pluginContributions.componentDirs];
|
||||
|
||||
@@ -209,7 +267,7 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
|
||||
// `.wrnexus/` next to each source file (and inside node_modules UI dirs).
|
||||
setCompileCacheDir(join(appRoot, ".wrnexus"));
|
||||
const theme = resolveThemeConfig(opts.theme);
|
||||
const uiStyles = uiCss();
|
||||
const uiStylesPath = uiCssPath();
|
||||
|
||||
const schemasJs = await schemaRuntime(router);
|
||||
|
||||
@@ -268,7 +326,7 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
|
||||
entries: pluginContributions.styles.flatMap((style) => (style.entry ? [style.entry] : [])),
|
||||
},
|
||||
theme,
|
||||
uiStyles,
|
||||
() => readFileSync(uiStylesPath, "utf8"),
|
||||
schemasJs,
|
||||
pluginAssetsFromContributions(pluginContributions),
|
||||
);
|
||||
@@ -407,6 +465,7 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
|
||||
});
|
||||
};
|
||||
const packageWatchDirs = [
|
||||
dirname(uiStylesPath),
|
||||
...componentDirs,
|
||||
...pluginContributions.clientRuntimes.flatMap((runtime) =>
|
||||
runtime.entry ? [dirname(runtime.entry)] : [],
|
||||
|
||||
Reference in New Issue
Block a user