UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

150 lines (148 loc) • 5.77 kB
const require_http_client = require('../http-client.cjs'); const require_fastkv = require('../fastkv.cjs'); const require_config = require('../config.cjs'); const require_snapshot = require('./snapshot.cjs'); const require_framework_version = require('./framework-version.cjs'); let node_fs = require("node:fs"); let node_path = require("node:path"); //#region src/cli/status.ts const FRAMEWORK_PACKAGES = ["everything-dev", "every-plugin"]; const CATALOG_TOOL_PACKAGES = [ "@rspack/core", "@rspack/cli", "@rsbuild/core", "@rsbuild/plugin-react", "@module-federation/enhanced", "@module-federation/node", "@module-federation/rsbuild-plugin", "@module-federation/runtime-core", "@module-federation/sdk", "@module-federation/dts-plugin" ]; const PRERELEASE_PATTERN = /-[0-9A-Za-z.-]+$/; /** * The dist-tag to compare an installed version against: prerelease installs * track the `rc` dist-tag (the changesets pre-mode train), stable installs * track `latest`. Falls back to `latest` when no `rc` tag is published. */ function resolveUpdateDistTag(installed) { return installed && PRERELEASE_PATTERN.test(installed) ? "rc" : "latest"; } /** The version a given dist-tag currently points at, or null when absent. */ function pickDistTagVersion(distTags, tag) { return distTags?.[tag] ?? null; } const SEMVER_PATTERN = /^(?<core>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\+[\w.-]+)?$/; function parseVersion(version) { if (!version) return null; const match = SEMVER_PATTERN.exec(version.trim().replace(/^[\^~>=v]+/, "")); if (!match?.groups) return null; const prerelease = match.groups.prerelease ? match.groups.prerelease.split(".").map((id) => /^\d+$/.test(id) ? Number(id) : id) : []; return { core: [ Number(match.groups.core), Number(match.groups.minor), Number(match.groups.patch) ], prerelease }; } function comparePrerelease(a, b) { if (a.length === 0 && b.length === 0) return 0; if (a.length === 0) return 1; if (b.length === 0) return -1; const length = Math.max(a.length, b.length); for (let i = 0; i < length; i += 1) { const left = a[i]; const right = b[i]; if (left === void 0) return -1; if (right === void 0) return 1; if (typeof left === "number" && typeof right === "number") { if (left !== right) return left < right ? -1 : 1; } else if (typeof left === "number") return -1; else if (typeof right === "number") return 1; else if (left !== right) return left < right ? -1 : 1; } return 0; } /** * Semver-ordered comparison of two version strings: -1 when `a` is older than * `b`, 1 when newer, 0 when equal. Unparseable versions compare as equal — * the update check must never fire on versions it cannot order (that is how * an install ahead of npm got flagged "outdated" with a downgrade arrow). */ function compareSemver(a, b) { const left = parseVersion(a); const right = parseVersion(b); if (!left || !right) return 0; for (let i = 0; i < left.core.length; i += 1) if (left.core[i] !== right.core[i]) return left.core[i] < right.core[i] ? -1 : 1; return comparePrerelease(left.prerelease, right.prerelease); } async function fetchLatestNpmVersion(packageName, tag) { if (tag === "latest") return require_http_client.fetchJsonOrNull(`https://registry.npmjs.org/${packageName}/latest`, { headers: { Accept: "application/json" }, retries: 0 }).then((data) => data?.version ?? null); return pickDistTagVersion((await require_http_client.fetchJsonOrNull(`https://registry.npmjs.org/${packageName}`, { headers: { Accept: "application/vnd.npm.install-v1+json" }, retries: 0 }))?.["dist-tags"], tag); } function readInstalledVersion(projectDir, packageName) { return require_framework_version.readInstalledFrameworkVersion(projectDir, packageName); } function checkEnvFile(projectDir) { if ((0, node_fs.existsSync)((0, node_path.join)(projectDir, ".env"))) return "found"; if ((0, node_fs.existsSync)((0, node_path.join)(projectDir, ".env.example"))) return "example-only"; return "missing"; } async function checkParentReachable(extendsRef) { if (!extendsRef?.startsWith("bos://")) return void 0; try { return await require_fastkv.fetchBosConfigFromFastKv(extendsRef) !== null; } catch { return false; } } async function getStatus(projectDir) { const authored = await require_config.readAuthoredConfigInput(projectDir); if (!authored) return { status: "error", error: `${require_config.MISSING_CONFIG_MESSAGE} in current directory`, packages: [], envFile: "missing" }; const config = authored; const packageNames = [...FRAMEWORK_PACKAGES]; for (const name of CATALOG_TOOL_PACKAGES) if (readInstalledVersion(projectDir, name)) packageNames.push(name); const packages = await Promise.all(packageNames.map(async (name) => { const resolved = require_framework_version.resolveFrameworkPackage(projectDir, name); const latest = await fetchLatestNpmVersion(name, FRAMEWORK_PACKAGES.includes(name) ? resolveUpdateDistTag(resolved.installedVersion) : "latest"); return { name, installed: resolved.installedVersion, latest: latest ?? void 0, isLinked: resolved.isLinked, specifier: resolved.specifier }; })); const snapshot = await require_snapshot.readSnapshot(projectDir); const extendsRef = config.extends; const parentReachable = await checkParentReachable(extendsRef); return { status: "ok", extends: extendsRef, account: config.account, domain: config.domain, packages, lastSync: snapshot?.timestamp, envFile: checkEnvFile(projectDir), parentReachable }; } //#endregion exports.compareSemver = compareSemver; exports.getStatus = getStatus; exports.pickDistTagVersion = pickDistTagVersion; exports.resolveUpdateDistTag = resolveUpdateDistTag; //# sourceMappingURL=status.cjs.map