everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
325 lines (323 loc) • 12.4 kB
JavaScript
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
const require_config = require('../config.cjs');
const require_theme = require('../utils/theme.cjs');
const require_resolution_session = require('../resolution/session.cjs');
const require_mf = require('../mf.cjs');
const require_build = require('../build.cjs');
const require_code_artifacts = require('../code-artifacts.cjs');
const require_sync = require('../cli/sync.cjs');
const require_upgrade = require('../cli/upgrade.cjs');
let node_fs = require("node:fs");
let node_path = require("node:path");
let node_process = require("node:process");
node_process = require_runtime.__toESM(node_process, 1);
let node_child_process = require("node:child_process");
//#region src/commands/upgrade.ts
function registerUpgrade(builder) {
return {
sync: builder.sync.handler(async ({ input }) => {
try {
const configPath = require_config.findConfigPath();
if (!configPath) return {
status: "error",
updated: [],
skipped: [],
added: [],
error: `${require_config.MISSING_CONFIG_MESSAGE} in current directory`
};
const projectDir = (0, node_path.resolve)((0, node_path.dirname)(configPath));
const result = await require_sync.syncTemplate(projectDir, input);
if (result.status === "synced" || result.status === "dry-run") {
const syncedConfig = await require_resolution_session.openResolution({ cwd: projectDir });
if (syncedConfig?.config) await require_code_artifacts.generateCodeArtifacts(projectDir, syncedConfig.config);
}
return result;
} catch (error) {
return {
status: "error",
updated: [],
skipped: [],
added: [],
error: error instanceof Error ? error.message : "Unknown error"
};
}
}),
upgrade: builder.upgrade.handler(async ({ input }) => {
try {
const configPath = require_config.findConfigPath();
if (!configPath) return {
status: "error",
packages: [],
error: `${require_config.MISSING_CONFIG_MESSAGE} in current directory`
};
const projectDir = (0, node_path.resolve)((0, node_path.dirname)(configPath));
return await require_upgrade.upgradeTemplate(projectDir, input);
} catch (error) {
return {
status: "error",
packages: [],
error: error instanceof Error ? error.message : "Unknown error"
};
}
}),
typesGen: builder.typesGen.handler(async ({ input }) => {
try {
const configPath = require_config.findConfigPath();
if (!configPath) return {
status: "error",
generated: [],
fetched: [],
skipped: [],
failed: [],
error: `${require_config.MISSING_CONFIG_MESSAGE} in current directory`
};
const projectDir = (0, node_path.resolve)((0, node_path.dirname)(configPath));
const env = input.env ?? (node_process.default.env.NODE_ENV === "production" ? "production" : "development");
const refreshed = await require_resolution_session.openResolution({
cwd: projectDir,
env,
remotePlugins: input.remotePlugins
});
if (!refreshed?.config || !refreshed.runtime) return {
status: "error",
generated: [],
fetched: [],
skipped: [],
failed: [],
error: "Failed to load the authored config"
};
const runtime = refreshed.runtime;
const resolvedConfig = refreshed.config;
if (input.dryRun) {
const pluginEntries = Object.entries(runtime.plugins ?? {});
const fetched = [];
const skipped = [];
const hasLocalApiWorkspace = (0, node_fs.existsSync)((0, node_path.join)(projectDir, "api", "src"));
if (runtime.api.source !== "local") fetched.push(`api remote (${runtime.api.url})`);
else {
const path = runtime.api.localPath ? ` (${(0, node_path.relative)(projectDir, runtime.api.localPath)})` : "";
skipped.push(`api local${path}`);
}
if (runtime.auth) {
if (runtime.auth.source !== "local") fetched.push(`auth remote (${runtime.auth.url})`);
else {
const path = runtime.auth.localPath ? ` (${(0, node_path.relative)(projectDir, runtime.auth.localPath)})` : "";
skipped.push(`auth local${path}`);
}
}
for (const [key, plugin] of pluginEntries) if (plugin.url && plugin.source !== "local") fetched.push(`${key} remote (${plugin.url})`);
else if (plugin.localPath) skipped.push(`${key} local (${(0, node_path.relative)(projectDir, plugin.localPath)})`);
else skipped.push(`${key} no URL resolved`);
const generated = ["ui/src/lib/api-types.gen.ts", "ui/src/lib/auth-types.gen.ts"];
if (hasLocalApiWorkspace) generated.push("api/src/lib/plugins-types.gen.ts", "api/src/lib/auth-types.gen.ts");
if ((0, node_fs.existsSync)((0, node_path.join)(projectDir, "host", "src"))) generated.push("host/src/lib/auth-types.gen.ts");
for (const [_key, plugin] of pluginEntries) {
const localPath = plugin.localPath;
if (!localPath) continue;
const pluginSrc = (0, node_path.join)(localPath, "src", "lib", "plugins-client.gen.ts");
if ((0, node_fs.existsSync)(pluginSrc)) generated.push((0, node_path.relative)(projectDir, pluginSrc));
}
if (runtime.auth?.localPath) {
const authSrc = (0, node_path.join)(runtime.auth.localPath, "src", "lib", "plugins-client.gen.ts");
if ((0, node_fs.existsSync)(authSrc)) generated.push((0, node_path.relative)(projectDir, authSrc));
}
return {
status: "success",
generated,
fetched,
skipped,
failed: []
};
}
const artifacts = await require_code_artifacts.generateCodeArtifacts(projectDir, resolvedConfig, { runtimeConfig: runtime });
const hasLocalApiWorkspace = (0, node_fs.existsSync)((0, node_path.join)(projectDir, "api", "src"));
const generated = ["ui/src/lib/api-types.gen.ts"];
if (hasLocalApiWorkspace) generated.push("api/src/lib/plugins-types.gen.ts", "api/src/lib/auth-types.gen.ts");
if (runtime.auth && (runtime.auth.source !== "local" || runtime.auth.localPath)) generated.push("ui/src/lib/auth-types.gen.ts");
if ((0, node_fs.existsSync)((0, node_path.join)(projectDir, "host", "src"))) generated.push("host/src/lib/auth-types.gen.ts");
for (const [_key, plugin] of Object.entries(runtime.plugins ?? {})) {
const localPath = plugin.localPath;
if (!localPath) continue;
const pluginSrc = (0, node_path.join)(localPath, "src", "lib", "plugins-client.gen.ts");
if ((0, node_fs.existsSync)(pluginSrc)) generated.push((0, node_path.relative)(projectDir, pluginSrc));
}
if (runtime.auth?.localPath) {
const authSrc = (0, node_path.join)(runtime.auth.localPath, "src", "lib", "plugins-client.gen.ts");
if ((0, node_fs.existsSync)(authSrc)) generated.push((0, node_path.relative)(projectDir, authSrc));
}
const contractStatus = artifacts?.contractStatus ?? [];
const fetched = [];
const skipped = [];
const failed = [];
for (const entry of contractStatus) if (entry.source === "remote") fetched.push(entry.url ? `${entry.key} remote (${entry.url})` : entry.key);
else if (entry.source === "local") {
const path = entry.localPath ? ` (${(0, node_path.relative)(projectDir, entry.localPath)})` : "";
skipped.push(`${entry.key} local${path}`);
} else if (entry.source === "skipped") skipped.push(`${entry.key} no URL resolved`);
else if (entry.source === "failed") {
const detail = entry.error ? `: ${entry.error}` : "";
failed.push(`${entry.key}${detail}`);
}
return {
status: "success",
generated,
fetched,
skipped,
failed
};
} catch (error) {
return {
status: "error",
generated: [],
fetched: [],
skipped: [],
failed: [],
error: error instanceof Error ? error.message : "Unknown error"
};
}
}),
typecheck: builder.typecheck.handler(async ({ input }) => {
try {
const configPath = require_config.findConfigPath();
if (!configPath) return {
status: "error",
checked: [],
skipped: [],
results: [],
error: `${require_config.MISSING_CONFIG_MESSAGE} in current directory`
};
const projectDir = (0, node_path.resolve)((0, node_path.dirname)(configPath));
const refreshed = await require_resolution_session.openResolution({ cwd: projectDir });
if (!refreshed?.config || !refreshed.runtime) return {
status: "error",
checked: [],
skipped: [],
results: [],
error: "Failed to load the authored config"
};
const runtime = refreshed.runtime;
const resolvedConfig = refreshed.config;
await require_code_artifacts.generateCodeArtifacts(projectDir, resolvedConfig, { runtimeConfig: runtime });
const workspaceEntries = [];
const skipped = [];
const appTargets = [
{
key: "host",
label: "host",
target: runtime.host
},
{
key: "ui",
label: "ui",
target: runtime.ui
},
{
key: "api",
label: "api",
target: runtime.api
}
];
if (runtime.auth) appTargets.push({
key: "auth",
label: "auth",
target: runtime.auth
});
for (const entry of appTargets) if (entry.target?.source === "local" && entry.target.localPath && (0, node_fs.existsSync)((0, node_path.join)(entry.target.localPath, "tsconfig.json"))) workspaceEntries.push({
key: entry.key,
label: entry.label,
dir: entry.target.localPath
});
else skipped.push({
key: entry.key,
label: entry.label
});
for (const [key, plugin] of Object.entries(runtime.plugins ?? {})) {
const label = `plugins/${key}`;
if (plugin.source === "local" && plugin.localPath && (0, node_fs.existsSync)((0, node_path.join)(plugin.localPath, "tsconfig.json"))) workspaceEntries.push({
key,
label,
dir: plugin.localPath
});
else skipped.push({
key,
label
});
}
const selected = require_build.selectWorkspaceTargets(input.packages, resolvedConfig);
const targets = input.packages === "all" ? workspaceEntries : workspaceEntries.filter((entry) => selected.includes(entry.key));
const skippedEntries = input.packages === "all" ? skipped : skipped.filter((entry) => selected.includes(entry.key));
const checked = [];
const results = [];
for (const entry of targets) {
const packageJsonPath = (0, node_path.join)(entry.dir, "package.json");
let args = [
"exec",
"tsc",
"--noEmit"
];
if ((0, node_fs.existsSync)(packageJsonPath)) try {
if (JSON.parse((0, node_fs.readFileSync)(packageJsonPath, "utf-8")).scripts?.typecheck) args = ["run", "typecheck"];
} catch {}
console.log(`\n ${require_theme.colors.dim("Checking")} ${require_theme.colors.cyan(entry.label)}`);
const child = (0, node_child_process.spawnSync)("pnpm", args, {
cwd: entry.dir,
stdio: "inherit"
});
const passed = child.status === 0;
checked.push(entry.label);
results.push({
workspace: entry.label,
passed,
error: passed ? void 0 : `typecheck failed (exit code ${child.status ?? "n/a"})`
});
}
return {
status: "success",
checked,
skipped: skippedEntries.map((entry) => entry.label),
results
};
} catch (error) {
return {
status: "error",
checked: [],
skipped: [],
results: [],
error: error instanceof Error ? error.message : "Unknown error"
};
}
}),
mfCheck: builder.mfCheck.handler(async ({ input }) => {
let authored = null;
try {
authored = await require_config.readAuthoredConfigInput();
} catch (e) {
return {
status: "fail",
hostVersion: null,
hostReachable: false,
hostReason: e instanceof Error ? e.message : String(e),
remotes: []
};
}
if (!authored) return {
status: "fail",
hostVersion: null,
hostReachable: false,
hostReason: require_config.MISSING_CONFIG_MESSAGE,
remotes: []
};
const report = await require_mf.checkFederationCompat(authored, { timeoutMs: input.timeoutMs });
return {
status: report.ok ? "ok" : "fail",
hostVersion: report.hostVersion,
hostReachable: report.hostReachable,
hostReason: report.hostReason,
remotes: report.remotes
};
})
};
}
//#endregion
exports.registerUpgrade = registerUpgrade;
//# sourceMappingURL=upgrade.cjs.map