feat: complete SSR CRM and refine auth UI
Quality / quality (ubuntu-latest) (push) Failing after 11m17s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-20 16:17:59 +05:30
parent f57bd05a03
commit cd0dffa87d
49 changed files with 1640 additions and 139 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/cli",
"version": "0.8.46",
"version": "0.8.47",
"type": "module",
"main": "src/index.ts",
"exports": {
+72 -5
View File
@@ -14,15 +14,23 @@
* (`databases.<name>`), with files under `app/db/<name>/`.
*/
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
import { join, resolve } from "node:path";
import { existsSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
import { basename, join, resolve } from "node:path";
import { pathToFileURL } from "node:url";
import {
createPluginRunner,
discoverPlugins,
type PackageMigrationDefinition,
} from "@wrnexus/plugin";
import { loadAppConfig, type AppConfig } from "@wrnexus/styles";
import {
generateQueriesFile,
analyzeMigrations,
appliedMigrations,
applyMigrations,
loadMigrations,
migrate,
parseMigration,
parseQueries,
rollback,
scaffoldMigration,
@@ -42,6 +50,55 @@ function dbBaseOf(appDir: string, dbName: string | null): string {
return dbName ? join(appDir, "db", dbName) : join(appDir, "db");
}
function packageMigrationName(definition: PackageMigrationDefinition, name?: string): string {
const clean = (value: string) => value.trim().replace(/[^a-zA-Z0-9_.-]+/g, "_");
return name ? `${clean(definition.id)}__${clean(name)}` : clean(definition.id);
}
function resolvePackageMigrations(
definitions: readonly PackageMigrationDefinition[],
database?: string,
) {
return definitions.flatMap((definition) => {
if ((definition.database?.trim() || "default") !== (database?.trim() || "default")) return [];
if (definition.source !== undefined) {
return [parseMigration(packageMigrationName(definition), definition.source)];
}
if (!definition.entry || !existsSync(definition.entry)) {
throw new Error(`WRN-PLUGIN-MIGRATION-MISSING: ${definition.id} has no readable entry.`);
}
if (statSync(definition.entry).isDirectory()) {
return loadMigrations(definition.entry).map((migration) => ({
...migration,
name: packageMigrationName(definition, migration.name),
}));
}
return [
parseMigration(
packageMigrationName(definition, basename(definition.entry, ".sql")),
readFileSync(definition.entry, "utf8"),
),
];
});
}
async function packageMigrations(root: string, config: AppConfig, database?: string) {
const discovered = await discoverPlugins(root, config.plugins, {
includeDevDependencies: true,
strict: true,
});
const runner = createPluginRunner(discovered, {
root,
mode: "development",
command: "dev",
metadata: new Map(),
warn: (message) => console.warn(`[wrnexus:plugin] ${message}`),
});
await runner.configure(config as Record<string, unknown>);
await runner.configResolved(config as Readonly<Record<string, unknown>>);
return resolvePackageMigrations((await runner.contributions()).migrations, database);
}
/** List user tables for the connected database (dialect-aware introspection). */
async function listTables(db: import("@wrnexus/db").Db): Promise<string[]> {
const dialect = db.driver.dialect;
@@ -126,6 +183,7 @@ export async function runDbCommand(
const dbConfig = dbName ? config.databases?.[dbName] : config.db;
const dbBase = dbBaseOf(appDir, dbName);
const migrationsDir = join(dbBase, "migrations");
const contributedMigrations = await packageMigrations(root, config, dbName ?? undefined);
const label = dbName ? ` (db: ${dbName})` : "";
const safetyIssues = analyzeMigrations(loadMigrations(migrationsDir));
@@ -242,7 +300,10 @@ export async function runDbCommand(
`WRN-DB-UNSAFE-MIGRATION: ${blockers.length} breaking rollout operation(s) found. Run 'wrnexus db check' and use an expand/contract migration; --allow-breaking explicitly overrides this gate.`,
);
}
const applied = await migrate(db, migrationsDir);
const applied = [
...(await migrate(db, migrationsDir)),
...(await applyMigrations(db, contributedMigrations)),
];
console.log(
applied.length
? `✓ Applied ${applied.length}${label}:\n ${applied.join("\n ")}`
@@ -257,8 +318,14 @@ export async function runDbCommand(
}
case "status": {
const rows = await status(db, migrationsDir);
if (rows.length === 0) console.log(`No migrations found in ${migrationsDir}.`);
else for (const r of rows) console.log(` [${r.applied ? "x" : " "}] ${r.name}`);
const applied = new Set(await appliedMigrations(db));
const packageRows = contributedMigrations.map(({ name }) => ({
name,
applied: applied.has(name),
}));
const allRows = [...rows, ...packageRows];
if (allRows.length === 0) console.log(`No migrations found in ${migrationsDir}.`);
else for (const r of allRows) console.log(` [${r.applied ? "x" : " "}] ${r.name}`);
break;
}
default:
-1
View File
@@ -23,7 +23,6 @@ import {
mkdirSync,
readFileSync,
readdirSync,
rmSync,
statSync,
writeFileSync,
} from "node:fs";