everything-dev 1.26.1 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/api-contract.cjs.map +1 -1
  2. package/dist/api-contract.mjs.map +1 -1
  3. package/dist/cli/catalog.cjs.map +1 -1
  4. package/dist/cli/catalog.mjs.map +1 -1
  5. package/dist/cli/framework-version.cjs.map +1 -1
  6. package/dist/cli/framework-version.mjs.map +1 -1
  7. package/dist/cli/infra.cjs +1 -1
  8. package/dist/cli/infra.cjs.map +1 -1
  9. package/dist/cli/infra.mjs +1 -1
  10. package/dist/cli/infra.mjs.map +1 -1
  11. package/dist/cli/init.cjs +127 -121
  12. package/dist/cli/init.cjs.map +1 -1
  13. package/dist/cli/init.d.cts +6 -6
  14. package/dist/cli/init.d.cts.map +1 -1
  15. package/dist/cli/init.d.mts +6 -6
  16. package/dist/cli/init.d.mts.map +1 -1
  17. package/dist/cli/init.mjs +125 -121
  18. package/dist/cli/init.mjs.map +1 -1
  19. package/dist/cli/parse.cjs.map +1 -1
  20. package/dist/cli/parse.mjs.map +1 -1
  21. package/dist/cli/prompts.cjs +29 -25
  22. package/dist/cli/prompts.cjs.map +1 -1
  23. package/dist/cli/prompts.mjs +28 -25
  24. package/dist/cli/prompts.mjs.map +1 -1
  25. package/dist/cli/status.cjs.map +1 -1
  26. package/dist/cli/status.mjs.map +1 -1
  27. package/dist/cli/sync.cjs +46 -93
  28. package/dist/cli/sync.cjs.map +1 -1
  29. package/dist/cli/sync.mjs +49 -96
  30. package/dist/cli/sync.mjs.map +1 -1
  31. package/dist/cli/timing.cjs.map +1 -1
  32. package/dist/cli/timing.mjs.map +1 -1
  33. package/dist/cli/upgrade.cjs +41 -20
  34. package/dist/cli/upgrade.cjs.map +1 -1
  35. package/dist/cli/upgrade.mjs +43 -22
  36. package/dist/cli/upgrade.mjs.map +1 -1
  37. package/dist/cli.cjs +187 -12
  38. package/dist/cli.cjs.map +1 -1
  39. package/dist/cli.mjs +187 -12
  40. package/dist/cli.mjs.map +1 -1
  41. package/dist/components/dev-view.cjs.map +1 -1
  42. package/dist/components/dev-view.mjs.map +1 -1
  43. package/dist/components/streaming-view.cjs.map +1 -1
  44. package/dist/components/streaming-view.mjs.map +1 -1
  45. package/dist/config.cjs.map +1 -1
  46. package/dist/config.mjs.map +1 -1
  47. package/dist/contract.cjs +174 -173
  48. package/dist/contract.cjs.map +1 -1
  49. package/dist/contract.d.cts +48 -44
  50. package/dist/contract.d.cts.map +1 -1
  51. package/dist/contract.d.mts +48 -44
  52. package/dist/contract.d.mts.map +1 -1
  53. package/dist/contract.mjs +3 -1
  54. package/dist/contract.mjs.map +1 -1
  55. package/dist/dev-logs.cjs.map +1 -1
  56. package/dist/dev-logs.mjs.map +1 -1
  57. package/dist/dev-session.cjs +0 -1
  58. package/dist/dev-session.mjs +1 -1
  59. package/dist/fastkv.cjs.map +1 -1
  60. package/dist/fastkv.mjs.map +1 -1
  61. package/dist/index.cjs +2 -4
  62. package/dist/index.d.cts +3 -3
  63. package/dist/index.d.mts +3 -3
  64. package/dist/index.mjs +1 -2
  65. package/dist/integrity.cjs.map +1 -1
  66. package/dist/integrity.mjs.map +1 -1
  67. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  68. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  69. package/dist/merge.cjs.map +1 -1
  70. package/dist/merge.mjs.map +1 -1
  71. package/dist/near-cli.cjs +1 -1
  72. package/dist/near-cli.cjs.map +1 -1
  73. package/dist/near-cli.mjs +1 -1
  74. package/dist/near-cli.mjs.map +1 -1
  75. package/dist/orchestrator.cjs +1 -1
  76. package/dist/orchestrator.cjs.map +1 -1
  77. package/dist/orchestrator.mjs +1 -1
  78. package/dist/orchestrator.mjs.map +1 -1
  79. package/dist/plugin.cjs +182 -171
  80. package/dist/plugin.cjs.map +1 -1
  81. package/dist/plugin.d.cts +72 -39
  82. package/dist/plugin.d.cts.map +1 -1
  83. package/dist/plugin.d.mts +71 -39
  84. package/dist/plugin.d.mts.map +1 -1
  85. package/dist/plugin.mjs +170 -160
  86. package/dist/plugin.mjs.map +1 -1
  87. package/dist/sdk.cjs +2 -2
  88. package/dist/sdk.d.cts +1 -1
  89. package/dist/sdk.d.mts +1 -1
  90. package/dist/sdk.mjs +1 -1
  91. package/dist/service-descriptor.d.cts +34 -0
  92. package/dist/service-descriptor.d.cts.map +1 -0
  93. package/dist/service-descriptor.d.mts +36 -0
  94. package/dist/service-descriptor.d.mts.map +1 -0
  95. package/dist/shared.cjs.map +1 -1
  96. package/dist/shared.mjs.map +1 -1
  97. package/dist/types.cjs +184 -184
  98. package/dist/types.cjs.map +1 -1
  99. package/dist/types.d.cts +5 -5
  100. package/dist/types.d.mts +5 -5
  101. package/dist/types.mjs +1 -1
  102. package/dist/types.mjs.map +1 -1
  103. package/dist/ui/types.d.cts +1 -0
  104. package/dist/ui/types.d.cts.map +1 -1
  105. package/dist/ui/types.d.mts +1 -0
  106. package/dist/ui/types.d.mts.map +1 -1
  107. package/dist/utils/banner.cjs.map +1 -1
  108. package/dist/utils/banner.mjs.map +1 -1
  109. package/dist/utils/run.cjs.map +1 -1
  110. package/dist/utils/run.mjs.map +1 -1
  111. package/package.json +3 -3
  112. package/skills/init-upgrade/SKILL.md +22 -16
  113. package/skills/publish-sync/SKILL.md +7 -18
  114. package/dist/utils/path-match.cjs +0 -18
  115. package/dist/utils/path-match.cjs.map +0 -1
  116. package/dist/utils/path-match.mjs +0 -17
  117. package/dist/utils/path-match.mjs.map +0 -1
  118. package/src/api-contract.ts +0 -623
  119. package/src/app.ts +0 -193
  120. package/src/cli/catalog.ts +0 -49
  121. package/src/cli/framework-version.ts +0 -61
  122. package/src/cli/help.ts +0 -13
  123. package/src/cli/infra.ts +0 -190
  124. package/src/cli/init.ts +0 -1202
  125. package/src/cli/parse.ts +0 -147
  126. package/src/cli/prompts.ts +0 -135
  127. package/src/cli/snapshot.ts +0 -46
  128. package/src/cli/status.ts +0 -99
  129. package/src/cli/sync.ts +0 -518
  130. package/src/cli/timing.ts +0 -63
  131. package/src/cli/upgrade.ts +0 -828
  132. package/src/cli.ts +0 -516
  133. package/src/components/dev-view.tsx +0 -352
  134. package/src/components/streaming-view.ts +0 -177
  135. package/src/config.ts +0 -893
  136. package/src/contract.meta.ts +0 -140
  137. package/src/contract.ts +0 -325
  138. package/src/dev-logs.ts +0 -92
  139. package/src/dev-session.ts +0 -283
  140. package/src/fastkv.ts +0 -181
  141. package/src/index.ts +0 -8
  142. package/src/integrity.ts +0 -138
  143. package/src/internal/manifest-normalizer.ts +0 -290
  144. package/src/merge.ts +0 -187
  145. package/src/mf.ts +0 -147
  146. package/src/near-cli.ts +0 -259
  147. package/src/network.ts +0 -3
  148. package/src/orchestrator.ts +0 -493
  149. package/src/plugin.ts +0 -1821
  150. package/src/sdk.ts +0 -14
  151. package/src/service-descriptor.ts +0 -281
  152. package/src/shared.ts +0 -249
  153. package/src/sidebar.ts +0 -140
  154. package/src/types.ts +0 -330
  155. package/src/ui/head.ts +0 -83
  156. package/src/ui/index.ts +0 -5
  157. package/src/ui/metadata.ts +0 -95
  158. package/src/ui/router.ts +0 -88
  159. package/src/ui/runtime.ts +0 -42
  160. package/src/ui/types.ts +0 -64
  161. package/src/utils/banner.ts +0 -21
  162. package/src/utils/linkify.ts +0 -11
  163. package/src/utils/path-match.ts +0 -16
  164. package/src/utils/run.ts +0 -31
  165. package/src/utils/save-config.ts +0 -20
  166. package/src/utils/theme.ts +0 -39
