everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
1 lines • 15.5 kB
Source Map (JSON)
{"version":3,"file":"upgrade-packages.mjs","names":[],"sources":["../../../src/services/scaffold/upgrade-packages.ts"],"sourcesContent":["import { existsSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { glob } from \"glob\";\nimport { readAuthoredConfigInput } from \"../../config\";\nimport { getExtendsRef } from \"../../utils/bos-ref\";\nimport { readJsonFile } from \"../../utils/json-file\";\nimport { readInstalledFrameworkVersion } from \"../framework-version\";\nimport { readWorkspaceCatalog, writeWorkspaceCatalog } from \"../workspace/catalog\";\nimport { findWorkspaceRoot } from \"../workspace/workspace\";\nimport { buildChildRootScripts, getParentOnlyScriptKeys } from \"./init\";\n\nexport const FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\nexport const AUTH_CORE_PACKAGE = \"@better-auth/core\";\nexport const AUTH_CORE_TRIGGER_PACKAGES = [\n \"better-auth\",\n \"better-near-auth\",\n \"@better-auth/api-key\",\n \"@better-auth/passkey\",\n] as const;\n\nexport function workspaceDirOf(projectDir: string): string {\n return findWorkspaceRoot(projectDir)?.dir ?? projectDir;\n}\n\nexport function readRootPackageJson(projectDir: string): Record<string, unknown> {\n return readJsonFile<Record<string, unknown>>(join(workspaceDirOf(projectDir), \"package.json\"));\n}\n\nexport function readRootCatalogEntry(projectDir: string, packageName: string): string | undefined {\n return readWorkspaceCatalog(workspaceDirOf(projectDir))[packageName];\n}\n\n/**\n * Chain-catalog vs local-catalog diff for the drift alarm (ADR 0034 pt 6):\n * entries only count when the local catalog actually pins a different version\n * (`from !== undefined`) — a purely-additive chain entry the child does not\n * consume is not drift. Reading the local catalog is `readWorkspaceCatalog`\n * (pnpm-workspace.yaml first, package.json fallback) — the v1 package.json-only\n * read made every entry read as new on v2 children, a permanent false positive.\n */\nexport function diffCatalogEntries(\n sourceRootCatalog: Record<string, string>,\n currentCatalogEntries: Record<string, string>,\n): Array<{ name: string; from: string | undefined; to: string }> {\n const updates: Array<{ name: string; from: string | undefined; to: string }> = [];\n for (const [name, targetVersion] of Object.entries(sourceRootCatalog)) {\n if (FRAMEWORK_PACKAGES.includes(name)) continue;\n const currentVersion = currentCatalogEntries[name];\n if (currentVersion === targetVersion) continue;\n updates.push({ name, from: currentVersion, to: targetVersion });\n }\n return updates;\n}\n\nexport function readCurrentPackageSpecifier(\n projectDir: string,\n packageName: string,\n): string | undefined {\n const pkg = readRootPackageJson(projectDir);\n\n for (const fieldName of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const field = pkg[fieldName] as Record<string, string> | undefined;\n const value = field?.[packageName];\n if (!value) continue;\n\n if (value === \"catalog:\") {\n return (\n readRootCatalogEntry(projectDir, packageName) ??\n readInstalledVersion(projectDir, packageName)\n );\n }\n\n if (value.startsWith(\"workspace:\") || value.startsWith(\"file:\") || value.startsWith(\"link:\")) {\n return readInstalledVersion(projectDir, packageName);\n }\n\n return value;\n }\n\n return (\n readRootCatalogEntry(projectDir, packageName) ?? readInstalledVersion(projectDir, packageName)\n );\n}\n\nfunction setCatalogRefs(\n field: Record<string, string> | undefined,\n packageNames: ReadonlyArray<string>,\n): boolean {\n if (!field) return false;\n\n let modified = false;\n for (const packageName of packageNames) {\n if (setCatalogRef(field, packageName)) {\n modified = true;\n }\n }\n\n return modified;\n}\n\nfunction syncPackageObjectCatalogRefs(\n pkg: Record<string, unknown>,\n packageNames: ReadonlyArray<string>,\n): boolean {\n let modified = false;\n\n for (const fieldName of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const field = pkg[fieldName] as Record<string, string> | undefined;\n if (setCatalogRefs(field, packageNames)) {\n modified = true;\n }\n }\n\n return modified;\n}\n\nfunction findPackageFieldWithAnyDependency(\n pkg: Record<string, unknown>,\n packageNames: ReadonlyArray<string>,\n): Record<string, string> | undefined {\n for (const fieldName of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const field = pkg[fieldName] as Record<string, string> | undefined;\n if (!field) continue;\n if (packageNames.some((packageName) => typeof field[packageName] === \"string\")) {\n return field;\n }\n }\n\n return undefined;\n}\n\nexport function packageObjectNeedsAuthCoreCatalogRef(pkg: Record<string, unknown>): boolean {\n const targetField = findPackageFieldWithAnyDependency(pkg, AUTH_CORE_TRIGGER_PACKAGES);\n if (!targetField) return false;\n\n for (const fieldName of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const field = pkg[fieldName] as Record<string, string> | undefined;\n if (field?.[AUTH_CORE_PACKAGE]) return false;\n }\n\n return true;\n}\n\nexport function ensureAuthCoreCatalogRef(pkg: Record<string, unknown>): boolean {\n if (!packageObjectNeedsAuthCoreCatalogRef(pkg)) return false;\n\n const targetField = findPackageFieldWithAnyDependency(pkg, AUTH_CORE_TRIGGER_PACKAGES);\n if (!targetField) return false;\n\n targetField[AUTH_CORE_PACKAGE] = \"catalog:\";\n return true;\n}\n\nexport function packageObjectNeedsCatalogRefs(\n pkg: Record<string, unknown>,\n packageNames: ReadonlyArray<string>,\n): boolean {\n for (const fieldName of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const field = pkg[fieldName] as Record<string, string> | undefined;\n if (!field) continue;\n\n for (const packageName of packageNames) {\n const value = field[packageName];\n if (!value) continue;\n if (value !== \"catalog:\" && !value.startsWith(\"file:\") && !value.startsWith(\"link:\")) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function packageFileNeedsCatalogRefs(\n filePath: string,\n packageNames: ReadonlyArray<string>,\n): boolean {\n return packageObjectNeedsCatalogRefs(\n readJsonFile<Record<string, unknown>>(filePath),\n packageNames,\n );\n}\n\nexport function updatePackageFileCatalogRefs(\n filePath: string,\n packageNames: ReadonlyArray<string>,\n): boolean {\n const pkg = readJsonFile<Record<string, unknown>>(filePath);\n const modified = syncPackageObjectCatalogRefs(pkg, packageNames);\n\n if (modified) {\n writeFileSync(filePath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n return modified;\n}\n\nexport function updatePackageFileAuthCoreRef(filePath: string): boolean {\n const pkg = readJsonFile<Record<string, unknown>>(filePath);\n const modified = ensureAuthCoreCatalogRef(pkg);\n\n if (modified) {\n writeFileSync(filePath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n return modified;\n}\n\nexport function syncRootCatalogWithParent(\n projectDir: string,\n parentCatalog: Record<string, string>,\n): boolean {\n const workspaceDir = workspaceDirOf(projectDir);\n const pkgPath = join(workspaceDir, \"package.json\");\n const pkg = readJsonFile<Record<string, unknown>>(pkgPath);\n const modified = syncPackageObjectCatalogRefs(pkg, Object.keys(parentCatalog));\n\n let catalogChanged = false;\n const catalog = readWorkspaceCatalog(workspaceDir);\n for (const [packageName, version] of Object.entries(parentCatalog)) {\n if (catalog[packageName] !== version) {\n catalog[packageName] = version;\n catalogChanged = true;\n }\n }\n if (catalogChanged) {\n writeWorkspaceCatalog(workspaceDir, catalog);\n }\n\n if (modified) {\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n return modified || catalogChanged;\n}\n\nexport function readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nexport function setCatalogRef(\n field: Record<string, string> | undefined,\n packageName: string,\n): boolean {\n if (!field || !(packageName in field)) return false;\n if (field[packageName] === \"catalog:\" || field[packageName].startsWith(\"file:\")) return false;\n field[packageName] = \"catalog:\";\n return true;\n}\n\nexport async function findWorkspacePackageJsons(projectDir: string): Promise<string[]> {\n const root = findWorkspaceRoot(projectDir);\n if (!root) return [];\n\n const pkgPaths: string[] = [];\n for (const member of root.members) {\n const pkgPath = join(member.dir, \"package.json\");\n if (existsSync(pkgPath) && statSync(pkgPath).isFile()) {\n pkgPaths.push(pkgPath);\n }\n }\n\n return [...new Set(pkgPaths)];\n}\n\nexport async function migrateChildRootPackageJson(projectDir: string): Promise<boolean> {\n const config = (await readAuthoredConfigInput(projectDir)) as Record<string, unknown> | null;\n const pkgPath = join(workspaceDirOf(projectDir), \"package.json\");\n if (!config || !existsSync(pkgPath)) {\n return false;\n }\n\n const extendsRef = getExtendsRef(config);\n if (!extendsRef?.startsWith(\"bos://\")) {\n return false;\n }\n\n const pkg = readJsonFile<Record<string, unknown>>(pkgPath);\n let changed = false;\n\n if (pkg.private !== true) {\n pkg.private = true;\n changed = true;\n }\n if (pkg.type !== \"module\") {\n pkg.type = \"module\";\n changed = true;\n }\n if (\"module\" in pkg) {\n delete pkg.module;\n changed = true;\n }\n\n const pluginPackageJsons = await glob(\"plugins/*/package.json\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n });\n const childScripts = buildChildRootScripts({\n ui: existsSync(join(projectDir, \"ui\", \"package.json\")),\n api: existsSync(join(projectDir, \"api\", \"package.json\")),\n host: existsSync(join(projectDir, \"host\", \"package.json\")),\n plugins: pluginPackageJsons.length > 0,\n });\n\n if (!pkg.scripts || typeof pkg.scripts !== \"object\") {\n pkg.scripts = {};\n changed = true;\n }\n const scripts = pkg.scripts as Record<string, string>;\n for (const [key, value] of Object.entries(childScripts)) {\n if (scripts[key] !== value) {\n scripts[key] = value;\n changed = true;\n }\n }\n for (const obsoleteScript of [...getParentOnlyScriptKeys(projectDir), \"sync-catalog\", \"init\"]) {\n if (obsoleteScript in scripts) {\n delete scripts[obsoleteScript];\n changed = true;\n }\n }\n if (changed) {\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n return changed;\n}\n"],"mappings":"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"}