release: WRNexusJS 0.4.0

This commit is contained in:
2026-07-27 12:42:18 +05:30
parent 8b728a3e5d
commit 30e5721e84
250 changed files with 10065 additions and 3923 deletions
+68 -2
View File
@@ -3,6 +3,7 @@ import { extname, join, resolve } from "node:path";
import { diagnose } from "@wrnexus/syntax";
import { buildRouter, findRouteConflicts } from "@wrnexus/router";
import { loadAppConfig, validateAppConfig } from "@wrnexus/styles";
import { createPluginRunner, discoverPlugins } from "@wrnexus/plugin";
export interface DoctorCheck {
name: string;
@@ -85,8 +86,13 @@ export function inspectProject(appRoot: string): DoctorCheck[] {
const marker = (pkg.wrnexus as { version?: string } | undefined)?.version;
checks.push({
name: "update marker",
ok: !marker || versionAtLeast(marker, "0.3.0"),
detail: marker ? `project last migrated to ${marker}` : "missing; run `wrnexus update`",
ok: !marker || versionAtLeast(marker, "0.4.0"),
detail:
marker && versionAtLeast(marker, "0.4.0")
? `project last migrated to ${marker}`
: marker
? `project is on ${marker}; run \`wrnexus update 0.4.0\``
: "missing; run `wrnexus update`",
level: "warning",
});
} catch {
@@ -182,6 +188,66 @@ export async function runDoctor(appRoot: string): Promise<boolean> {
: "valid",
level: issues.some((issue) => issue.severity === "error") ? "error" : "warning",
});
const discovered = await discoverPlugins(root, config.plugins, {
includeDevDependencies: true,
strict: true,
warn: (message) =>
checks.push({ name: "package plugin discovery", ok: false, detail: message }),
});
const runner = createPluginRunner(discovered, {
root,
mode: "development",
command: "dev",
metadata: new Map(),
warn: () => {},
});
await runner.configure(config as Record<string, unknown>);
await runner.configResolved(config as Readonly<Record<string, unknown>>);
const contributions = await runner.contributions();
checks.push({
name: "package plugins",
ok: true,
detail: `${runner.plugins.length} plugins, ${contributions.clientRuntimes.length} runtimes, ${contributions.assets.length} assets, ${contributions.routes.length} routes, ${contributions.migrations.length} migrations`,
});
const missingContributions = [
...contributions.componentDirs.map((path) => ({ kind: "component directory", path })),
...contributions.clientRuntimes
.filter((runtime) => runtime.entry)
.map((runtime) => ({ kind: `runtime ${runtime.id}`, path: runtime.entry! })),
...contributions.assets
.filter((asset) => asset.entry)
.map((asset) => ({ kind: `asset ${asset.id}`, path: asset.entry! })),
...contributions.routes.map((route) => ({
kind: `${route.kind} route ${route.path}`,
path: route.entry,
})),
...contributions.middleware.map((path) => ({ kind: "middleware", path })),
...contributions.migrations
.filter((migration) => migration.entry)
.map((migration) => ({ kind: `migration ${migration.id}`, path: migration.entry! })),
].filter((entry) => !existsSync(entry.path));
checks.push({
name: "package contribution files",
ok: missingContributions.length === 0,
detail: missingContributions.length
? missingContributions.map((entry) => `${entry.kind}: ${entry.path}`).join("; ")
: "all discovered contribution files exist",
});
const legacyCaptchaAssets = [
"public/assets/wrnexus/captcha.js",
"public/__wrnexus/captcha.js",
].filter((path) => existsSync(join(root, path)));
checks.push({
name: "legacy CAPTCHA runtime copies",
ok: legacyCaptchaAssets.length === 0,
detail: legacyCaptchaAssets.length
? `remove with wrnexus update 0.4.0: ${legacyCaptchaAssets.join(", ")}`
: "none; CAPTCHA runtime is package-managed",
level: "warning",
});
} catch (error) {
checks.push({
name: "resolved configuration",