@@ -1 +1 @@
1
- {"version":3,"file":"sync.mjs","names":["isPlainObjectFromMerge"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport {\n copyFileSync,\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { glob } from \"glob\";\nimport { loadConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { isPathExcluded } from \"../utils/path-match\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n personalizeConfig,\n readTemplatekeep,\n resolveSourceDir,\n runBunInstall,\n runTypesGen,\n} from \"./init\";\nimport { readSnapshot, writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"biome.json\",\n \"bos.config.json\",\n \"package.json\",\n \"docker-compose.yml\",\n \".github/renovate.json\",\n \".github/workflows/ci.yml\",\n \".github/workflows/release-sync.yml\",\n \"ui/package.json\",\n \"ui/postcss.config.mjs\",\n \"ui/rsbuild.config.ts\",\n \"ui/tsconfig.json\",\n \"ui/src/app.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/lib/api.ts\",\n \"ui/src/lib/auth.ts\",\n \"ui/src/router.server.tsx\",\n \"ui/src/router.tsx\",\n \"ui/src/routes/__root.tsx\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.contract.json\",\n \"api/tsconfig.json\",\n \"api/src/lib/auth.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n return FRAMEWORK_OWNED_SYNC_FILES.has(filePath);\n}\n\nfunction readExcludeFile(filePath: string): string[] {\n if (!existsSync(filePath)) return [];\n const content = readFileSync(filePath, \"utf-8\");\n return content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nexport async function readTemplatesyncExclude(sourceDir: string): Promise<string[]> {\n return readExcludeFile(join(sourceDir, \".templatesync-exclude\"));\n}\n\nexport function readLocalSyncExcludes(projectDir: string): string[] {\n return readExcludeFile(join(projectDir, \".bos\", \"sync-local-exclude\"));\n}\n\nfunction computeLocalHash(projectDir: string, filePath: string): string | null {\n const fullPath = join(projectDir, filePath);\n if (!existsSync(fullPath)) return null;\n try {\n const content = readFileSync(fullPath);\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n } catch {\n return null;\n }\n}\n\nfunction backupFiles(projectDir: string, filePaths: string[]): string | null {\n const filesToBackup = filePaths.filter((f) => existsSync(join(projectDir, f)));\n if (filesToBackup.length === 0) return null;\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupDir = join(projectDir, \".bos\", \"sync-backup\", timestamp);\n\n for (const filePath of filesToBackup) {\n const src = join(projectDir, filePath);\n const dest = join(backupDir, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n copyFileSync(src, dest);\n }\n\n return backupDir;\n}\n\nfunction mergeStringMaps(\n local: Record<string, string> | undefined,\n template: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!local && !template) return undefined;\n\n const merged: Record<string, string> = { ...(local ?? {}) };\n for (const [name, value] of Object.entries(template ?? {})) {\n merged[name] = value;\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeWorkspacePackages(local: unknown, template: unknown): string[] | undefined {\n const localPackages = Array.isArray(local) ? local : [];\n const templatePackages = Array.isArray(template) ? template : [];\n if (localPackages.length === 0 && templatePackages.length === 0) return undefined;\n\n const ordered = new Set<string>();\n for (const entry of templatePackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n for (const entry of localPackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n\n return ordered.size > 0 ? [...ordered] : undefined;\n}\n\nexport function mergePackageJson(\n filePath: string,\n local: PackageJson,\n template: PackageJson,\n): PackageJson {\n const merged: PackageJson = { ...local, ...template };\n\n if (filePath === \"package.json\") {\n for (const key of [\"name\", \"private\", \"version\"] as const) {\n if (key in local) {\n merged[key] = local[key];\n }\n }\n } else if (\"version\" in local) {\n merged.version = local.version;\n }\n\n for (const depField of [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"overrides\",\n ] as const) {\n const localDeps = local[depField] as Record<string, string> | undefined;\n const templateDeps = template[depField] as Record<string, string> | undefined;\n\n const mergedDeps = mergeStringMaps(localDeps, templateDeps);\n if (mergedDeps) {\n merged[depField] = mergedDeps;\n } else {\n delete merged[depField];\n }\n }\n\n if (\n (local.scripts && typeof local.scripts === \"object\") ||\n (template.scripts && typeof template.scripts === \"object\")\n ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\n template.scripts as Record<string, string> | undefined,\n );\n if (mergedScripts) {\n merged.scripts = mergedScripts;\n } else {\n delete merged.scripts;\n }\n }\n\n if (\n (local.workspaces && typeof local.workspaces === \"object\") ||\n (template.workspaces && typeof template.workspaces === \"object\")\n ) {\n const localWorkspaces = (local.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n const templateWorkspaces = (template.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n const mergedWorkspaces: { packages?: string[]; catalog?: Record<string, string> } = {\n ...localWorkspaces,\n ...templateWorkspaces,\n };\n\n const mergedPackages = mergeWorkspacePackages(\n localWorkspaces.packages,\n templateWorkspaces.packages,\n );\n if (mergedPackages) {\n mergedWorkspaces.packages = mergedPackages;\n } else {\n delete mergedWorkspaces.packages;\n }\n\n const mergedCatalog = mergeStringMaps(localWorkspaces.catalog, templateWorkspaces.catalog);\n if (mergedCatalog) {\n mergedWorkspaces.catalog = mergedCatalog;\n } else {\n delete mergedWorkspaces.catalog;\n }\n\n if (Object.keys(mergedWorkspaces).length > 0) {\n merged.workspaces = mergedWorkspaces;\n } else {\n delete merged.workspaces;\n }\n }\n\n return merged;\n}\n\nfunction toDestPath(filePath: string): string {\n return filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n}\n\nfunction writeSyncedFile(sourceDir: string, projectDir: string, filePath: string): void {\n const src = join(sourceDir, filePath);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(projectDir, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n\n if (filePath.endsWith(\"bos.config.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergeBosConfigWithTemplate(local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n if (filePath.endsWith(\"package.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergePackageJson(destPath, local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n writeFileSync(dest, readFileSync(src));\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the raw bos.config.json (not the resolved config) because it needs\n // the user's explicit local settings: their extends ref, selected plugins, etc.\n // The resolved config is the merged result and would include inherited parent\n // values that the user didn't explicitly choose, which would break sync filtering.\n const localConfig = JSON.parse(\n readFileSync(join(projectDir, \"bos.config.json\"), \"utf-8\"),\n ) as Record<string, unknown>;\n\n let extendsRef: string | undefined;\n if (typeof localConfig.extends === \"string\") {\n extendsRef = localConfig.extends;\n } else if (isPlainObjectFromMerge(localConfig.extends)) {\n extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n }\n if (!extendsRef?.startsWith(\"bos://\")) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: \"No extends field found in bos.config.json — cannot determine parent\",\n };\n }\n\n const extendsMatch = extendsRef.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!extendsMatch) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: `Invalid extends reference: ${extendsRef}`,\n };\n }\n\n const extendsAccount = extendsMatch[1];\n const extendsGateway = extendsMatch[2];\n\n const { sourceDir, cleanup } = await resolveSourceDir({\n extendsAccount,\n extendsGateway,\n });\n\n try {\n const patterns = await readTemplatekeep(sourceDir);\n if (patterns.length === 0) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: \"No .templatekeep found in template source\",\n };\n }\n\n const parentExcludes = await readTemplatesyncExclude(sourceDir);\n const localExcludes = readLocalSyncExcludes(projectDir);\n const excludePatterns = [...parentExcludes, ...localExcludes];\n\n const allTemplateFiles = new Set<string>();\n for (const pattern of patterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n allTemplateFiles.add(match);\n }\n }\n\n const childPlugins =\n localConfig.plugins && typeof localConfig.plugins === \"object\"\n ? Object.keys(localConfig.plugins as Record<string, unknown>)\n : [];\n\n const pluginRoutes: Record<string, string[]> = {};\n const parentRuntime = await loadConfig({ cwd: sourceDir });\n for (const [key, plugin] of Object.entries(parentRuntime?.runtime.plugins ?? {})) {\n if (plugin.routes && plugin.routes.length > 0) {\n pluginRoutes[key] = plugin.routes;\n }\n }\n\n const excludedRoutePatterns: string[] = [];\n for (const [pluginKey, routePatterns] of Object.entries(pluginRoutes)) {\n if (!childPlugins.includes(pluginKey)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n\n const filteredFiles = new Set<string>();\n for (const filePath of allTemplateFiles) {\n const pluginMatch = filePath.match(/^plugins\\/([^/]+)/);\n if (pluginMatch && !childPlugins.includes(pluginMatch[1])) continue;\n if (isPathExcluded(filePath, excludedRoutePatterns)) continue;\n filteredFiles.add(filePath);\n }\n\n for (const [pluginKey, routePatterns] of Object.entries(pluginRoutes)) {\n if (!childPlugins.includes(pluginKey)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isPathExcluded(match, excludedRoutePatterns)) {\n filteredFiles.add(match);\n }\n }\n }\n }\n\n const snapshot = await readSnapshot(projectDir);\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n\n for (const filePath of filteredFiles) {\n const destPath = toDestPath(filePath);\n const frameworkOwned = isFrameworkOwnedSyncFile(destPath);\n if (isPathExcluded(destPath, excludePatterns) && !frameworkOwned) continue;\n\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceContent = readFileSync(join(sourceDir, filePath));\n const sourceHash = createHash(\"sha256\").update(sourceContent).digest(\"hex\").substring(0, 16);\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash === sourceHash) continue;\n\n if (frameworkOwned) {\n updated.push(destPath);\n continue;\n }\n\n const snapshotHash = snapshot?.files[destPath];\n\n if (snapshotHash === undefined) {\n updated.push(destPath);\n continue;\n }\n\n if (localHash === snapshotHash) {\n updated.push(destPath);\n } else {\n if (options.force) {\n updated.push(destPath);\n } else {\n skipped.push(destPath);\n }\n }\n }\n\n if (options.dryRun) {\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n };\n }\n\n const filesToWrite = [...updated, ...added].filter(\n (f) => isFrameworkOwnedSyncFile(f) || !isPathExcluded(f, excludePatterns),\n );\n\n const destToSource = new Map<string, string>();\n for (const filePath of filteredFiles) {\n destToSource.set(toDestPath(filePath), filePath);\n }\n\n if (filesToWrite.length > 0) {\n backupFiles(projectDir, filesToWrite);\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath);\n }\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const filePath of filteredFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n const content = readFileSync(src);\n newSnapshotFiles[toDestPath(filePath)] = createHash(\"sha256\")\n .update(content)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\n });\n\n const account = (localConfig.account as string) || extendsAccount;\n const domain = (localConfig.domain as string) || extendsGateway;\n\n await personalizeConfig(projectDir, {\n extendsAccount,\n extendsGateway,\n account,\n domain,\n plugins: childPlugins,\n pluginRoutes,\n overrides: [\"ui\", \"api\", \"host\", \"plugins\"],\n workspaceOpts: { sourceDir },\n mode: \"sync\",\n });\n\n const syncedConfig = await loadConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(projectDir, syncedConfig.runtime);\n }\n\n if (!options.noInstall) {\n await runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sync.mjs","names":["isPlainObjectFromMerge"],"sources":["../../src/cli/sync.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { loadConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n personalizeConfig,\n resolveSourceDir,\n runBunInstall,\n runTypesGen,\n sourcePathToDestinationPath,\n} from \"./init\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"AGENTS.md\",\n \"biome.json\",\n \"bos.config.json\",\n \"bunfig.toml\",\n \"CONTRIBUTING.md\",\n \"package.json\",\n \".changeset/config.json\",\n \".changeset/README.md\",\n \".github/renovate.json\",\n \".github/workflows/ci.yml\",\n \".github/workflows/release-sync.yml\",\n \".opencode/skills/everything-dev/SKILL.md\",\n \"ui/package.json\",\n \"ui/postcss.config.mjs\",\n \"ui/rsbuild.config.ts\",\n \"ui/tsconfig.json\",\n \"ui/src/app.ts\",\n \"ui/src/globals.d.ts\",\n \"ui/src/hydrate.tsx\",\n \"ui/src/lib/api.ts\",\n \"ui/src/lib/auth.ts\",\n \"ui/src/router.server.tsx\",\n \"ui/src/router.tsx\",\n \"ui/src/routes/__root.tsx\",\n \"api/package.json\",\n \"api/plugin.dev.ts\",\n \"api/rspack.config.js\",\n \"api/tsconfig.contract.json\",\n \"api/tsconfig.json\",\n \"api/src/lib/auth.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n return FRAMEWORK_OWNED_SYNC_FILES.has(filePath);\n}\n\nfunction computeLocalHash(projectDir: string, filePath: string): string | null {\n const fullPath = join(projectDir, filePath);\n if (!existsSync(fullPath)) return null;\n try {\n const content = readFileSync(fullPath);\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n } catch {\n return null;\n }\n}\n\nfunction backupFiles(projectDir: string, filePaths: string[]): string | null {\n const filesToBackup = filePaths.filter((f) => existsSync(join(projectDir, f)));\n if (filesToBackup.length === 0) return null;\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupDir = join(projectDir, \".bos\", \"sync-backup\", timestamp);\n\n for (const filePath of filesToBackup) {\n const src = join(projectDir, filePath);\n const dest = join(backupDir, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n copyFileSync(src, dest);\n }\n\n return backupDir;\n}\n\nfunction mergeStringMaps(\n local: Record<string, string> | undefined,\n template: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!local && !template) return undefined;\n\n const merged: Record<string, string> = { ...(local ?? {}) };\n for (const [name, value] of Object.entries(template ?? {})) {\n merged[name] = value;\n }\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\nfunction mergeWorkspacePackages(local: unknown, template: unknown): string[] | undefined {\n const localPackages = Array.isArray(local) ? local : [];\n const templatePackages = Array.isArray(template) ? template : [];\n if (localPackages.length === 0 && templatePackages.length === 0) return undefined;\n\n const ordered = new Set<string>();\n for (const entry of templatePackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n for (const entry of localPackages) {\n if (typeof entry === \"string\" && entry.length > 0) ordered.add(entry);\n }\n\n const hasPluginEntry = [...ordered].some((e) => e.startsWith(\"plugins/\") && e !== \"plugins/*\");\n if (hasPluginEntry) {\n for (const entry of [...ordered]) {\n if (entry.startsWith(\"plugins/\") && entry !== \"plugins/*\") {\n ordered.delete(entry);\n }\n }\n ordered.add(\"plugins/*\");\n }\n\n return ordered.size > 0 ? [...ordered] : undefined;\n}\n\nexport function mergePackageJson(\n filePath: string,\n local: PackageJson,\n template: PackageJson,\n): PackageJson {\n const merged: PackageJson = { ...local, ...template };\n\n if (filePath === \"package.json\") {\n for (const key of [\"name\", \"private\", \"version\"] as const) {\n if (key in local) {\n merged[key] = local[key];\n }\n }\n } else if (\"version\" in local) {\n merged.version = local.version;\n }\n\n for (const depField of [\n \"dependencies\",\n \"devDependencies\",\n \"peerDependencies\",\n \"overrides\",\n ] as const) {\n const localDeps = local[depField] as Record<string, string> | undefined;\n const templateDeps = template[depField] as Record<string, string> | undefined;\n\n const mergedDeps = mergeStringMaps(localDeps, templateDeps);\n if (mergedDeps) {\n merged[depField] = mergedDeps;\n } else {\n delete merged[depField];\n }\n }\n\n if (\n (local.scripts && typeof local.scripts === \"object\") ||\n (template.scripts && typeof template.scripts === \"object\")\n ) {\n const mergedScripts = mergeStringMaps(\n local.scripts as Record<string, string> | undefined,\n template.scripts as Record<string, string> | undefined,\n );\n if (mergedScripts) {\n merged.scripts = mergedScripts;\n } else {\n delete merged.scripts;\n }\n }\n\n if (\n (local.workspaces && typeof local.workspaces === \"object\") ||\n (template.workspaces && typeof template.workspaces === \"object\")\n ) {\n const localWorkspaces = (local.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n const templateWorkspaces = (template.workspaces ?? {}) as {\n packages?: string[];\n catalog?: Record<string, string>;\n };\n\n const mergedWorkspaces: { packages?: string[]; catalog?: Record<string, string> } = {\n ...localWorkspaces,\n ...templateWorkspaces,\n };\n\n const mergedPackages = mergeWorkspacePackages(\n localWorkspaces.packages,\n templateWorkspaces.packages,\n );\n if (mergedPackages) {\n mergedWorkspaces.packages = mergedPackages;\n } else {\n delete mergedWorkspaces.packages;\n }\n\n const mergedCatalog = mergeStringMaps(localWorkspaces.catalog, templateWorkspaces.catalog);\n if (mergedCatalog) {\n mergedWorkspaces.catalog = mergedCatalog;\n } else {\n delete mergedWorkspaces.catalog;\n }\n\n if (Object.keys(mergedWorkspaces).length > 0) {\n merged.workspaces = mergedWorkspaces;\n } else {\n delete merged.workspaces;\n }\n }\n\n return merged;\n}\n\nfunction toDestPath(filePath: string): string {\n return sourcePathToDestinationPath(filePath);\n}\n\nfunction toSourcePath(sourceDir: string, destPath: string): string | null {\n const directPath = join(sourceDir, destPath);\n if (existsSync(directPath)) {\n return destPath;\n }\n\n if (destPath.startsWith(\".github/\")) {\n const templatePath = destPath.replace(/^\\.github\\//, \".github/templates/\");\n if (existsSync(join(sourceDir, templatePath))) {\n return templatePath;\n }\n }\n\n return null;\n}\n\nfunction writeSyncedFile(sourceDir: string, projectDir: string, filePath: string): void {\n const src = join(sourceDir, filePath);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(projectDir, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n\n if (filePath.endsWith(\"bos.config.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergeBosConfigWithTemplate(local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n if (filePath.endsWith(\"package.json\")) {\n const localContent = existsSync(dest) ? readFileSync(dest, \"utf-8\") : null;\n const templateContent = readFileSync(src, \"utf-8\");\n\n if (localContent) {\n const local = JSON.parse(localContent) as Record<string, unknown>;\n const template = JSON.parse(templateContent) as Record<string, unknown>;\n const merged = mergePackageJson(destPath, local, template);\n writeFileSync(dest, `${JSON.stringify(merged, null, 2)}\\n`);\n return;\n }\n }\n\n writeFileSync(dest, readFileSync(src));\n}\n\nexport async function syncTemplate(projectDir: string, options: SyncOptions): Promise<SyncResult> {\n // Sync reads the raw bos.config.json (not the resolved config) because it needs\n // the user's explicit local settings: their extends ref, selected plugins, etc.\n // The resolved config is the merged result and would include inherited parent\n // values that the user didn't explicitly choose, which would break sync filtering.\n const localConfig = JSON.parse(\n readFileSync(join(projectDir, \"bos.config.json\"), \"utf-8\"),\n ) as Record<string, unknown>;\n\n let extendsRef: string | undefined;\n if (typeof localConfig.extends === \"string\") {\n extendsRef = localConfig.extends;\n } else if (isPlainObjectFromMerge(localConfig.extends)) {\n extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n }\n if (!extendsRef?.startsWith(\"bos://\")) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: \"No extends field found in bos.config.json — cannot determine parent\",\n };\n }\n\n const extendsMatch = extendsRef.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!extendsMatch) {\n return {\n status: \"error\",\n updated: [],\n skipped: [],\n added: [],\n error: `Invalid extends reference: ${extendsRef}`,\n };\n }\n\n const extendsAccount = extendsMatch[1];\n const extendsGateway = extendsMatch[2];\n\n const { sourceDir, cleanup } = await resolveSourceDir({\n extendsAccount,\n extendsGateway,\n });\n\n try {\n const childPlugins =\n localConfig.plugins && typeof localConfig.plugins === \"object\"\n ? Object.keys(localConfig.plugins as Record<string, unknown>)\n : [];\n const withUi = existsSync(join(projectDir, \"ui\", \"package.json\"));\n const withApi = existsSync(join(projectDir, \"api\", \"package.json\"));\n const withHost = existsSync(join(projectDir, \"host\", \"package.json\"));\n\n const filteredFiles = new Set<string>();\n const destToSource = new Map<string, string>();\n for (const destPath of FRAMEWORK_OWNED_SYNC_FILES) {\n if (destPath.startsWith(\"ui/\") && !withUi) continue;\n if (destPath.startsWith(\"api/\") && !withApi) continue;\n if (destPath.startsWith(\"host/\") && !withHost) continue;\n const sourcePath = toSourcePath(sourceDir, destPath);\n if (!sourcePath) continue;\n filteredFiles.add(sourcePath);\n destToSource.set(destPath, sourcePath);\n }\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n\n for (const [destPath, filePath] of destToSource.entries()) {\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceContent = readFileSync(join(sourceDir, filePath));\n const sourceHash = createHash(\"sha256\").update(sourceContent).digest(\"hex\").substring(0, 16);\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash !== sourceHash) {\n updated.push(destPath);\n }\n }\n\n if (options.dryRun) {\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n };\n }\n\n const filesToWrite = [...updated, ...added];\n\n if (filesToWrite.length > 0) {\n backupFiles(projectDir, filesToWrite);\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath);\n }\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const filePath of filteredFiles) {\n const src = join(sourceDir, filePath);\n const content = readFileSync(src);\n newSnapshotFiles[toDestPath(filePath)] = createHash(\"sha256\")\n .update(content)\n .digest(\"hex\")\n .substring(0, 16);\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\n });\n\n const account = (localConfig.account as string) || extendsAccount;\n const domain = (localConfig.domain as string) || extendsGateway;\n const overrides: Array<\"ui\" | \"api\" | \"host\" | \"plugins\"> = [];\n if (withUi) overrides.push(\"ui\");\n if (withApi) overrides.push(\"api\");\n if (withHost) overrides.push(\"host\");\n if (childPlugins.length > 0) overrides.push(\"plugins\");\n\n await personalizeConfig(projectDir, {\n extendsAccount,\n extendsGateway,\n account,\n domain,\n overrides,\n plugins: childPlugins,\n workspaceOpts: { sourceDir },\n mode: \"sync\",\n });\n\n const syncedConfig = await loadConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(projectDir, syncedConfig.runtime);\n }\n\n if (!options.noInstall) {\n await runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n return {\n status: \"synced\",\n updated,\n skipped,\n added,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"timing.cjs","names":[],"sources":["../../src/cli/timing.ts"],"sourcesContent":["import type { spinner as clackSpinner } from \"@clack/prompts\";\n\ntype Spinner = ReturnType<typeof clackSpinner>;\n\nexport interface PhaseTiming {\n name: string;\n durationMs: number;\n}\n\nconst PHASE_LABELS: Record<string, string> = {\n \"parent config\": \"Fetching parent config...\",\n \"template source\": \"Resolving template source...\",\n \"scaffold project\": \"Creating project scaffold...\",\n \"copy files\": \"Copying template files...\",\n \"personalize config\": \"Personalizing config...\",\n \"write snapshot\": \"Writing snapshot...\",\n \"resolve config\": \"Resolving config...\",\n \"generate env/docker\": \"Generating environment config...\",\n \"create env file\": \"Creating .env file...\",\n \"install dependencies\": \"Installing dependencies...\",\n \"generate types\": \"Generating types...\",\n \"generate migrations\": \"Generating database migrations...\",\n \"generate code artifacts\": \"Generating code artifacts...\",\n \"docker compose up\": \"Starting Docker services...\",\n};\n\nfunction phaseLabel(name: string): string {\n return PHASE_LABELS[name] ?? name;\n}\n\nexport async function timePhase<T>(\n timings: PhaseTiming[],\n name: string,\n fn: () => Promise<T>,\n spinner?: Spinner,\n): Promise<T> {\n spinner?.message(phaseLabel(name));\n const startedAt = Date.now();\n try {\n return await fn();\n } finally {\n timings.push({ name, durationMs: Date.now() - startedAt });\n }\n}\n\nexport function sumPhaseDurations(timings: PhaseTiming[]): number {\n return timings.reduce((total, timing) => total + timing.durationMs, 0);\n}\n\nexport function formatDuration(durationMs: number): string {\n if (durationMs < 1000) {\n return `${durationMs}ms`;\n }\n\n if (durationMs < 60_000) {\n const seconds = durationMs / 1000;\n return `${seconds.toFixed(seconds >= 10 ? 0 : 1)}s`;\n }\n\n const minutes = Math.floor(durationMs / 60_000);\n const seconds = Math.round((durationMs % 60_000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n"],"mappings":";;AASA,MAAM,eAAuC;CAC3C,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,cAAc;CACd,sBAAsB;CACtB,kBAAkB;CAClB,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,wBAAwB;CACxB,kBAAkB;CAClB,uBAAuB;CACvB,2BAA2B;CAC3B,qBAAqB;CACtB;AAED,SAAS,WAAW,MAAsB;AACxC,QAAO,aAAa,SAAS;;AAG/B,eAAsB,UACpB,SACA,MACA,IACA,SACY;AACZ,UAAS,QAAQ,WAAW,KAAK,CAAC;CAClC,MAAM,YAAY,KAAK,KAAK;AAC5B,KAAI;AACF,SAAO,MAAM,IAAI;WACT;AACR,UAAQ,KAAK;GAAE;GAAM,YAAY,KAAK,KAAK,GAAG;GAAW,CAAC;;;AAI9D,SAAgB,kBAAkB,SAAgC;AAChE,QAAO,QAAQ,QAAQ,OAAO,WAAW,QAAQ,OAAO,YAAY,EAAE;;AAGxE,SAAgB,eAAe,YAA4B;AACzD,KAAI,aAAa,IACf,QAAO,GAAG,WAAW;AAGvB,KAAI,aAAa,KAAQ;EACvB,MAAM,UAAU,aAAa;AAC7B,SAAO,GAAG,QAAQ,QAAQ,WAAW,KAAK,IAAI,EAAE,CAAC;;AAKnD,QAAO,GAFS,KAAK,MAAM,aAAa,IAAO,CAE7B,IADF,KAAK,MAAO,aAAa,MAAU,IAAK,CAC1B"}
1
+ {"version":3,"file":"timing.cjs","names":[],"sources":["../../src/cli/timing.ts"],"sourcesContent":["import type { spinner as clackSpinner } from \"@clack/prompts\";\n\ntype Spinner = ReturnType<typeof clackSpinner>;\n\nexport interface PhaseTiming {\n name: string;\n durationMs: number;\n}\n\nconst PHASE_LABELS: Record<string, string> = {\n \"parent config\": \"Fetching parent config...\",\n \"template source\": \"Resolving template source...\",\n \"scaffold project\": \"Creating project scaffold...\",\n \"copy files\": \"Copying template files...\",\n \"personalize config\": \"Personalizing config...\",\n \"write snapshot\": \"Writing snapshot...\",\n \"resolve config\": \"Resolving config...\",\n \"generate env/docker\": \"Generating environment config...\",\n \"create env file\": \"Creating .env file...\",\n \"install dependencies\": \"Installing dependencies...\",\n \"generate types\": \"Generating types...\",\n \"generate migrations\": \"Generating database migrations...\",\n \"generate code artifacts\": \"Generating code artifacts...\",\n \"docker compose up\": \"Starting Docker services...\",\n};\n\nfunction phaseLabel(name: string): string {\n return PHASE_LABELS[name] ?? name;\n}\n\nexport async function timePhase<T>(\n timings: PhaseTiming[],\n name: string,\n fn: () => Promise<T>,\n spinner?: Spinner,\n): Promise<T> {\n spinner?.message(phaseLabel(name));\n const startedAt = Date.now();\n try {\n return await fn();\n } finally {\n timings.push({ name, durationMs: Date.now() - startedAt });\n }\n}\n\nexport function sumPhaseDurations(timings: PhaseTiming[]): number {\n return timings.reduce((total, timing) => total + timing.durationMs, 0);\n}\n\nexport function formatDuration(durationMs: number): string {\n if (durationMs < 1000) {\n return `${durationMs}ms`;\n }\n\n if (durationMs < 60_000) {\n const seconds = durationMs / 1000;\n return `${seconds.toFixed(seconds >= 10 ? 0 : 1)}s`;\n }\n\n const minutes = Math.floor(durationMs / 60_000);\n const seconds = Math.round((durationMs % 60_000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n"],"mappings":";;AASA,MAAM,eAAuC;CAC3C,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,cAAc;CACd,sBAAsB;CACtB,kBAAkB;CAClB,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,wBAAwB;CACxB,kBAAkB;CAClB,uBAAuB;CACvB,2BAA2B;CAC3B,qBAAqB;CACtB;AAED,SAAS,WAAW,MAAsB;AACxC,QAAO,aAAa,SAAS;;AAG/B,eAAsB,UACpB,SACA,MACA,IACA,SACY;AACZ,UAAS,QAAQ,WAAW,KAAK,CAAC;CAClC,MAAM,YAAY,KAAK,KAAK;AAC5B,KAAI;AACF,SAAO,MAAM,IAAI;WACT;AACR,UAAQ,KAAK;GAAE;GAAM,YAAY,KAAK,KAAK,GAAG;GAAW,CAAC;;;AAI9D,SAAgB,kBAAkB,SAAgC;AAChE,QAAO,QAAQ,QAAQ,OAAO,WAAW,QAAQ,OAAO,YAAY,EAAE;;AAGxE,SAAgB,eAAe,YAA4B;AACzD,KAAI,aAAa,IACf,QAAO,GAAG,WAAW;AAGvB,KAAI,aAAa,KAAQ;EACvB,MAAM,UAAU,aAAa;AAC7B,SAAO,GAAG,QAAQ,QAAQ,WAAW,KAAK,IAAI,EAAE,CAAC;;AAKnD,QAAO,GAFS,KAAK,MAAM,aAAa,IAEvB,CAAC,IADF,KAAK,MAAO,aAAa,MAAU,IACtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"timing.mjs","names":[],"sources":["../../src/cli/timing.ts"],"sourcesContent":["import type { spinner as clackSpinner } from \"@clack/prompts\";\n\ntype Spinner = ReturnType<typeof clackSpinner>;\n\nexport interface PhaseTiming {\n name: string;\n durationMs: number;\n}\n\nconst PHASE_LABELS: Record<string, string> = {\n \"parent config\": \"Fetching parent config...\",\n \"template source\": \"Resolving template source...\",\n \"scaffold project\": \"Creating project scaffold...\",\n \"copy files\": \"Copying template files...\",\n \"personalize config\": \"Personalizing config...\",\n \"write snapshot\": \"Writing snapshot...\",\n \"resolve config\": \"Resolving config...\",\n \"generate env/docker\": \"Generating environment config...\",\n \"create env file\": \"Creating .env file...\",\n \"install dependencies\": \"Installing dependencies...\",\n \"generate types\": \"Generating types...\",\n \"generate migrations\": \"Generating database migrations...\",\n \"generate code artifacts\": \"Generating code artifacts...\",\n \"docker compose up\": \"Starting Docker services...\",\n};\n\nfunction phaseLabel(name: string): string {\n return PHASE_LABELS[name] ?? name;\n}\n\nexport async function timePhase<T>(\n timings: PhaseTiming[],\n name: string,\n fn: () => Promise<T>,\n spinner?: Spinner,\n): Promise<T> {\n spinner?.message(phaseLabel(name));\n const startedAt = Date.now();\n try {\n return await fn();\n } finally {\n timings.push({ name, durationMs: Date.now() - startedAt });\n }\n}\n\nexport function sumPhaseDurations(timings: PhaseTiming[]): number {\n return timings.reduce((total, timing) => total + timing.durationMs, 0);\n}\n\nexport function formatDuration(durationMs: number): string {\n if (durationMs < 1000) {\n return `${durationMs}ms`;\n }\n\n if (durationMs < 60_000) {\n const seconds = durationMs / 1000;\n return `${seconds.toFixed(seconds >= 10 ? 0 : 1)}s`;\n }\n\n const minutes = Math.floor(durationMs / 60_000);\n const seconds = Math.round((durationMs % 60_000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n"],"mappings":";AASA,MAAM,eAAuC;CAC3C,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,cAAc;CACd,sBAAsB;CACtB,kBAAkB;CAClB,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,wBAAwB;CACxB,kBAAkB;CAClB,uBAAuB;CACvB,2BAA2B;CAC3B,qBAAqB;CACtB;AAED,SAAS,WAAW,MAAsB;AACxC,QAAO,aAAa,SAAS;;AAG/B,eAAsB,UACpB,SACA,MACA,IACA,SACY;AACZ,UAAS,QAAQ,WAAW,KAAK,CAAC;CAClC,MAAM,YAAY,KAAK,KAAK;AAC5B,KAAI;AACF,SAAO,MAAM,IAAI;WACT;AACR,UAAQ,KAAK;GAAE;GAAM,YAAY,KAAK,KAAK,GAAG;GAAW,CAAC;;;AAI9D,SAAgB,kBAAkB,SAAgC;AAChE,QAAO,QAAQ,QAAQ,OAAO,WAAW,QAAQ,OAAO,YAAY,EAAE;;AAGxE,SAAgB,eAAe,YAA4B;AACzD,KAAI,aAAa,IACf,QAAO,GAAG,WAAW;AAGvB,KAAI,aAAa,KAAQ;EACvB,MAAM,UAAU,aAAa;AAC7B,SAAO,GAAG,QAAQ,QAAQ,WAAW,KAAK,IAAI,EAAE,CAAC;;AAKnD,QAAO,GAFS,KAAK,MAAM,aAAa,IAAO,CAE7B,IADF,KAAK,MAAO,aAAa,MAAU,IAAK,CAC1B"}
1
+ {"version":3,"file":"timing.mjs","names":[],"sources":["../../src/cli/timing.ts"],"sourcesContent":["import type { spinner as clackSpinner } from \"@clack/prompts\";\n\ntype Spinner = ReturnType<typeof clackSpinner>;\n\nexport interface PhaseTiming {\n name: string;\n durationMs: number;\n}\n\nconst PHASE_LABELS: Record<string, string> = {\n \"parent config\": \"Fetching parent config...\",\n \"template source\": \"Resolving template source...\",\n \"scaffold project\": \"Creating project scaffold...\",\n \"copy files\": \"Copying template files...\",\n \"personalize config\": \"Personalizing config...\",\n \"write snapshot\": \"Writing snapshot...\",\n \"resolve config\": \"Resolving config...\",\n \"generate env/docker\": \"Generating environment config...\",\n \"create env file\": \"Creating .env file...\",\n \"install dependencies\": \"Installing dependencies...\",\n \"generate types\": \"Generating types...\",\n \"generate migrations\": \"Generating database migrations...\",\n \"generate code artifacts\": \"Generating code artifacts...\",\n \"docker compose up\": \"Starting Docker services...\",\n};\n\nfunction phaseLabel(name: string): string {\n return PHASE_LABELS[name] ?? name;\n}\n\nexport async function timePhase<T>(\n timings: PhaseTiming[],\n name: string,\n fn: () => Promise<T>,\n spinner?: Spinner,\n): Promise<T> {\n spinner?.message(phaseLabel(name));\n const startedAt = Date.now();\n try {\n return await fn();\n } finally {\n timings.push({ name, durationMs: Date.now() - startedAt });\n }\n}\n\nexport function sumPhaseDurations(timings: PhaseTiming[]): number {\n return timings.reduce((total, timing) => total + timing.durationMs, 0);\n}\n\nexport function formatDuration(durationMs: number): string {\n if (durationMs < 1000) {\n return `${durationMs}ms`;\n }\n\n if (durationMs < 60_000) {\n const seconds = durationMs / 1000;\n return `${seconds.toFixed(seconds >= 10 ? 0 : 1)}s`;\n }\n\n const minutes = Math.floor(durationMs / 60_000);\n const seconds = Math.round((durationMs % 60_000) / 1000);\n return `${minutes}m ${seconds}s`;\n}\n"],"mappings":";AASA,MAAM,eAAuC;CAC3C,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,cAAc;CACd,sBAAsB;CACtB,kBAAkB;CAClB,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,wBAAwB;CACxB,kBAAkB;CAClB,uBAAuB;CACvB,2BAA2B;CAC3B,qBAAqB;CACtB;AAED,SAAS,WAAW,MAAsB;AACxC,QAAO,aAAa,SAAS;;AAG/B,eAAsB,UACpB,SACA,MACA,IACA,SACY;AACZ,UAAS,QAAQ,WAAW,KAAK,CAAC;CAClC,MAAM,YAAY,KAAK,KAAK;AAC5B,KAAI;AACF,SAAO,MAAM,IAAI;WACT;AACR,UAAQ,KAAK;GAAE;GAAM,YAAY,KAAK,KAAK,GAAG;GAAW,CAAC;;;AAI9D,SAAgB,kBAAkB,SAAgC;AAChE,QAAO,QAAQ,QAAQ,OAAO,WAAW,QAAQ,OAAO,YAAY,EAAE;;AAGxE,SAAgB,eAAe,YAA4B;AACzD,KAAI,aAAa,IACf,QAAO,GAAG,WAAW;AAGvB,KAAI,aAAa,KAAQ;EACvB,MAAM,UAAU,aAAa;AAC7B,SAAO,GAAG,QAAQ,QAAQ,WAAW,KAAK,IAAI,EAAE,CAAC;;AAKnD,QAAO,GAFS,KAAK,MAAM,aAAa,IAEvB,CAAC,IADF,KAAK,MAAO,aAAa,MAAU,IACtB,CAAC"}
@@ -27,6 +27,12 @@ const CATALOG_TOOL_PACKAGES = [
27
27
  "@module-federation/sdk",
28
28
  "@module-federation/dts-plugin"
29
29
  ];
30
+ const PINNED_CATALOG_TOOL_VERSIONS = {
31
+ "@rspack/core": "1.7.11",
32
+ "@rspack/cli": "1.7.11",
33
+ "@rsbuild/core": "1.7.5",
34
+ "@rsbuild/plugin-react": "1.4.6"
35
+ };
30
36
  const LEGACY_UI_IMPORT_REWRITES = [
31
37
  ["from \"@/auth\"", "from \"@/app\""],
32
38
  ["from '@/auth'", "from '@/app'"],
@@ -47,8 +53,35 @@ const OBSOLETE_FILES = [
47
53
  "ui/scripts/generate-metadata.ts",
48
54
  ".github/dependabot.yml",
49
55
  ".github/templates/dependabot.yml",
50
- "packages/everything-dev/cli.js"
56
+ "packages/everything-dev/cli.js",
57
+ ".templatekeep",
58
+ ".templatesync-exclude"
51
59
  ];
60
+ function extractVersion(value) {
61
+ if (!value) return null;
62
+ return value.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/)?.[0] ?? null;
63
+ }
64
+ async function readExtendedRootCatalog(projectDir) {
65
+ const configPath = (0, node_path.join)(projectDir, "bos.config.json");
66
+ if (!(0, node_fs.existsSync)(configPath)) return {};
67
+ const localConfig = JSON.parse((0, node_fs.readFileSync)(configPath, "utf-8"));
68
+ let extendsRef;
69
+ if (typeof localConfig.extends === "string") extendsRef = localConfig.extends;
70
+ else if (require_merge.isPlainObject(localConfig.extends)) extendsRef = require_merge.resolveExtendsRef(localConfig.extends, "production");
71
+ const parsed = extendsRef ? parseBosRef(extendsRef) : null;
72
+ if (!parsed) return {};
73
+ const { sourceDir, cleanup } = await require_cli_init.resolveSourceDir({
74
+ extendsAccount: parsed.account,
75
+ extendsGateway: parsed.gateway
76
+ });
77
+ try {
78
+ const sourcePkgPath = (0, node_path.join)(sourceDir, "package.json");
79
+ if (!(0, node_fs.existsSync)(sourcePkgPath)) return {};
80
+ return { ...JSON.parse((0, node_fs.readFileSync)(sourcePkgPath, "utf-8")).workspaces?.catalog ?? {} };
81
+ } finally {
82
+ await cleanup();
83
+ }
84
+ }
52
85
  function getExtendsRef(config) {
53
86
  if (typeof config.extends === "string") return config.extends;
54
87
  if (config.extends && typeof config.extends === "object") return require_merge.resolveExtendsRef(config.extends, "production");
@@ -315,18 +348,6 @@ async function addSelectedParentPlugins(projectDir) {
315
348
  await require_save_config.saveBosConfig(projectDir, pluginOptions.localConfig);
316
349
  return selected;
317
350
  }
318
- async function fetchLatestNpmVersion(packageName) {
319
- try {
320
- const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
321
- headers: { Accept: "application/json" },
322
- signal: AbortSignal.timeout(1e4)
323
- });
324
- if (!response.ok) return null;
325
- return (await response.json()).version;
326
- } catch {
327
- return null;
328
- }
329
- }
330
351
  function readInstalledVersion(projectDir, packageName) {
331
352
  return require_framework_version.readInstalledFrameworkVersion(projectDir, packageName);
332
353
  }
