release: WRNexusJS 0.8.0
This commit is contained in:
+115
-1
@@ -30,6 +30,7 @@ import {
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { basename, dirname, join, relative, resolve } from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { formatWrn, parse } from "@wrnexus/syntax";
|
||||
import { AI_GUIDE, CLAUDE_MD } from "./ai-guide.ts";
|
||||
import { inspectProject, type DoctorCheck } from "./doctor.ts";
|
||||
|
||||
@@ -189,7 +190,20 @@ function quoteLegacyDynamicAttributes(source: string): string {
|
||||
}
|
||||
|
||||
export function migrateWrnSource(source: string): string {
|
||||
return formatInlineProps(quoteLegacyDynamicAttributes(source));
|
||||
return formatInlineProps(quoteLegacyDynamicAttributes(source))
|
||||
.replace(/[ \t]+$/gm, "")
|
||||
.replace(/\r\n?/g, "\n")
|
||||
.replace(/\n{3,}$/g, "\n\n")
|
||||
.replace(/\s*$/, "\n");
|
||||
}
|
||||
|
||||
export function formatCurrentWrnSource(source: string): string {
|
||||
return formatWrn(migrateWrnSource(source), {
|
||||
insertSpaces: true,
|
||||
tabSize: 2,
|
||||
printWidth: 100,
|
||||
multilineAttributes: true,
|
||||
});
|
||||
}
|
||||
|
||||
function findMatching(source: string, open: number, openChar = "{", closeChar = "}"): number {
|
||||
@@ -1857,6 +1871,106 @@ const MIGRATIONS: Migration[] = [
|
||||
if (!ctx.report.needsReview.includes(review)) ctx.report.needsReview.push(review);
|
||||
},
|
||||
},
|
||||
{
|
||||
version: "0.8.0",
|
||||
id: "0.8.0-01-package-kits",
|
||||
description:
|
||||
"Adds package-owned helper kits, reusable UI blocks, standalone realtime rooms, repaired i18n, image helpers, JWT utilities, and encrypted HTTP envelopes.",
|
||||
apply(ctx) {
|
||||
const file = join(ctx.appRoot, "package.json");
|
||||
if (!existsSync(file)) return;
|
||||
const pkg = JSON.parse(readFileSync(file, "utf8")) as Record<string, any>;
|
||||
const dependencies = (pkg.dependencies ??= {});
|
||||
const additions = ["@wrnexus/realtime", "@wrnexus/csr"];
|
||||
const added: string[] = [];
|
||||
for (const name of additions) {
|
||||
if (dependencies[name] === `^${ctx.to}`) continue;
|
||||
dependencies[name] = `^${ctx.to}`;
|
||||
added.push(name);
|
||||
}
|
||||
if (added.length) {
|
||||
ctx.log(`+ package-kit dependencies: ${added.join(", ")}`);
|
||||
if (!ctx.dryRun) writeFileSync(file, JSON.stringify(pkg, null, 2) + "\n", "utf8");
|
||||
}
|
||||
const review =
|
||||
"Review package-owned components and helpers, i18n locale layout, encrypted HTTP trust boundaries, and realtime room authorization before enabling them in production.";
|
||||
if (!ctx.report.needsReview.includes(review)) ctx.report.needsReview.push(review);
|
||||
},
|
||||
},
|
||||
{
|
||||
version: "0.8.0",
|
||||
id: "0.8.0-02-current-wrn-source",
|
||||
description:
|
||||
"Upgrades every application WRN source to current syntax, adds resolvable imports, normalizes formatting, and records unresolved work.",
|
||||
apply(ctx) {
|
||||
const appDirectory = join(ctx.appRoot, "app");
|
||||
if (!existsSync(appDirectory)) return;
|
||||
const index = buildV060SymbolIndex(ctx.appRoot);
|
||||
const changedFiles: string[] = [];
|
||||
|
||||
for (const file of walkProjectFiles(appDirectory, ".wrn")) {
|
||||
const relativeFile = relative(ctx.appRoot, file).replace(/\\/g, "/");
|
||||
const before = readFileSync(file, "utf8");
|
||||
let after = migrateV060WrnSource(before, ctx.report, relativeFile);
|
||||
after = migrateImportedLayout(after, relativeFile, ctx.appRoot, index, ctx.report);
|
||||
after = addExplicitImportsToSource(after, relativeFile, ctx.appRoot, index, ctx.report);
|
||||
after = formatCurrentWrnSource(after);
|
||||
if (after === before) continue;
|
||||
|
||||
try {
|
||||
parse(after);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message.split("\n", 1)[0] : String(error);
|
||||
ctx.report.parseFailures.push(`${relativeFile}: ${message}`);
|
||||
ctx.report.needsReview.push(
|
||||
`${relativeFile}: automatic modernization was skipped because the migrated source did not parse`,
|
||||
);
|
||||
ctx.log(`! ${relativeFile}: left unchanged because migrated source did not parse`);
|
||||
continue;
|
||||
}
|
||||
|
||||
changedFiles.push(relativeFile);
|
||||
if (!ctx.report.changedAutomatically.includes(relativeFile)) {
|
||||
ctx.report.changedAutomatically.push(relativeFile);
|
||||
}
|
||||
ctx.log(`~ ${relativeFile}: current WRN syntax, imports, and formatting`);
|
||||
if (!ctx.dryRun) writeFileSync(file, after, "utf8");
|
||||
}
|
||||
|
||||
const reportFile = join(
|
||||
ctx.appRoot,
|
||||
".wrnexus",
|
||||
"migrations",
|
||||
"0.8.0-source-modernization.json",
|
||||
);
|
||||
ctx.log(
|
||||
`+ .wrnexus/migrations/0.8.0-source-modernization.json (${changedFiles.length} WRN files updated)`,
|
||||
);
|
||||
if (!ctx.dryRun) {
|
||||
mkdirSync(dirname(reportFile), { recursive: true });
|
||||
writeFileSync(
|
||||
reportFile,
|
||||
JSON.stringify(
|
||||
{
|
||||
version: "0.8.0",
|
||||
from: ctx.from,
|
||||
to: ctx.to,
|
||||
appliedAt: new Date().toISOString(),
|
||||
changedFiles,
|
||||
unresolvedImports: ctx.report.unresolvedImports,
|
||||
ambiguousFunctions: ctx.report.ambiguousFunctions,
|
||||
legacyOutputPayloads: ctx.report.legacyOutputPayloads,
|
||||
parseFailures: ctx.report.parseFailures,
|
||||
needsReview: ctx.report.needsReview,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
) + "\n",
|
||||
"utf8",
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
/** Release tooling uses this to require an explicit migration entry per version. */
|
||||
|
||||
Reference in New Issue
Block a user