@@ -374,7 +395,7 @@ function updateRootPackageVersion(projectDir, packageName, newVersion) {
374
395
  workspaces.catalog = {};
375
396
  modified = true;
376
397
  }
377
- const nextVersion = `^${newVersion}`;
398
+ const nextVersion = newVersion;
378
399
  if (workspaces.catalog[packageName] !== nextVersion) {
379
400
  workspaces.catalog[packageName] = nextVersion;
380
401
  modified = true;
@@ -391,7 +412,7 @@ function updateRootCatalogVersion(projectDir, packageName, newVersion) {
391
412
  };
392
413
  const workspaces = pkg.workspaces;
393
414
  if (!workspaces.catalog || typeof workspaces.catalog !== "object") workspaces.catalog = {};
394
- const nextVersion = `^${newVersion}`;
415
+ const nextVersion = newVersion;
395
416
  if (workspaces.catalog[packageName] === nextVersion) return false;
396
417
  workspaces.catalog[packageName] = nextVersion;
397
418
  (0, node_fs.writeFileSync)(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
@@ -456,11 +477,12 @@ async function upgradeTemplate(projectDir, options) {
456
477
  timings,
457
478
  error: "No package.json found in current directory"
458
479
  };
480
+ const sourceRootCatalog = await readExtendedRootCatalog(projectDir);
459
481
  const { packages, catalogVersionUpdates } = await require_timing.timePhase(timings, "check package versions", async () => {
460
482
  const nextPackages = [];
461
483
  for (const name of FRAMEWORK_PACKAGES) {
462
484
  const installed = readInstalledVersion(projectDir, name);
463
- const latest = await fetchLatestNpmVersion(name);
485
+ const latest = extractVersion(sourceRootCatalog[name]);
464
486
  if (!latest) {
465
487
  nextPackages.push({
466
488
  name,
@@ -479,13 +501,12 @@ async function upgradeTemplate(projectDir, options) {
479
501
  for (const name of CATALOG_TOOL_PACKAGES) {
480
502
  const installed = readInstalledVersion(projectDir, name);
481
503
  if (!installed) continue;
482
- const latest = await fetchLatestNpmVersion(name);
483
- if (!latest) continue;
484
- if (installed === latest) continue;
504
+ const targetVersion = PINNED_CATALOG_TOOL_VERSIONS[name] ?? extractVersion(sourceRootCatalog[name]) ?? installed;
505
+ if (installed === targetVersion) continue;
485
506
  nextCatalogVersionUpdates.push({
486
507
  name,
487
508
  from: installed,
488
- to: latest
509
+ to: targetVersion
489
510
  });
490
511
  }
491
512
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.cjs","names":["resolveExtendsRef","saveBosConfig","fetchParentConfig","process","p","readInstalledFrameworkVersion","timePhase","syncTemplate","runBunInstallForUpgrade","runTypesGen"],"sources":["../../src/cli/upgrade.ts"],"sourcesContent":["import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport { glob } from \"glob\";\nimport type { PhaseTiming, UpgradeOptions, UpgradeResult } from \"../contract\";\nimport { resolveExtendsRef } from \"../merge\";\nimport { saveBosConfig } from \"../utils/save-config\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { fetchParentConfig, runBunInstallForUpgrade, runTypesGen } from \"./init\";\nimport { syncTemplate } from \"./sync\";\nimport { timePhase } from \"./timing\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\nconst LEGACY_UI_IMPORT_REWRITES = [\n ['from \"@/auth\"', 'from \"@/app\"'],\n [\"from '@/auth'\", \"from '@/app'\"],\n ['from \"@/lib/use-api-client\"', 'from \"@/app\"'],\n [\"from '@/lib/use-api-client'\", \"from '@/app'\"],\n ['from \"@/lib/api-client\"', 'from \"@/app\"'],\n [\"from '@/lib/api-client'\", \"from '@/app'\"],\n] as const;\nconst OBSOLETE_FILES = [\n \"ui/src/auth.ts\",\n \"ui/src/auth-types.gen.ts\",\n \"ui/src/lib/api-client.ts\",\n \"ui/src/lib/use-api-client.ts\",\n \"ui/src/api-contract.ts\",\n \"ui/src/api-contract.gen.ts\",\n \"ui/src/lib/auth-client.ts\",\n \"ui/src/lib/session.ts\",\n \"ui/scripts/generate-metadata.ts\",\n \".github/dependabot.yml\",\n \".github/templates/dependabot.yml\",\n \"packages/everything-dev/cli.js\",\n];\n\ninterface NpmPackageInfo {\n version: string;\n}\n\nfunction getExtendsRef(config: Record<string, unknown>): string | undefined {\n if (typeof config.extends === \"string\") {\n return config.extends;\n }\n\n if (config.extends && typeof config.extends === \"object\") {\n return resolveExtendsRef(config.extends as Record<string, string>, \"production\");\n }\n\n return undefined;\n}\n\nfunction parseBosRef(ref: string): { account: string; gateway: string } | null {\n const match = ref.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match?.[1] || !match[2]) return null;\n return { account: match[1], gateway: match[2] };\n}\n\nfunction parseTargetedRef(ref: string): { configRef: string; targetPath?: string } {\n const hashIndex = ref.indexOf(\"#\");\n if (hashIndex === -1) {\n return { configRef: ref };\n }\n return {\n configRef: ref.slice(0, hashIndex),\n targetPath: ref.slice(hashIndex + 1) || undefined,\n };\n}\n\nfunction ensureTargetedRef(ref: string, targetPath: string): string {\n const parsed = parseTargetedRef(ref);\n if (parsed.targetPath) return ref;\n return `${parsed.configRef}#${targetPath}`;\n}\n\nfunction rewriteExtendsTarget(\n entry: Record<string, unknown> | undefined,\n targetPath: string,\n): boolean {\n if (!entry?.extends) return false;\n\n if (typeof entry.extends === \"string\") {\n const next = ensureTargetedRef(entry.extends, targetPath);\n if (next === entry.extends) return false;\n entry.extends = next;\n return true;\n }\n\n if (typeof entry.extends === \"object\") {\n let changed = false;\n for (const [key, value] of Object.entries(entry.extends as Record<string, unknown>)) {\n if (typeof value !== \"string\") continue;\n const next = ensureTargetedRef(value, targetPath);\n if (next !== value) {\n (entry.extends as Record<string, unknown>)[key] = next;\n changed = true;\n }\n }\n return changed;\n }\n\n return false;\n}\n\nfunction migrateRootConfigTargets(config: Record<string, unknown>): boolean {\n let changed = false;\n const app =\n config.app && typeof config.app === \"object\"\n ? (config.app as Record<string, unknown>)\n : undefined;\n\n if (app?.api && typeof app.api === \"object\") {\n changed = rewriteExtendsTarget(app.api as Record<string, unknown>, \"app.api\") || changed;\n }\n if (app?.auth && typeof app.auth === \"object\") {\n changed = rewriteExtendsTarget(app.auth as Record<string, unknown>, \"app.auth\") || changed;\n }\n\n if (config.plugins && typeof config.plugins === \"object\") {\n for (const [pluginKey, pluginValue] of Object.entries(\n config.plugins as Record<string, unknown>,\n )) {\n if (typeof pluginValue === \"string\") {\n const next = ensureTargetedRef(pluginValue, `plugins.${pluginKey}`);\n if (next !== pluginValue) {\n (config.plugins as Record<string, unknown>)[pluginKey] = next;\n changed = true;\n }\n continue;\n }\n if (!pluginValue || typeof pluginValue !== \"object\") continue;\n changed =\n rewriteExtendsTarget(pluginValue as Record<string, unknown>, `plugins.${pluginKey}`) ||\n changed;\n }\n }\n\n return changed;\n}\n\nfunction migratePluginProviderConfig(config: Record<string, unknown>, pluginKey: string): boolean {\n let changed = false;\n if (!config.plugins || typeof config.plugins !== \"object\") {\n return false;\n }\n\n const plugins = config.plugins as Record<string, unknown>;\n const entry = plugins[pluginKey];\n if (!entry || typeof entry !== \"object\") return false;\n\n const pluginEntry = entry as Record<string, unknown>;\n\n if (\"name\" in pluginEntry) {\n delete pluginEntry.name;\n changed = true;\n }\n\n if (typeof pluginEntry.development === \"string\" && pluginEntry.development.startsWith(\"local:\")) {\n if (\"extends\" in pluginEntry) {\n delete pluginEntry.extends;\n changed = true;\n }\n }\n\n changed = rewriteExtendsTarget(pluginEntry, `plugins.${pluginKey}`) || changed;\n\n return changed;\n}\n\nfunction mergePluginConfigIntoRoot(\n rootConfig: Record<string, unknown>,\n pluginKey: string,\n pluginConfig: Record<string, unknown>,\n): boolean {\n let changed = false;\n\n if (!rootConfig.plugins || typeof rootConfig.plugins !== \"object\") {\n rootConfig.plugins = {};\n changed = true;\n }\n const plugins = rootConfig.plugins as Record<string, unknown>;\n if (!plugins[pluginKey] || typeof plugins[pluginKey] !== \"object\") {\n plugins[pluginKey] = {};\n changed = true;\n }\n\n const entry = plugins[pluginKey] as Record<string, unknown>;\n\n const pluginData = extractPluginEntry(pluginConfig, pluginKey);\n\n const apiData = getApiEntry(pluginConfig);\n\n if (pluginData) {\n for (const key of [\n \"secrets\",\n \"variables\",\n \"routes\",\n \"sidebar\",\n \"production\",\n \"integrity\",\n \"proxy\",\n ] as const) {\n if (pluginData[key] !== undefined && entry[key] === undefined) {\n entry[key] = pluginData[key];\n changed = true;\n }\n }\n\n if (typeof pluginData.development === \"string\" && pluginData.development.startsWith(\"local:\")) {\n pluginData.development = `local:plugins/${pluginKey}`;\n }\n if (entry.development === undefined && pluginData.development !== undefined) {\n entry.development = pluginData.development;\n changed = true;\n }\n }\n\n if (apiData) {\n for (const key of [\n \"production\",\n \"integrity\",\n \"proxy\",\n \"variables\",\n \"secrets\",\n \"sidebar\",\n \"routes\",\n ] as const) {\n if (apiData[key] !== undefined && entry[key] === undefined) {\n entry[key] = apiData[key];\n changed = true;\n }\n }\n }\n\n if (\"extends\" in entry) {\n const extendsStr = typeof entry.extends === \"string\" ? entry.extends : undefined;\n if (!extendsStr || extendsStr.includes(`#plugins.${pluginKey}`)) {\n delete entry.extends;\n changed = true;\n }\n }\n\n if (\"name\" in entry) {\n delete entry.name;\n changed = true;\n }\n\n if (configHasTopLevelFields(pluginConfig, pluginKey)) {\n if (entry.routes === undefined && Array.isArray(pluginConfig.routes)) {\n entry.routes = pluginConfig.routes;\n changed = true;\n }\n if (entry.sidebar === undefined && Array.isArray(pluginConfig.sidebar)) {\n entry.sidebar = pluginConfig.sidebar;\n changed = true;\n }\n const api = getApiEntry(pluginConfig);\n if (api) {\n if (entry.routes === undefined && Array.isArray(api.routes)) {\n entry.routes = api.routes;\n changed = true;\n }\n if (entry.sidebar === undefined && Array.isArray(api.sidebar)) {\n entry.sidebar = api.sidebar;\n changed = true;\n }\n }\n }\n\n return changed;\n}\n\nfunction extractPluginEntry(\n pluginConfig: Record<string, unknown>,\n pluginKey: string,\n): Record<string, unknown> | null {\n if (\n pluginConfig.plugins &&\n typeof pluginConfig.plugins === \"object\" &&\n (pluginConfig.plugins as Record<string, unknown>)[pluginKey] &&\n typeof (pluginConfig.plugins as Record<string, unknown>)[pluginKey] === \"object\"\n ) {\n return (pluginConfig.plugins as Record<string, unknown>)[pluginKey] as Record<string, unknown>;\n }\n\n const fallback: Record<string, unknown> = {};\n if (pluginConfig.sidebar !== undefined) {\n fallback.sidebar = pluginConfig.sidebar;\n }\n if (pluginConfig.routes !== undefined) {\n fallback.routes = pluginConfig.routes;\n }\n if (Object.keys(fallback).length > 0) {\n return fallback;\n }\n\n return null;\n}\n\nfunction configHasTopLevelFields(\n pluginConfig: Record<string, unknown>,\n _pluginKey: string,\n): boolean {\n return (\n (pluginConfig.routes !== undefined && Array.isArray(pluginConfig.routes)) ||\n (pluginConfig.sidebar !== undefined && Array.isArray(pluginConfig.sidebar)) ||\n getApiEntry(pluginConfig) !== null\n );\n}\n\nfunction getApiEntry(pluginConfig: Record<string, unknown>): Record<string, unknown> | null {\n if (!pluginConfig.app || typeof pluginConfig.app !== \"object\") return null;\n const app = pluginConfig.app as Record<string, unknown>;\n if (!app.api || typeof app.api !== \"object\") return null;\n return app.api as Record<string, unknown>;\n}\n\nexport async function migrateBosConfigFiles(projectDir: string): Promise<string[]> {\n const migrated: string[] = [];\n const rootConfigPath = join(projectDir, \"bos.config.json\");\n\n if (existsSync(rootConfigPath)) {\n const rootConfig = JSON.parse(readFileSync(rootConfigPath, \"utf-8\")) as Record<string, unknown>;\n let rootChanged = migrateRootConfigTargets(rootConfig);\n\n const pluginConfigPaths = await glob(\"plugins/*/bos.config.json\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n });\n\n for (const relativePath of pluginConfigPaths) {\n const match = relativePath.match(/^plugins\\/([^/]+)\\/bos\\.config\\.json$/);\n const pluginKey = match?.[1];\n if (!pluginKey) continue;\n\n const filePath = join(projectDir, relativePath);\n try {\n const pluginConfig = JSON.parse(readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n rootChanged = mergePluginConfigIntoRoot(rootConfig, pluginKey, pluginConfig) || rootChanged;\n } catch {}\n\n try {\n rmSync(filePath);\n migrated.push(relativePath);\n } catch {}\n }\n\n if (rootConfig.plugins && typeof rootConfig.plugins === \"object\") {\n for (const pluginKey of Object.keys(rootConfig.plugins as Record<string, unknown>)) {\n rootChanged = migratePluginProviderConfig(rootConfig, pluginKey) || rootChanged;\n }\n }\n\n if (rootChanged || migrated.length > 0) {\n await saveBosConfig(projectDir, rootConfig);\n if (!migrated.includes(\"bos.config.json\")) {\n migrated.push(\"bos.config.json\");\n }\n }\n }\n\n return migrated;\n}\n\nasync function loadParentPluginOptions(projectDir: string): Promise<{\n localConfig: Record<string, unknown>;\n parentPlugins: Record<string, unknown>;\n newPluginKeys: string[];\n} | null> {\n const configPath = join(projectDir, \"bos.config.json\");\n if (!existsSync(configPath)) {\n return null;\n }\n\n const localConfig = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n const extendsRef = getExtendsRef(localConfig);\n if (!extendsRef?.startsWith(\"bos://\")) {\n return null;\n }\n\n const parsed = parseBosRef(extendsRef);\n if (!parsed) {\n return null;\n }\n\n let parentConfig: Record<string, unknown>;\n try {\n parentConfig = await fetchParentConfig(parsed.account, parsed.gateway);\n } catch {\n return null;\n }\n\n const parentPlugins =\n parentConfig.plugins && typeof parentConfig.plugins === \"object\"\n ? (parentConfig.plugins as Record<string, unknown>)\n : {};\n const localPlugins =\n localConfig.plugins && typeof localConfig.plugins === \"object\"\n ? (localConfig.plugins as Record<string, unknown>)\n : {};\n\n const newPluginKeys = Object.keys(parentPlugins).filter((key) => !(key in localPlugins));\n return { localConfig, parentPlugins, newPluginKeys };\n}\n\nasync function addSelectedParentPlugins(projectDir: string): Promise<string[]> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n return [];\n }\n\n const pluginOptions = await loadParentPluginOptions(projectDir);\n if (!pluginOptions || pluginOptions.newPluginKeys.length === 0) {\n return [];\n }\n\n const selectedValue = await p.multiselect({\n message: \"Select new plugins from parent:\",\n options: pluginOptions.newPluginKeys.map((key) => ({ value: key, label: key })),\n required: false,\n });\n\n if (p.isCancel(selectedValue)) {\n process.exit(0);\n }\n\n const selected = selectedValue as string[];\n if (selected.length === 0) {\n return [];\n }\n\n const localPlugins =\n pluginOptions.localConfig.plugins && typeof pluginOptions.localConfig.plugins === \"object\"\n ? (pluginOptions.localConfig.plugins as Record<string, unknown>)\n : {};\n const nextPlugins = { ...localPlugins };\n for (const key of selected) {\n const parentPlugin = pluginOptions.parentPlugins[key];\n if (parentPlugin && typeof parentPlugin === \"object\") {\n const nextPlugin = structuredClone(parentPlugin as Record<string, unknown>);\n rewriteExtendsTarget(nextPlugin, `plugins.${key}`);\n nextPlugins[key] = nextPlugin;\n } else if (typeof parentPlugin === \"string\") {\n nextPlugins[key] = ensureTargetedRef(parentPlugin, `plugins.${key}`);\n } else {\n nextPlugins[key] = parentPlugin;\n }\n }\n\n pluginOptions.localConfig.plugins = nextPlugins;\n await saveBosConfig(projectDir, pluginOptions.localConfig);\n\n return selected;\n}\n\nasync function fetchLatestNpmVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {\n headers: { Accept: \"application/json\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (!response.ok) return null;\n const data = (await response.json()) as NpmPackageInfo;\n return data.version;\n } catch {\n return null;\n }\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction setCatalogRef(field: Record<string, string> | undefined, packageName: string): 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\nfunction updateWorkspacePackageRefInFile(filePath: string, packageName: string): boolean {\n const pkg = JSON.parse(readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\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 (setCatalogRef(field, packageName)) {\n modified = true;\n }\n }\n\n if (modified) {\n writeFileSync(filePath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n return modified;\n}\n\nfunction updateRootPackageVersion(\n projectDir: string,\n packageName: string,\n newVersion: string,\n): boolean {\n const pkgPath = join(projectDir, \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\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 (setCatalogRef(field, packageName)) {\n modified = true;\n }\n }\n\n if (!pkg.workspaces || typeof pkg.workspaces !== \"object\") {\n pkg.workspaces = { packages: [], catalog: {} };\n modified = true;\n }\n\n const workspaces = pkg.workspaces as { packages?: string[]; catalog?: Record<string, string> };\n if (!workspaces.catalog || typeof workspaces.catalog !== \"object\") {\n workspaces.catalog = {};\n modified = true;\n }\n\n const nextVersion = `^${newVersion}`;\n if (workspaces.catalog[packageName] !== nextVersion) {\n workspaces.catalog[packageName] = nextVersion;\n modified = true;\n }\n\n if (modified) {\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n return modified;\n}\n\nfunction updateRootCatalogVersion(\n projectDir: string,\n packageName: string,\n newVersion: string,\n): boolean {\n const pkgPath = join(projectDir, \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n\n if (!pkg.workspaces || typeof pkg.workspaces !== \"object\") {\n pkg.workspaces = { packages: [], catalog: {} };\n }\n const workspaces = pkg.workspaces as { packages?: string[]; catalog?: Record<string, string> };\n if (!workspaces.catalog || typeof workspaces.catalog !== \"object\") {\n workspaces.catalog = {};\n }\n\n const nextVersion = `^${newVersion}`;\n if (workspaces.catalog[packageName] === nextVersion) return false;\n\n workspaces.catalog[packageName] = nextVersion;\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nasync function findWorkspacePackageJsons(projectDir: string): Promise<string[]> {\n const rootPkgPath = join(projectDir, \"package.json\");\n if (!existsSync(rootPkgPath)) return [];\n\n const rootPkg = JSON.parse(readFileSync(rootPkgPath, \"utf-8\")) as Record<string, unknown>;\n const workspaceConfig = rootPkg.workspaces as { packages?: string[] } | string[] | undefined;\n\n const patterns: string[] = [];\n if (Array.isArray(workspaceConfig)) {\n patterns.push(...workspaceConfig);\n } else if (workspaceConfig?.packages && Array.isArray(workspaceConfig.packages)) {\n patterns.push(...workspaceConfig.packages);\n }\n\n if (patterns.length === 0) return [];\n\n const pkgPaths: string[] = [];\n for (const pattern of patterns) {\n const matches = await glob(pattern, { cwd: projectDir, dot: false, absolute: false });\n for (const match of matches) {\n const pkgPath = join(projectDir, match, \"package.json\");\n if (existsSync(pkgPath) && statSync(pkgPath).isFile()) {\n pkgPaths.push(pkgPath);\n }\n }\n }\n\n return [...new Set(pkgPaths)];\n}\n\nfunction buildChangelogUrl(\n oldVersion: string | undefined,\n newVersion: string,\n parentConfig: Record<string, unknown> | null,\n): string | undefined {\n if (!oldVersion || oldVersion === newVersion) return undefined;\n const repoUrl = parentConfig?.repository as string | undefined;\n if (!repoUrl) return undefined;\n\n const githubMatch = repoUrl.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/);\n if (!githubMatch) return undefined;\n\n const [, owner, repo] = githubMatch;\n return `https://github.com/${owner}/${repo}/compare/v${oldVersion}...v${newVersion}`;\n}\n\nasync function rewriteLegacyUiImports(projectDir: string): Promise<string[]> {\n const files = await glob(\"ui/src/**/*.{ts,tsx}\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n });\n const migrated: string[] = [];\n\n for (const file of files) {\n const filePath = join(projectDir, file);\n const original = readFileSync(filePath, \"utf-8\");\n let next = original;\n\n for (const [from, to] of LEGACY_UI_IMPORT_REWRITES) {\n next = next.replaceAll(from, to);\n }\n\n if (next !== original) {\n writeFileSync(filePath, next);\n migrated.push(file);\n }\n }\n\n return migrated;\n}\n\nexport async function upgradeTemplate(\n projectDir: string,\n options: UpgradeOptions,\n): Promise<UpgradeResult> {\n const timings: PhaseTiming[] = [];\n const pkgPath = join(projectDir, \"package.json\");\n if (!existsSync(pkgPath)) {\n return {\n status: \"error\",\n packages: [],\n timings,\n error: \"No package.json found in current directory\",\n };\n }\n\n const { packages, catalogVersionUpdates } = await timePhase(\n timings,\n \"check package versions\",\n async () => {\n const nextPackages: UpgradeResult[\"packages\"] = [];\n\n for (const name of FRAMEWORK_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n const latest = await fetchLatestNpmVersion(name);\n\n if (!latest) {\n nextPackages.push({ name, from: installed, to: installed ?? \"unknown\" });\n continue;\n }\n\n nextPackages.push({ name, from: installed, to: latest });\n }\n\n const nextCatalogVersionUpdates: Array<{\n name: string;\n from: string | undefined;\n to: string;\n }> = [];\n for (const name of CATALOG_TOOL_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n if (!installed) continue;\n const latest = await fetchLatestNpmVersion(name);\n if (!latest) continue;\n if (installed === latest) continue;\n nextCatalogVersionUpdates.push({ name, from: installed, to: latest });\n }\n\n return { packages: nextPackages, catalogVersionUpdates: nextCatalogVersionUpdates };\n },\n );\n\n const hasFrameworkUpdates = packages.some((p) => p.from !== p.to && p.from !== undefined);\n const hasCatalogUpdates = catalogVersionUpdates.length > 0;\n const hasUpdates = hasFrameworkUpdates || hasCatalogUpdates;\n\n if (options.dryRun) {\n let changelogUrl: string | undefined;\n const pluginOptions = options.noSync\n ? null\n : await timePhase(timings, \"discover parent plugins\", () =>\n loadParentPluginOptions(projectDir),\n );\n if (hasUpdates) {\n const configPath = join(projectDir, \"bos.config.json\");\n let parentConfig: Record<string, unknown> | null = null;\n if (existsSync(configPath)) {\n try {\n parentConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n } catch {}\n }\n const mainPkg = packages.find((p) => p.name === \"everything-dev\");\n if (mainPkg?.from && mainPkg.from !== mainPkg.to) {\n changelogUrl = buildChangelogUrl(mainPkg.from, mainPkg.to, parentConfig);\n }\n }\n\n return {\n status: \"dry-run\",\n packages: [\n ...packages,\n ...catalogVersionUpdates.map((u) => ({ name: u.name, from: u.from, to: u.to })),\n ],\n availablePlugins: pluginOptions?.newPluginKeys,\n timings,\n changelogUrl,\n };\n }\n\n await timePhase(timings, \"apply package updates\", async () => {\n for (const pkg of packages) {\n if (pkg.from !== undefined && pkg.from !== pkg.to) {\n updateRootPackageVersion(projectDir, pkg.name, pkg.to);\n }\n }\n\n for (const update of catalogVersionUpdates) {\n updateRootCatalogVersion(projectDir, update.name, update.to);\n }\n\n const workspacePkgPaths = await findWorkspacePackageJsons(projectDir);\n for (const pkgPath of workspacePkgPaths) {\n for (const pkg of packages) {\n if (pkg.from !== undefined && pkg.from !== pkg.to) {\n updateWorkspacePackageRefInFile(pkgPath, pkg.name);\n }\n }\n for (const update of catalogVersionUpdates) {\n updateWorkspacePackageRefInFile(pkgPath, update.name);\n }\n }\n });\n\n const migratedBosConfigs = await timePhase(timings, \"migrate bos configs\", () =>\n migrateBosConfigFiles(projectDir),\n );\n\n let syncResult: UpgradeResult[\"sync\"];\n let addedPlugins: string[] = [];\n if (!options.noSync) {\n addedPlugins = await timePhase(timings, \"discover parent plugins\", async () => {\n if (options.dryRun) return [];\n return addSelectedParentPlugins(projectDir);\n });\n\n syncResult = await timePhase(timings, \"sync template\", () =>\n syncTemplate(projectDir, {\n dryRun: false,\n force: options.force,\n noInstall: true,\n }),\n );\n }\n\n if ((hasUpdates || addedPlugins.length > 0) && !options.noInstall) {\n await timePhase(timings, \"install dependencies\", () => runBunInstallForUpgrade(projectDir));\n await timePhase(timings, \"generate types\", () => runTypesGen(projectDir));\n }\n\n const migratedFiles = await timePhase(timings, \"clean obsolete files\", async () => {\n const nextMigratedFiles = [\n ...migratedBosConfigs,\n ...(await rewriteLegacyUiImports(projectDir)),\n ];\n for (const file of OBSOLETE_FILES) {\n const filePath = join(projectDir, file);\n if (existsSync(filePath)) {\n rmSync(filePath);\n nextMigratedFiles.push(file);\n }\n }\n return nextMigratedFiles;\n });\n\n let changelogUrl: string | undefined;\n const mainPkg = packages.find((p) => p.name === \"everything-dev\");\n if (mainPkg?.from && mainPkg.from !== mainPkg.to) {\n const configPath = join(projectDir, \"bos.config.json\");\n let parentConfig: Record<string, unknown> | null = null;\n if (existsSync(configPath)) {\n try {\n parentConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n } catch {}\n }\n changelogUrl = buildChangelogUrl(mainPkg.from, mainPkg.to, parentConfig);\n }\n\n return {\n status: \"upgraded\",\n packages: [\n ...packages,\n ...catalogVersionUpdates.map((u) => ({ name: u.name, from: u.from, to: u.to })),\n ],\n sync: syncResult,\n migrated: migratedFiles.length > 0 ? migratedFiles : undefined,\n selectedPlugins: addedPlugins.length > 0 ? addedPlugins : undefined,\n timings,\n changelogUrl,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"upgrade.cjs","names":["isPlainObjectFromMerge","resolveExtendsRef","resolveSourceDir","saveBosConfig","fetchParentConfig","process","p","readInstalledFrameworkVersion","timePhase","syncTemplate","runBunInstallForUpgrade","runTypesGen"],"sources":["../../src/cli/upgrade.ts"],"sourcesContent":["import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport process from \"node:process\";\nimport * as p from \"@clack/prompts\";\nimport { glob } from \"glob\";\nimport type { PhaseTiming, UpgradeOptions, UpgradeResult } from \"../contract\";\nimport { isPlainObject as isPlainObjectFromMerge, resolveExtendsRef } from \"../merge\";\nimport { saveBosConfig } from \"../utils/save-config\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { fetchParentConfig, resolveSourceDir, runBunInstallForUpgrade, runTypesGen } from \"./init\";\nimport { syncTemplate } from \"./sync\";\nimport { timePhase } from \"./timing\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\n\nconst CATALOG_TOOL_PACKAGES = [\n \"@rspack/core\",\n \"@rspack/cli\",\n \"@rsbuild/core\",\n \"@rsbuild/plugin-react\",\n \"@module-federation/enhanced\",\n \"@module-federation/node\",\n \"@module-federation/rsbuild-plugin\",\n \"@module-federation/runtime-core\",\n \"@module-federation/sdk\",\n \"@module-federation/dts-plugin\",\n] as const;\nconst PINNED_CATALOG_TOOL_VERSIONS: Partial<\n Record<(typeof CATALOG_TOOL_PACKAGES)[number], string>\n> = {\n \"@rspack/core\": \"1.7.11\",\n \"@rspack/cli\": \"1.7.11\",\n \"@rsbuild/core\": \"1.7.5\",\n \"@rsbuild/plugin-react\": \"1.4.6\",\n};\nconst LEGACY_UI_IMPORT_REWRITES = [\n ['from \"@/auth\"', 'from \"@/app\"'],\n [\"from '@/auth'\", \"from '@/app'\"],\n ['from \"@/lib/use-api-client\"', 'from \"@/app\"'],\n [\"from '@/lib/use-api-client'\", \"from '@/app'\"],\n ['from \"@/lib/api-client\"', 'from \"@/app\"'],\n [\"from '@/lib/api-client'\", \"from '@/app'\"],\n] as const;\nconst OBSOLETE_FILES = [\n \"ui/src/auth.ts\",\n \"ui/src/auth-types.gen.ts\",\n \"ui/src/lib/api-client.ts\",\n \"ui/src/lib/use-api-client.ts\",\n \"ui/src/api-contract.ts\",\n \"ui/src/api-contract.gen.ts\",\n \"ui/src/lib/auth-client.ts\",\n \"ui/src/lib/session.ts\",\n \"ui/scripts/generate-metadata.ts\",\n \".github/dependabot.yml\",\n \".github/templates/dependabot.yml\",\n \"packages/everything-dev/cli.js\",\n \".templatekeep\",\n \".templatesync-exclude\",\n];\n\nfunction extractVersion(value: string | undefined): string | null {\n if (!value) return null;\n const match = value.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match?.[0] ?? null;\n}\n\nasync function readExtendedRootCatalog(projectDir: string): Promise<Record<string, string>> {\n const configPath = join(projectDir, \"bos.config.json\");\n if (!existsSync(configPath)) {\n return {};\n }\n\n const localConfig = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n let extendsRef: string | undefined;\n if (typeof localConfig.extends === \"string\") {\n extendsRef = localConfig.extends;\n } else if (isPlainObjectFromMerge(localConfig.extends)) {\n extendsRef = resolveExtendsRef(localConfig.extends as Record<string, string>, \"production\");\n }\n\n const parsed = extendsRef ? parseBosRef(extendsRef) : null;\n if (!parsed) {\n return {};\n }\n\n const { sourceDir, cleanup } = await resolveSourceDir({\n extendsAccount: parsed.account,\n extendsGateway: parsed.gateway,\n });\n\n try {\n const sourcePkgPath = join(sourceDir, \"package.json\");\n if (!existsSync(sourcePkgPath)) {\n return {};\n }\n\n const sourcePkg = JSON.parse(readFileSync(sourcePkgPath, \"utf-8\")) as {\n workspaces?: { catalog?: Record<string, string> };\n };\n return { ...(sourcePkg.workspaces?.catalog ?? {}) };\n } finally {\n await cleanup();\n }\n}\n\nfunction getExtendsRef(config: Record<string, unknown>): string | undefined {\n if (typeof config.extends === \"string\") {\n return config.extends;\n }\n\n if (config.extends && typeof config.extends === \"object\") {\n return resolveExtendsRef(config.extends as Record<string, string>, \"production\");\n }\n\n return undefined;\n}\n\nfunction parseBosRef(ref: string): { account: string; gateway: string } | null {\n const match = ref.match(/^bos:\\/\\/([^/]+)\\/(.+)$/);\n if (!match?.[1] || !match[2]) return null;\n return { account: match[1], gateway: match[2] };\n}\n\nfunction parseTargetedRef(ref: string): { configRef: string; targetPath?: string } {\n const hashIndex = ref.indexOf(\"#\");\n if (hashIndex === -1) {\n return { configRef: ref };\n }\n return {\n configRef: ref.slice(0, hashIndex),\n targetPath: ref.slice(hashIndex + 1) || undefined,\n };\n}\n\nfunction ensureTargetedRef(ref: string, targetPath: string): string {\n const parsed = parseTargetedRef(ref);\n if (parsed.targetPath) return ref;\n return `${parsed.configRef}#${targetPath}`;\n}\n\nfunction rewriteExtendsTarget(\n entry: Record<string, unknown> | undefined,\n targetPath: string,\n): boolean {\n if (!entry?.extends) return false;\n\n if (typeof entry.extends === \"string\") {\n const next = ensureTargetedRef(entry.extends, targetPath);\n if (next === entry.extends) return false;\n entry.extends = next;\n return true;\n }\n\n if (typeof entry.extends === \"object\") {\n let changed = false;\n for (const [key, value] of Object.entries(entry.extends as Record<string, unknown>)) {\n if (typeof value !== \"string\") continue;\n const next = ensureTargetedRef(value, targetPath);\n if (next !== value) {\n (entry.extends as Record<string, unknown>)[key] = next;\n changed = true;\n }\n }\n return changed;\n }\n\n return false;\n}\n\nfunction migrateRootConfigTargets(config: Record<string, unknown>): boolean {\n let changed = false;\n const app =\n config.app && typeof config.app === \"object\"\n ? (config.app as Record<string, unknown>)\n : undefined;\n\n if (app?.api && typeof app.api === \"object\") {\n changed = rewriteExtendsTarget(app.api as Record<string, unknown>, \"app.api\") || changed;\n }\n if (app?.auth && typeof app.auth === \"object\") {\n changed = rewriteExtendsTarget(app.auth as Record<string, unknown>, \"app.auth\") || changed;\n }\n\n if (config.plugins && typeof config.plugins === \"object\") {\n for (const [pluginKey, pluginValue] of Object.entries(\n config.plugins as Record<string, unknown>,\n )) {\n if (typeof pluginValue === \"string\") {\n const next = ensureTargetedRef(pluginValue, `plugins.${pluginKey}`);\n if (next !== pluginValue) {\n (config.plugins as Record<string, unknown>)[pluginKey] = next;\n changed = true;\n }\n continue;\n }\n if (!pluginValue || typeof pluginValue !== \"object\") continue;\n changed =\n rewriteExtendsTarget(pluginValue as Record<string, unknown>, `plugins.${pluginKey}`) ||\n changed;\n }\n }\n\n return changed;\n}\n\nfunction migratePluginProviderConfig(config: Record<string, unknown>, pluginKey: string): boolean {\n let changed = false;\n if (!config.plugins || typeof config.plugins !== \"object\") {\n return false;\n }\n\n const plugins = config.plugins as Record<string, unknown>;\n const entry = plugins[pluginKey];\n if (!entry || typeof entry !== \"object\") return false;\n\n const pluginEntry = entry as Record<string, unknown>;\n\n if (\"name\" in pluginEntry) {\n delete pluginEntry.name;\n changed = true;\n }\n\n if (typeof pluginEntry.development === \"string\" && pluginEntry.development.startsWith(\"local:\")) {\n if (\"extends\" in pluginEntry) {\n delete pluginEntry.extends;\n changed = true;\n }\n }\n\n changed = rewriteExtendsTarget(pluginEntry, `plugins.${pluginKey}`) || changed;\n\n return changed;\n}\n\nfunction mergePluginConfigIntoRoot(\n rootConfig: Record<string, unknown>,\n pluginKey: string,\n pluginConfig: Record<string, unknown>,\n): boolean {\n let changed = false;\n\n if (!rootConfig.plugins || typeof rootConfig.plugins !== \"object\") {\n rootConfig.plugins = {};\n changed = true;\n }\n const plugins = rootConfig.plugins as Record<string, unknown>;\n if (!plugins[pluginKey] || typeof plugins[pluginKey] !== \"object\") {\n plugins[pluginKey] = {};\n changed = true;\n }\n\n const entry = plugins[pluginKey] as Record<string, unknown>;\n\n const pluginData = extractPluginEntry(pluginConfig, pluginKey);\n\n const apiData = getApiEntry(pluginConfig);\n\n if (pluginData) {\n for (const key of [\n \"secrets\",\n \"variables\",\n \"routes\",\n \"sidebar\",\n \"production\",\n \"integrity\",\n \"proxy\",\n ] as const) {\n if (pluginData[key] !== undefined && entry[key] === undefined) {\n entry[key] = pluginData[key];\n changed = true;\n }\n }\n\n if (typeof pluginData.development === \"string\" && pluginData.development.startsWith(\"local:\")) {\n pluginData.development = `local:plugins/${pluginKey}`;\n }\n if (entry.development === undefined && pluginData.development !== undefined) {\n entry.development = pluginData.development;\n changed = true;\n }\n }\n\n if (apiData) {\n for (const key of [\n \"production\",\n \"integrity\",\n \"proxy\",\n \"variables\",\n \"secrets\",\n \"sidebar\",\n \"routes\",\n ] as const) {\n if (apiData[key] !== undefined && entry[key] === undefined) {\n entry[key] = apiData[key];\n changed = true;\n }\n }\n }\n\n if (\"extends\" in entry) {\n const extendsStr = typeof entry.extends === \"string\" ? entry.extends : undefined;\n if (!extendsStr || extendsStr.includes(`#plugins.${pluginKey}`)) {\n delete entry.extends;\n changed = true;\n }\n }\n\n if (\"name\" in entry) {\n delete entry.name;\n changed = true;\n }\n\n if (configHasTopLevelFields(pluginConfig, pluginKey)) {\n if (entry.routes === undefined && Array.isArray(pluginConfig.routes)) {\n entry.routes = pluginConfig.routes;\n changed = true;\n }\n if (entry.sidebar === undefined && Array.isArray(pluginConfig.sidebar)) {\n entry.sidebar = pluginConfig.sidebar;\n changed = true;\n }\n const api = getApiEntry(pluginConfig);\n if (api) {\n if (entry.routes === undefined && Array.isArray(api.routes)) {\n entry.routes = api.routes;\n changed = true;\n }\n if (entry.sidebar === undefined && Array.isArray(api.sidebar)) {\n entry.sidebar = api.sidebar;\n changed = true;\n }\n }\n }\n\n return changed;\n}\n\nfunction extractPluginEntry(\n pluginConfig: Record<string, unknown>,\n pluginKey: string,\n): Record<string, unknown> | null {\n if (\n pluginConfig.plugins &&\n typeof pluginConfig.plugins === \"object\" &&\n (pluginConfig.plugins as Record<string, unknown>)[pluginKey] &&\n typeof (pluginConfig.plugins as Record<string, unknown>)[pluginKey] === \"object\"\n ) {\n return (pluginConfig.plugins as Record<string, unknown>)[pluginKey] as Record<string, unknown>;\n }\n\n const fallback: Record<string, unknown> = {};\n if (pluginConfig.sidebar !== undefined) {\n fallback.sidebar = pluginConfig.sidebar;\n }\n if (pluginConfig.routes !== undefined) {\n fallback.routes = pluginConfig.routes;\n }\n if (Object.keys(fallback).length > 0) {\n return fallback;\n }\n\n return null;\n}\n\nfunction configHasTopLevelFields(\n pluginConfig: Record<string, unknown>,\n _pluginKey: string,\n): boolean {\n return (\n (pluginConfig.routes !== undefined && Array.isArray(pluginConfig.routes)) ||\n (pluginConfig.sidebar !== undefined && Array.isArray(pluginConfig.sidebar)) ||\n getApiEntry(pluginConfig) !== null\n );\n}\n\nfunction getApiEntry(pluginConfig: Record<string, unknown>): Record<string, unknown> | null {\n if (!pluginConfig.app || typeof pluginConfig.app !== \"object\") return null;\n const app = pluginConfig.app as Record<string, unknown>;\n if (!app.api || typeof app.api !== \"object\") return null;\n return app.api as Record<string, unknown>;\n}\n\nexport async function migrateBosConfigFiles(projectDir: string): Promise<string[]> {\n const migrated: string[] = [];\n const rootConfigPath = join(projectDir, \"bos.config.json\");\n\n if (existsSync(rootConfigPath)) {\n const rootConfig = JSON.parse(readFileSync(rootConfigPath, \"utf-8\")) as Record<string, unknown>;\n let rootChanged = migrateRootConfigTargets(rootConfig);\n\n const pluginConfigPaths = await glob(\"plugins/*/bos.config.json\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n });\n\n for (const relativePath of pluginConfigPaths) {\n const match = relativePath.match(/^plugins\\/([^/]+)\\/bos\\.config\\.json$/);\n const pluginKey = match?.[1];\n if (!pluginKey) continue;\n\n const filePath = join(projectDir, relativePath);\n try {\n const pluginConfig = JSON.parse(readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n rootChanged = mergePluginConfigIntoRoot(rootConfig, pluginKey, pluginConfig) || rootChanged;\n } catch {}\n\n try {\n rmSync(filePath);\n migrated.push(relativePath);\n } catch {}\n }\n\n if (rootConfig.plugins && typeof rootConfig.plugins === \"object\") {\n for (const pluginKey of Object.keys(rootConfig.plugins as Record<string, unknown>)) {\n rootChanged = migratePluginProviderConfig(rootConfig, pluginKey) || rootChanged;\n }\n }\n\n if (rootChanged || migrated.length > 0) {\n await saveBosConfig(projectDir, rootConfig);\n if (!migrated.includes(\"bos.config.json\")) {\n migrated.push(\"bos.config.json\");\n }\n }\n }\n\n return migrated;\n}\n\nasync function loadParentPluginOptions(projectDir: string): Promise<{\n localConfig: Record<string, unknown>;\n parentPlugins: Record<string, unknown>;\n newPluginKeys: string[];\n} | null> {\n const configPath = join(projectDir, \"bos.config.json\");\n if (!existsSync(configPath)) {\n return null;\n }\n\n const localConfig = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n const extendsRef = getExtendsRef(localConfig);\n if (!extendsRef?.startsWith(\"bos://\")) {\n return null;\n }\n\n const parsed = parseBosRef(extendsRef);\n if (!parsed) {\n return null;\n }\n\n let parentConfig: Record<string, unknown>;\n try {\n parentConfig = await fetchParentConfig(parsed.account, parsed.gateway);\n } catch {\n return null;\n }\n\n const parentPlugins =\n parentConfig.plugins && typeof parentConfig.plugins === \"object\"\n ? (parentConfig.plugins as Record<string, unknown>)\n : {};\n const localPlugins =\n localConfig.plugins && typeof localConfig.plugins === \"object\"\n ? (localConfig.plugins as Record<string, unknown>)\n : {};\n\n const newPluginKeys = Object.keys(parentPlugins).filter((key) => !(key in localPlugins));\n return { localConfig, parentPlugins, newPluginKeys };\n}\n\nasync function addSelectedParentPlugins(projectDir: string): Promise<string[]> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n return [];\n }\n\n const pluginOptions = await loadParentPluginOptions(projectDir);\n if (!pluginOptions || pluginOptions.newPluginKeys.length === 0) {\n return [];\n }\n\n const selectedValue = await p.multiselect({\n message: \"Select new plugins from parent:\",\n options: pluginOptions.newPluginKeys.map((key) => ({ value: key, label: key })),\n required: false,\n });\n\n if (p.isCancel(selectedValue)) {\n process.exit(0);\n }\n\n const selected = selectedValue as string[];\n if (selected.length === 0) {\n return [];\n }\n\n const localPlugins =\n pluginOptions.localConfig.plugins && typeof pluginOptions.localConfig.plugins === \"object\"\n ? (pluginOptions.localConfig.plugins as Record<string, unknown>)\n : {};\n const nextPlugins = { ...localPlugins };\n for (const key of selected) {\n const parentPlugin = pluginOptions.parentPlugins[key];\n if (parentPlugin && typeof parentPlugin === \"object\") {\n const nextPlugin = structuredClone(parentPlugin as Record<string, unknown>);\n rewriteExtendsTarget(nextPlugin, `plugins.${key}`);\n nextPlugins[key] = nextPlugin;\n } else if (typeof parentPlugin === \"string\") {\n nextPlugins[key] = ensureTargetedRef(parentPlugin, `plugins.${key}`);\n } else {\n nextPlugins[key] = parentPlugin;\n }\n }\n\n pluginOptions.localConfig.plugins = nextPlugins;\n await saveBosConfig(projectDir, pluginOptions.localConfig);\n\n return selected;\n}\n\nfunction readInstalledVersion(projectDir: string, packageName: string): string | undefined {\n return readInstalledFrameworkVersion(projectDir, packageName);\n}\n\nfunction setCatalogRef(field: Record<string, string> | undefined, packageName: string): 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\nfunction updateWorkspacePackageRefInFile(filePath: string, packageName: string): boolean {\n const pkg = JSON.parse(readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\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 (setCatalogRef(field, packageName)) {\n modified = true;\n }\n }\n\n if (modified) {\n writeFileSync(filePath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n return modified;\n}\n\nfunction updateRootPackageVersion(\n projectDir: string,\n packageName: string,\n newVersion: string,\n): boolean {\n const pkgPath = join(projectDir, \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\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 (setCatalogRef(field, packageName)) {\n modified = true;\n }\n }\n\n if (!pkg.workspaces || typeof pkg.workspaces !== \"object\") {\n pkg.workspaces = { packages: [], catalog: {} };\n modified = true;\n }\n\n const workspaces = pkg.workspaces as { packages?: string[]; catalog?: Record<string, string> };\n if (!workspaces.catalog || typeof workspaces.catalog !== \"object\") {\n workspaces.catalog = {};\n modified = true;\n }\n\n const nextVersion = newVersion;\n if (workspaces.catalog[packageName] !== nextVersion) {\n workspaces.catalog[packageName] = nextVersion;\n modified = true;\n }\n\n if (modified) {\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n return modified;\n}\n\nfunction updateRootCatalogVersion(\n projectDir: string,\n packageName: string,\n newVersion: string,\n): boolean {\n const pkgPath = join(projectDir, \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n\n if (!pkg.workspaces || typeof pkg.workspaces !== \"object\") {\n pkg.workspaces = { packages: [], catalog: {} };\n }\n const workspaces = pkg.workspaces as { packages?: string[]; catalog?: Record<string, string> };\n if (!workspaces.catalog || typeof workspaces.catalog !== \"object\") {\n workspaces.catalog = {};\n }\n\n const nextVersion = newVersion;\n if (workspaces.catalog[packageName] === nextVersion) return false;\n\n workspaces.catalog[packageName] = nextVersion;\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nasync function findWorkspacePackageJsons(projectDir: string): Promise<string[]> {\n const rootPkgPath = join(projectDir, \"package.json\");\n if (!existsSync(rootPkgPath)) return [];\n\n const rootPkg = JSON.parse(readFileSync(rootPkgPath, \"utf-8\")) as Record<string, unknown>;\n const workspaceConfig = rootPkg.workspaces as { packages?: string[] } | string[] | undefined;\n\n const patterns: string[] = [];\n if (Array.isArray(workspaceConfig)) {\n patterns.push(...workspaceConfig);\n } else if (workspaceConfig?.packages && Array.isArray(workspaceConfig.packages)) {\n patterns.push(...workspaceConfig.packages);\n }\n\n if (patterns.length === 0) return [];\n\n const pkgPaths: string[] = [];\n for (const pattern of patterns) {\n const matches = await glob(pattern, { cwd: projectDir, dot: false, absolute: false });\n for (const match of matches) {\n const pkgPath = join(projectDir, match, \"package.json\");\n if (existsSync(pkgPath) && statSync(pkgPath).isFile()) {\n pkgPaths.push(pkgPath);\n }\n }\n }\n\n return [...new Set(pkgPaths)];\n}\n\nfunction buildChangelogUrl(\n oldVersion: string | undefined,\n newVersion: string,\n parentConfig: Record<string, unknown> | null,\n): string | undefined {\n if (!oldVersion || oldVersion === newVersion) return undefined;\n const repoUrl = parentConfig?.repository as string | undefined;\n if (!repoUrl) return undefined;\n\n const githubMatch = repoUrl.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/);\n if (!githubMatch) return undefined;\n\n const [, owner, repo] = githubMatch;\n return `https://github.com/${owner}/${repo}/compare/v${oldVersion}...v${newVersion}`;\n}\n\nasync function rewriteLegacyUiImports(projectDir: string): Promise<string[]> {\n const files = await glob(\"ui/src/**/*.{ts,tsx}\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n });\n const migrated: string[] = [];\n\n for (const file of files) {\n const filePath = join(projectDir, file);\n const original = readFileSync(filePath, \"utf-8\");\n let next = original;\n\n for (const [from, to] of LEGACY_UI_IMPORT_REWRITES) {\n next = next.replaceAll(from, to);\n }\n\n if (next !== original) {\n writeFileSync(filePath, next);\n migrated.push(file);\n }\n }\n\n return migrated;\n}\n\nexport async function upgradeTemplate(\n projectDir: string,\n options: UpgradeOptions,\n): Promise<UpgradeResult> {\n const timings: PhaseTiming[] = [];\n const pkgPath = join(projectDir, \"package.json\");\n if (!existsSync(pkgPath)) {\n return {\n status: \"error\",\n packages: [],\n timings,\n error: \"No package.json found in current directory\",\n };\n }\n\n const sourceRootCatalog = await readExtendedRootCatalog(projectDir);\n\n const { packages, catalogVersionUpdates } = await timePhase(\n timings,\n \"check package versions\",\n async () => {\n const nextPackages: UpgradeResult[\"packages\"] = [];\n\n for (const name of FRAMEWORK_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n const latest = extractVersion(sourceRootCatalog[name]);\n\n if (!latest) {\n nextPackages.push({ name, from: installed, to: installed ?? \"unknown\" });\n continue;\n }\n\n nextPackages.push({ name, from: installed, to: latest });\n }\n\n const nextCatalogVersionUpdates: Array<{\n name: string;\n from: string | undefined;\n to: string;\n }> = [];\n for (const name of CATALOG_TOOL_PACKAGES) {\n const installed = readInstalledVersion(projectDir, name);\n if (!installed) continue;\n const targetVersion =\n PINNED_CATALOG_TOOL_VERSIONS[name] ??\n extractVersion(sourceRootCatalog[name]) ??\n installed;\n if (installed === targetVersion) continue;\n nextCatalogVersionUpdates.push({ name, from: installed, to: targetVersion });\n }\n\n return { packages: nextPackages, catalogVersionUpdates: nextCatalogVersionUpdates };\n },\n );\n\n const hasFrameworkUpdates = packages.some((p) => p.from !== p.to && p.from !== undefined);\n const hasCatalogUpdates = catalogVersionUpdates.length > 0;\n const hasUpdates = hasFrameworkUpdates || hasCatalogUpdates;\n\n if (options.dryRun) {\n let changelogUrl: string | undefined;\n const pluginOptions = options.noSync\n ? null\n : await timePhase(timings, \"discover parent plugins\", () =>\n loadParentPluginOptions(projectDir),\n );\n if (hasUpdates) {\n const configPath = join(projectDir, \"bos.config.json\");\n let parentConfig: Record<string, unknown> | null = null;\n if (existsSync(configPath)) {\n try {\n parentConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n } catch {}\n }\n const mainPkg = packages.find((p) => p.name === \"everything-dev\");\n if (mainPkg?.from && mainPkg.from !== mainPkg.to) {\n changelogUrl = buildChangelogUrl(mainPkg.from, mainPkg.to, parentConfig);\n }\n }\n\n return {\n status: \"dry-run\",\n packages: [\n ...packages,\n ...catalogVersionUpdates.map((u) => ({ name: u.name, from: u.from, to: u.to })),\n ],\n availablePlugins: pluginOptions?.newPluginKeys,\n timings,\n changelogUrl,\n };\n }\n\n await timePhase(timings, \"apply package updates\", async () => {\n for (const pkg of packages) {\n if (pkg.from !== undefined && pkg.from !== pkg.to) {\n updateRootPackageVersion(projectDir, pkg.name, pkg.to);\n }\n }\n\n for (const update of catalogVersionUpdates) {\n updateRootCatalogVersion(projectDir, update.name, update.to);\n }\n\n const workspacePkgPaths = await findWorkspacePackageJsons(projectDir);\n for (const pkgPath of workspacePkgPaths) {\n for (const pkg of packages) {\n if (pkg.from !== undefined && pkg.from !== pkg.to) {\n updateWorkspacePackageRefInFile(pkgPath, pkg.name);\n }\n }\n for (const update of catalogVersionUpdates) {\n updateWorkspacePackageRefInFile(pkgPath, update.name);\n }\n }\n });\n\n const migratedBosConfigs = await timePhase(timings, \"migrate bos configs\", () =>\n migrateBosConfigFiles(projectDir),\n );\n\n let syncResult: UpgradeResult[\"sync\"];\n let addedPlugins: string[] = [];\n if (!options.noSync) {\n addedPlugins = await timePhase(timings, \"discover parent plugins\", async () => {\n if (options.dryRun) return [];\n return addSelectedParentPlugins(projectDir);\n });\n\n syncResult = await timePhase(timings, \"sync template\", () =>\n syncTemplate(projectDir, {\n dryRun: false,\n force: options.force,\n noInstall: true,\n }),\n );\n }\n\n if ((hasUpdates || addedPlugins.length > 0) && !options.noInstall) {\n await timePhase(timings, \"install dependencies\", () => runBunInstallForUpgrade(projectDir));\n await timePhase(timings, \"generate types\", () => runTypesGen(projectDir));\n }\n\n const migratedFiles = await timePhase(timings, \"clean obsolete files\", async () => {\n const nextMigratedFiles = [\n ...migratedBosConfigs,\n ...(await rewriteLegacyUiImports(projectDir)),\n ];\n for (const file of OBSOLETE_FILES) {\n const filePath = join(projectDir, file);\n if (existsSync(filePath)) {\n rmSync(filePath);\n nextMigratedFiles.push(file);\n }\n }\n return nextMigratedFiles;\n });\n\n let changelogUrl: string | undefined;\n const mainPkg = packages.find((p) => p.name === \"everything-dev\");\n if (mainPkg?.from && mainPkg.from !== mainPkg.to) {\n const configPath = join(projectDir, \"bos.config.json\");\n let parentConfig: Record<string, unknown> | null = null;\n if (existsSync(configPath)) {\n try {\n parentConfig = JSON.parse(readFileSync(configPath, \"utf-8\"));\n } catch {}\n }\n changelogUrl = buildChangelogUrl(mainPkg.from, mainPkg.to, parentConfig);\n }\n\n return {\n status: \"upgraded\",\n packages: [\n ...packages,\n ...catalogVersionUpdates.map((u) => ({ name: u.name, from: u.from, to: u.to })),\n ],\n sync: syncResult,\n migrated: migratedFiles.length > 0 ? migratedFiles : undefined,\n selectedPlugins: addedPlugins.length > 0 ? addedPlugins : undefined,\n timings,\n changelogUrl,\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { resolveExtendsRef } from "../merge.mjs";
1
+ import { isPlainObject, resolveExtendsRef } from "../merge.mjs";
2
2
  import { saveBosConfig } from "../utils/save-config.mjs";
3
- import { fetchParentConfig, runBunInstallForUpgrade, runTypesGen } from "./init.mjs";
3
+ import { fetchParentConfig, resolveSourceDir, runBunInstallForUpgrade, runTypesGen } from "./init.mjs";
4
4
  import { readInstalledFrameworkVersion } from "./framework-version.mjs";
5
5
  import { syncTemplate } from "./sync.mjs";
6
6
  import { timePhase } from "./timing.mjs";
@@ -24,6 +24,12 @@ const CATALOG_TOOL_PACKAGES = [
24
24
  "@module-federation/sdk",
25
25
  "@module-federation/dts-plugin"
26
26
  ];
27
+ const PINNED_CATALOG_TOOL_VERSIONS = {
28
+ "@rspack/core": "1.7.11",
29
+ "@rspack/cli": "1.7.11",
30
+ "@rsbuild/core": "1.7.5",
31
+ "@rsbuild/plugin-react": "1.4.6"
32
+ };
27
33
  const LEGACY_UI_IMPORT_REWRITES = [
28
34
  ["from \"@/auth\"", "from \"@/app\""],
29
35
  ["from '@/auth'", "from '@/app'"],
@@ -44,8 +50,35 @@ const OBSOLETE_FILES = [
44
50
  "ui/scripts/generate-metadata.ts",
45
51
  ".github/dependabot.yml",
46
52
  ".github/templates/dependabot.yml",
47
- "packages/everything-dev/cli.js"
53
+ "packages/everything-dev/cli.js",
54
+ ".templatekeep",
55
+ ".templatesync-exclude"
48
56
  ];
57
+ function extractVersion(value) {
58
+ if (!value) return null;
59
+ return value.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/)?.[0] ?? null;
60
+ }
61
+ async function readExtendedRootCatalog(projectDir) {
62
+ const configPath = join(projectDir, "bos.config.json");
63
+ if (!existsSync(configPath)) return {};
64
+ const localConfig = JSON.parse(readFileSync(configPath, "utf-8"));
65
+ let extendsRef;
66
+ if (typeof localConfig.extends === "string") extendsRef = localConfig.extends;
67
+ else if (isPlainObject(localConfig.extends)) extendsRef = resolveExtendsRef(localConfig.extends, "production");
68
+ const parsed = extendsRef ? parseBosRef(extendsRef) : null;
69
+ if (!parsed) return {};
70
+ const { sourceDir, cleanup } = await resolveSourceDir({
71
+ extendsAccount: parsed.account,
72
+ extendsGateway: parsed.gateway
73
+ });
74
+ try {
75
+ const sourcePkgPath = join(sourceDir, "package.json");
76
+ if (!existsSync(sourcePkgPath)) return {};
77
+ return { ...JSON.parse(readFileSync(sourcePkgPath, "utf-8")).workspaces?.catalog ?? {} };
78
+ } finally {
79
+ await cleanup();
80
+ }
81
+ }
49
82
  function getExtendsRef(config) {
50
83
  if (typeof config.extends === "string") return config.extends;
51
84
  if (config.extends && typeof config.extends === "object") return resolveExtendsRef(config.extends, "production");
@@ -312,18 +345,6 @@ async function addSelectedParentPlugins(projectDir) {
312
345
  await saveBosConfig(projectDir, pluginOptions.localConfig);
313
346
  return selected;
314
347
  }
315
- async function fetchLatestNpmVersion(packageName) {
316
- try {
317
- const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
318
- headers: { Accept: "application/json" },
319
- signal: AbortSignal.timeout(1e4)
320
- });
321
- if (!response.ok) return null;
322
- return (await response.json()).version;
323
- } catch {
324
- return null;
325
- }
326
- }
327
348
  function readInstalledVersion(projectDir, packageName) {
328
349
  return readInstalledFrameworkVersion(projectDir, packageName);
329
350
  }
@@ -371,7 +392,7 @@ function updateRootPackageVersion(projectDir, packageName, newVersion) {
371
392
  workspaces.catalog = {};
372
393
  modified = true;
373
394
  }
374
- const nextVersion = `^${newVersion}`;
395
+ const nextVersion = newVersion;
375
396
  if (workspaces.catalog[packageName] !== nextVersion) {
376
397
  workspaces.catalog[packageName] = nextVersion;
377
398
  modified = true;
@@ -388,7 +409,7 @@ function updateRootCatalogVersion(projectDir, packageName, newVersion) {
388
409
  };
389
410
  const workspaces = pkg.workspaces;
390
411
  if (!workspaces.catalog || typeof workspaces.catalog !== "object") workspaces.catalog = {};
391
- const nextVersion = `^${newVersion}`;
412
+ const nextVersion = newVersion;
392
413
  if (workspaces.catalog[packageName] === nextVersion) return false;
393
414
  workspaces.catalog[packageName] = nextVersion;
394
415
  writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
@@ -453,11 +474,12 @@ async function upgradeTemplate(projectDir, options) {
453
474
  timings,
454
475
  error: "No package.json found in current directory"
455
476
  };
477
+ const sourceRootCatalog = await readExtendedRootCatalog(projectDir);
456
478
  const { packages, catalogVersionUpdates } = await timePhase(timings, "check package versions", async () => {
457
479
  const nextPackages = [];
458
480
  for (const name of FRAMEWORK_PACKAGES) {
459
481
  const installed = readInstalledVersion(projectDir, name);
460
- const latest = await fetchLatestNpmVersion(name);
482
+ const latest = extractVersion(sourceRootCatalog[name]);
461
483
  if (!latest) {
462
484
  nextPackages.push({
463
485
  name,
@@ -476,13 +498,12 @@ async function upgradeTemplate(projectDir, options) {
476
498
  for (const name of CATALOG_TOOL_PACKAGES) {
477
499
  const installed = readInstalledVersion(projectDir, name);
478
500
  if (!installed) continue;
479
- const latest = await fetchLatestNpmVersion(name);
480
- if (!latest) continue;
481
- if (installed === latest) continue;
501
+ const targetVersion = PINNED_CATALOG_TOOL_VERSIONS[name] ?? extractVersion(sourceRootCatalog[name]) ?? installed;
502
+ if (installed === targetVersion) continue;
482
503
  nextCatalogVersionUpdates.push({
483
504
  name,
484
505
  from: installed,
485
- to: latest
506
+ to: targetVersion
486
507
  });
487
508
  }
488
509
  return {