everything-dev 1.12.3 → 1.13.1

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 (124) hide show
  1. package/cli.js +1 -1
  2. package/dist/app.cjs +24 -101
  3. package/dist/app.cjs.map +1 -1
  4. package/dist/app.mjs +25 -102
  5. package/dist/app.mjs.map +1 -1
  6. package/dist/cli/init.cjs +143 -66
  7. package/dist/cli/init.cjs.map +1 -1
  8. package/dist/cli/init.d.cts +1 -1
  9. package/dist/cli/init.d.cts.map +1 -1
  10. package/dist/cli/init.d.mts +1 -1
  11. package/dist/cli/init.d.mts.map +1 -1
  12. package/dist/cli/init.mjs +144 -67
  13. package/dist/cli/init.mjs.map +1 -1
  14. package/dist/cli/prompts.cjs +3 -3
  15. package/dist/cli/prompts.cjs.map +1 -1
  16. package/dist/cli/prompts.mjs +3 -3
  17. package/dist/cli/prompts.mjs.map +1 -1
  18. package/dist/cli/sync.cjs +15 -56
  19. package/dist/cli/sync.cjs.map +1 -1
  20. package/dist/cli/sync.mjs +15 -56
  21. package/dist/cli/sync.mjs.map +1 -1
  22. package/dist/cli/upgrade.cjs +3 -1
  23. package/dist/cli/upgrade.cjs.map +1 -1
  24. package/dist/cli/upgrade.mjs +3 -1
  25. package/dist/cli/upgrade.mjs.map +1 -1
  26. package/dist/config.cjs +223 -81
  27. package/dist/config.cjs.map +1 -1
  28. package/dist/config.d.cts +21 -5
  29. package/dist/config.d.cts.map +1 -1
  30. package/dist/config.d.mts +21 -5
  31. package/dist/config.d.mts.map +1 -1
  32. package/dist/config.mjs +217 -83
  33. package/dist/config.mjs.map +1 -1
  34. package/dist/contract.d.cts +104 -8
  35. package/dist/contract.d.cts.map +1 -1
  36. package/dist/contract.d.mts +104 -8
  37. package/dist/contract.d.mts.map +1 -1
  38. package/dist/host.cjs +34 -1
  39. package/dist/host.cjs.map +1 -1
  40. package/dist/host.d.cts.map +1 -1
  41. package/dist/host.d.mts.map +1 -1
  42. package/dist/host.mjs +34 -1
  43. package/dist/host.mjs.map +1 -1
  44. package/dist/index.cjs +17 -0
  45. package/dist/index.d.cts +5 -3
  46. package/dist/index.d.mts +5 -3
  47. package/dist/index.mjs +5 -3
  48. package/dist/merge.cjs +113 -0
  49. package/dist/merge.cjs.map +1 -0
  50. package/dist/merge.d.cts +7 -0
  51. package/dist/merge.d.cts.map +1 -0
  52. package/dist/merge.d.mts +7 -0
  53. package/dist/merge.d.mts.map +1 -0
  54. package/dist/merge.mjs +107 -0
  55. package/dist/merge.mjs.map +1 -0
  56. package/dist/plugin.cjs +117 -105
  57. package/dist/plugin.cjs.map +1 -1
  58. package/dist/plugin.d.cts +114 -8
  59. package/dist/plugin.d.cts.map +1 -1
  60. package/dist/plugin.d.mts +114 -8
  61. package/dist/plugin.d.mts.map +1 -1
  62. package/dist/plugin.mjs +117 -105
  63. package/dist/plugin.mjs.map +1 -1
  64. package/dist/service-descriptor.cjs +21 -0
  65. package/dist/service-descriptor.cjs.map +1 -1
  66. package/dist/service-descriptor.d.cts +23 -1
  67. package/dist/service-descriptor.d.cts.map +1 -1
  68. package/dist/service-descriptor.d.mts +23 -1
  69. package/dist/service-descriptor.d.mts.map +1 -1
  70. package/dist/service-descriptor.mjs +21 -0
  71. package/dist/service-descriptor.mjs.map +1 -1
  72. package/dist/shared.cjs +24 -2
  73. package/dist/shared.cjs.map +1 -1
  74. package/dist/shared.d.cts +3 -0
  75. package/dist/shared.d.cts.map +1 -1
  76. package/dist/shared.d.mts +3 -0
  77. package/dist/shared.d.mts.map +1 -1
  78. package/dist/shared.mjs +25 -3
  79. package/dist/shared.mjs.map +1 -1
  80. package/dist/sidebar.cjs +124 -0
  81. package/dist/sidebar.cjs.map +1 -0
  82. package/dist/sidebar.d.cts +8 -0
  83. package/dist/sidebar.d.cts.map +1 -0
  84. package/dist/sidebar.d.mts +8 -0
  85. package/dist/sidebar.d.mts.map +1 -0
  86. package/dist/sidebar.mjs +122 -0
  87. package/dist/sidebar.mjs.map +1 -0
  88. package/dist/types.cjs +104 -10
  89. package/dist/types.cjs.map +1 -1
  90. package/dist/types.d.cts +256 -29
  91. package/dist/types.d.cts.map +1 -1
  92. package/dist/types.d.mts +256 -29
  93. package/dist/types.d.mts.map +1 -1
  94. package/dist/types.mjs +100 -11
  95. package/dist/types.mjs.map +1 -1
  96. package/dist/utils/path-match.cjs +18 -0
  97. package/dist/utils/path-match.cjs.map +1 -0
  98. package/dist/utils/path-match.mjs +17 -0
  99. package/dist/utils/path-match.mjs.map +1 -0
  100. package/dist/utils/save-config.cjs +19 -0
  101. package/dist/utils/save-config.cjs.map +1 -0
  102. package/dist/utils/save-config.mjs +18 -0
  103. package/dist/utils/save-config.mjs.map +1 -0
  104. package/package.json +3 -2
  105. package/skills/dev-workflow/SKILL.md +8 -0
  106. package/skills/extends-config/SKILL.md +132 -0
  107. package/skills/init-upgrade/SKILL.md +128 -0
  108. package/skills/publish-sync/SKILL.md +30 -0
  109. package/src/app.ts +23 -118
  110. package/src/cli/init.ts +199 -100
  111. package/src/cli/prompts.ts +2 -2
  112. package/src/cli/sync.ts +27 -96
  113. package/src/cli/upgrade.ts +2 -0
  114. package/src/config.ts +356 -132
  115. package/src/host.ts +45 -0
  116. package/src/index.ts +1 -0
  117. package/src/merge.ts +198 -0
  118. package/src/plugin.ts +340 -318
  119. package/src/service-descriptor.ts +23 -0
  120. package/src/shared.ts +48 -5
  121. package/src/sidebar.ts +162 -0
  122. package/src/types.ts +134 -28
  123. package/src/utils/path-match.ts +16 -0
  124. package/src/utils/save-config.ts +20 -0
@@ -24,7 +24,9 @@ const OBSOLETE_FILES = [
24
24
  "ui/src/api-contract.gen.ts",
25
25
  "ui/src/lib/auth-client.ts",
26
26
  "ui/src/lib/session.ts",
27
- "ui/scripts/generate-metadata.ts"
27
+ "ui/scripts/generate-metadata.ts",
28
+ ".github/dependabot.yml",
29
+ ".github/templates/dependabot.yml"
28
30
  ];
29
31
  async function fetchLatestNpmVersion(packageName) {
30
32
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.mjs","names":[],"sources":["../../src/cli/upgrade.ts"],"sourcesContent":["import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { glob } from \"glob\";\nimport type { UpgradeOptions, UpgradeResult } from \"../contract\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { runBunInstall, runTypesGen } from \"./init\";\nimport { syncTemplate } from \"./sync\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\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];\n\ninterface NpmPackageInfo {\n version: string;\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\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 pkgPath = join(projectDir, \"package.json\");\n if (!existsSync(pkgPath)) {\n return {\n status: \"error\",\n packages: [],\n error: \"No package.json found in current directory\",\n };\n }\n\n const packages: 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 packages.push({ name, from: installed, to: installed ?? \"unknown\" });\n continue;\n }\n\n packages.push({ name, from: installed, to: latest });\n }\n\n const hasUpdates = packages.some((p) => p.from !== p.to && p.from !== undefined);\n\n if (options.dryRun) {\n let changelogUrl: string | undefined;\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 changelogUrl,\n };\n }\n\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 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 }\n\n if (hasUpdates && !options.noInstall) {\n await runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n let syncResult: UpgradeResult[\"sync\"];\n if (!options.noSync) {\n syncResult = await syncTemplate(projectDir, {\n dryRun: false,\n force: options.force,\n noInstall: true,\n });\n }\n\n const migratedFiles = await rewriteLegacyUiImports(projectDir);\n for (const file of OBSOLETE_FILES) {\n const filePath = join(projectDir, file);\n if (existsSync(filePath)) {\n rmSync(filePath);\n migratedFiles.push(file);\n }\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 sync: syncResult,\n migrated: migratedFiles.length > 0 ? migratedFiles : undefined,\n changelogUrl,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"upgrade.mjs","names":[],"sources":["../../src/cli/upgrade.ts"],"sourcesContent":["import { existsSync, readFileSync, rmSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { glob } from \"glob\";\nimport type { UpgradeOptions, UpgradeResult } from \"../contract\";\nimport { readInstalledFrameworkVersion } from \"./framework-version\";\nimport { runBunInstall, runTypesGen } from \"./init\";\nimport { syncTemplate } from \"./sync\";\n\nconst FRAMEWORK_PACKAGES = [\"everything-dev\", \"every-plugin\"];\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];\n\ninterface NpmPackageInfo {\n version: string;\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\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 pkgPath = join(projectDir, \"package.json\");\n if (!existsSync(pkgPath)) {\n return {\n status: \"error\",\n packages: [],\n error: \"No package.json found in current directory\",\n };\n }\n\n const packages: 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 packages.push({ name, from: installed, to: installed ?? \"unknown\" });\n continue;\n }\n\n packages.push({ name, from: installed, to: latest });\n }\n\n const hasUpdates = packages.some((p) => p.from !== p.to && p.from !== undefined);\n\n if (options.dryRun) {\n let changelogUrl: string | undefined;\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 changelogUrl,\n };\n }\n\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 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 }\n\n if (hasUpdates && !options.noInstall) {\n await runBunInstall(projectDir);\n await runTypesGen(projectDir);\n }\n\n let syncResult: UpgradeResult[\"sync\"];\n if (!options.noSync) {\n syncResult = await syncTemplate(projectDir, {\n dryRun: false,\n force: options.force,\n noInstall: true,\n });\n }\n\n const migratedFiles = await rewriteLegacyUiImports(projectDir);\n for (const file of OBSOLETE_FILES) {\n const filePath = join(projectDir, file);\n if (existsSync(filePath)) {\n rmSync(filePath);\n migratedFiles.push(file);\n }\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 sync: syncResult,\n migrated: migratedFiles.length > 0 ? migratedFiles : undefined,\n changelogUrl,\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,qBAAqB,CAAC,kBAAkB,eAAe;AAC7D,MAAM,4BAA4B;CAChC,CAAC,mBAAiB,iBAAe;CACjC,CAAC,iBAAiB,eAAe;CACjC,CAAC,iCAA+B,iBAAe;CAC/C,CAAC,+BAA+B,eAAe;CAC/C,CAAC,6BAA2B,iBAAe;CAC3C,CAAC,2BAA2B,eAAe;CAC5C;AACD,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAMD,eAAe,sBAAsB,aAA6C;AAChF,KAAI;EACF,MAAM,WAAW,MAAM,MAAM,8BAA8B,YAAY,UAAU;GAC/E,SAAS,EAAE,QAAQ,oBAAoB;GACvC,QAAQ,YAAY,QAAQ,IAAO;GACpC,CAAC;AACF,MAAI,CAAC,SAAS,GAAI,QAAO;AAEzB,UADc,MAAM,SAAS,MAAM,EACvB;SACN;AACN,SAAO;;;AAIX,SAAS,qBAAqB,YAAoB,aAAyC;AACzF,QAAO,8BAA8B,YAAY,YAAY;;AAG/D,SAAS,cAAc,OAA2C,aAA8B;AAC9F,KAAI,CAAC,SAAS,EAAE,eAAe,OAAQ,QAAO;AAC9C,KAAI,MAAM,iBAAiB,cAAc,MAAM,aAAa,WAAW,QAAQ,CAAE,QAAO;AACxF,OAAM,eAAe;AACrB,QAAO;;AAGT,SAAS,gCAAgC,UAAkB,aAA8B;CACvF,MAAM,MAAM,KAAK,MAAM,aAAa,UAAU,QAAQ,CAAC;CACvD,IAAI,WAAW;AAEf,MAAK,MAAM,aAAa;EAAC;EAAgB;EAAmB;EAAmB,EAAW;EACxF,MAAM,QAAQ,IAAI;AAClB,MAAI,cAAc,OAAO,YAAY,CACnC,YAAW;;AAIf,KAAI,SACF,eAAc,UAAU,GAAG,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC,IAAI;AAE9D,QAAO;;AAGT,SAAS,yBACP,YACA,aACA,YACS;CACT,MAAM,UAAU,KAAK,YAAY,eAAe;CAChD,MAAM,MAAM,KAAK,MAAM,aAAa,SAAS,QAAQ,CAAC;CACtD,IAAI,WAAW;AAEf,MAAK,MAAM,aAAa;EAAC;EAAgB;EAAmB;EAAmB,EAAW;EACxF,MAAM,QAAQ,IAAI;AAClB,MAAI,cAAc,OAAO,YAAY,CACnC,YAAW;;AAIf,KAAI,CAAC,IAAI,cAAc,OAAO,IAAI,eAAe,UAAU;AACzD,MAAI,aAAa;GAAE,UAAU,EAAE;GAAE,SAAS,EAAE;GAAE;AAC9C,aAAW;;CAGb,MAAM,aAAa,IAAI;AACvB,KAAI,CAAC,WAAW,WAAW,OAAO,WAAW,YAAY,UAAU;AACjE,aAAW,UAAU,EAAE;AACvB,aAAW;;CAGb,MAAM,cAAc,IAAI;AACxB,KAAI,WAAW,QAAQ,iBAAiB,aAAa;AACnD,aAAW,QAAQ,eAAe;AAClC,aAAW;;AAGb,KAAI,SACF,eAAc,SAAS,GAAG,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC,IAAI;AAG7D,QAAO;;AAGT,eAAe,0BAA0B,YAAuC;CAC9E,MAAM,cAAc,KAAK,YAAY,eAAe;AACpD,KAAI,CAAC,WAAW,YAAY,CAAE,QAAO,EAAE;CAGvC,MAAM,kBADU,KAAK,MAAM,aAAa,aAAa,QAAQ,CAAC,CAC9B;CAEhC,MAAM,WAAqB,EAAE;AAC7B,KAAI,MAAM,QAAQ,gBAAgB,CAChC,UAAS,KAAK,GAAG,gBAAgB;UACxB,iBAAiB,YAAY,MAAM,QAAQ,gBAAgB,SAAS,CAC7E,UAAS,KAAK,GAAG,gBAAgB,SAAS;AAG5C,KAAI,SAAS,WAAW,EAAG,QAAO,EAAE;CAEpC,MAAM,WAAqB,EAAE;AAC7B,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,MAAM,KAAK,SAAS;GAAE,KAAK;GAAY,KAAK;GAAO,UAAU;GAAO,CAAC;AACrF,OAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,UAAU,KAAK,YAAY,OAAO,eAAe;AACvD,OAAI,WAAW,QAAQ,IAAI,SAAS,QAAQ,CAAC,QAAQ,CACnD,UAAS,KAAK,QAAQ;;;AAK5B,QAAO,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;;AAG/B,SAAS,kBACP,YACA,YACA,cACoB;AACpB,KAAI,CAAC,cAAc,eAAe,WAAY,QAAO;CACrD,MAAM,UAAU,cAAc;AAC9B,KAAI,CAAC,QAAS,QAAO;CAErB,MAAM,cAAc,QAAQ,MAAM,wDAAwD;AAC1F,KAAI,CAAC,YAAa,QAAO;CAEzB,MAAM,GAAG,OAAO,QAAQ;AACxB,QAAO,sBAAsB,MAAM,GAAG,KAAK,YAAY,WAAW,MAAM;;AAG1E,eAAe,uBAAuB,YAAuC;CAC3E,MAAM,QAAQ,MAAM,KAAK,wBAAwB;EAC/C,KAAK;EACL,OAAO;EACP,KAAK;EACL,UAAU;EACX,CAAC;CACF,MAAM,WAAqB,EAAE;AAE7B,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,WAAW,KAAK,YAAY,KAAK;EACvC,MAAM,WAAW,aAAa,UAAU,QAAQ;EAChD,IAAI,OAAO;AAEX,OAAK,MAAM,CAAC,MAAM,OAAO,0BACvB,QAAO,KAAK,WAAW,MAAM,GAAG;AAGlC,MAAI,SAAS,UAAU;AACrB,iBAAc,UAAU,KAAK;AAC7B,YAAS,KAAK,KAAK;;;AAIvB,QAAO;;AAGT,eAAsB,gBACpB,YACA,SACwB;AAExB,KAAI,CAAC,WADW,KAAK,YAAY,eAAe,CACxB,CACtB,QAAO;EACL,QAAQ;EACR,UAAU,EAAE;EACZ,OAAO;EACR;CAGH,MAAM,WAAsC,EAAE;AAE9C,MAAK,MAAM,QAAQ,oBAAoB;EACrC,MAAM,YAAY,qBAAqB,YAAY,KAAK;EACxD,MAAM,SAAS,MAAM,sBAAsB,KAAK;AAEhD,MAAI,CAAC,QAAQ;AACX,YAAS,KAAK;IAAE;IAAM,MAAM;IAAW,IAAI,aAAa;IAAW,CAAC;AACpE;;AAGF,WAAS,KAAK;GAAE;GAAM,MAAM;GAAW,IAAI;GAAQ,CAAC;;CAGtD,MAAM,aAAa,SAAS,MAAM,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,OAAU;AAEhF,KAAI,QAAQ,QAAQ;EAClB,IAAI;AACJ,MAAI,YAAY;GACd,MAAM,aAAa,KAAK,YAAY,kBAAkB;GACtD,IAAI,eAA+C;AACnD,OAAI,WAAW,WAAW,CACxB,KAAI;AACF,mBAAe,KAAK,MAAM,aAAa,YAAY,QAAQ,CAAC;WACtD;GAEV,MAAM,UAAU,SAAS,MAAM,MAAM,EAAE,SAAS,iBAAiB;AACjE,OAAI,SAAS,QAAQ,QAAQ,SAAS,QAAQ,GAC5C,gBAAe,kBAAkB,QAAQ,MAAM,QAAQ,IAAI,aAAa;;AAI5E,SAAO;GACL,QAAQ;GACR;GACA;GACD;;AAGH,MAAK,MAAM,OAAO,SAChB,KAAI,IAAI,SAAS,UAAa,IAAI,SAAS,IAAI,GAC7C,0BAAyB,YAAY,IAAI,MAAM,IAAI,GAAG;CAI1D,MAAM,oBAAoB,MAAM,0BAA0B,WAAW;AACrE,MAAK,MAAM,WAAW,kBACpB,MAAK,MAAM,OAAO,SAChB,KAAI,IAAI,SAAS,UAAa,IAAI,SAAS,IAAI,GAC7C,iCAAgC,SAAS,IAAI,KAAK;AAKxD,KAAI,cAAc,CAAC,QAAQ,WAAW;AACpC,QAAM,cAAc,WAAW;AAC/B,QAAM,YAAY,WAAW;;CAG/B,IAAI;AACJ,KAAI,CAAC,QAAQ,OACX,cAAa,MAAM,aAAa,YAAY;EAC1C,QAAQ;EACR,OAAO,QAAQ;EACf,WAAW;EACZ,CAAC;CAGJ,MAAM,gBAAgB,MAAM,uBAAuB,WAAW;AAC9D,MAAK,MAAM,QAAQ,gBAAgB;EACjC,MAAM,WAAW,KAAK,YAAY,KAAK;AACvC,MAAI,WAAW,SAAS,EAAE;AACxB,UAAO,SAAS;AAChB,iBAAc,KAAK,KAAK;;;CAI5B,IAAI;CACJ,MAAM,UAAU,SAAS,MAAM,MAAM,EAAE,SAAS,iBAAiB;AACjE,KAAI,SAAS,QAAQ,QAAQ,SAAS,QAAQ,IAAI;EAChD,MAAM,aAAa,KAAK,YAAY,kBAAkB;EACtD,IAAI,eAA+C;AACnD,MAAI,WAAW,WAAW,CACxB,KAAI;AACF,kBAAe,KAAK,MAAM,aAAa,YAAY,QAAQ,CAAC;UACtD;AAEV,iBAAe,kBAAkB,QAAQ,MAAM,QAAQ,IAAI,aAAa;;AAG1E,QAAO;EACL,QAAQ;EACR;EACA,MAAM;EACN,UAAU,cAAc,SAAS,IAAI,gBAAgB;EACrD;EACD"}
package/dist/config.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
3
3
  const require_fastkv = require('./fastkv.cjs');
4
+ const require_merge = require('./merge.cjs');
4
5
  const require_network = require('./network.cjs');
5
6
  const require_types = require('./types.cjs');
6
7
  let node_fs = require("node:fs");
@@ -9,6 +10,7 @@ let node_path = require("node:path");
9
10
  //#region src/config.ts
10
11
  const LOCAL_PREFIX = "local:";
11
12
  const DEFAULT_HOST_PORT = 3e3;
13
+ const RESOLVED_CONFIG_FILENAME = "bos.resolved-config.json";
12
14
  let cachedConfig = null;
13
15
  let projectRoot = null;
14
16
  function clearConfigCache() {
@@ -38,16 +40,17 @@ async function loadConfig(options) {
38
40
  return null;
39
41
  }
40
42
  const baseDir = (0, node_path.dirname)(configPath);
43
+ const env = options?.env ?? "development";
44
+ const runtimeEnv = env === "staging" ? "production" : env;
41
45
  try {
42
46
  const extendedChain = [];
43
- const parsed = await resolveConfigWithExtends(configPath, baseDir, /* @__PURE__ */ new Set(), extendedChain);
47
+ const parsed = await resolveConfigWithExtends(configPath, baseDir, /* @__PURE__ */ new Set(), extendedChain, env);
44
48
  const config = require_types.BosConfigSchema.parse(parsed);
45
49
  cachedConfig = config;
46
50
  projectRoot = baseDir;
47
- const pluginRuntime = await resolveRuntimePlugins(config.plugins ?? {}, baseDir, options?.env ?? "development");
48
51
  return {
49
52
  config,
50
- runtime: buildRuntimeConfig(config, baseDir, options?.env ?? "development", { plugins: pluginRuntime }),
53
+ runtime: buildRuntimeConfig(config, baseDir, runtimeEnv, { plugins: await resolveRuntimePlugins(config.plugins ?? {}, baseDir, runtimeEnv) }),
51
54
  source: {
52
55
  path: configPath,
53
56
  extended: extendedChain.length > 0 ? extendedChain : void 0,
@@ -67,7 +70,60 @@ async function buildRuntimePluginsForConfig(config, baseDir, env) {
67
70
  const plugins = await resolveRuntimePlugins(config.plugins ?? {}, baseDir, env);
68
71
  return Object.keys(plugins).length > 0 ? plugins : void 0;
69
72
  }
70
- function resolveDevelopmentTarget(development, production, baseDir) {
73
+ function getResolvedConfigPath(configDir) {
74
+ return (0, node_path.join)(configDir, ".bos", RESOLVED_CONFIG_FILENAME);
75
+ }
76
+ function loadResolvedConfig(configDir) {
77
+ const resolvedPath = getResolvedConfigPath(configDir);
78
+ if (!(0, node_fs.existsSync)(resolvedPath)) return null;
79
+ try {
80
+ const raw = JSON.parse((0, node_fs.readFileSync)(resolvedPath, "utf-8"));
81
+ if (!require_merge.isPlainObject(raw)) return null;
82
+ const { _resolved, ...configData } = raw;
83
+ return require_types.BosConfigSchema.parse(configData);
84
+ } catch {
85
+ return null;
86
+ }
87
+ }
88
+ function writeResolvedConfig(configDir, config, env, extendsChain, source) {
89
+ const resolvedPath = getResolvedConfigPath(configDir);
90
+ const resolvedDir = (0, node_path.dirname)(resolvedPath);
91
+ if (!(0, node_fs.existsSync)(resolvedDir)) (0, node_fs.mkdirSync)(resolvedDir, { recursive: true });
92
+ const ordered = require_merge.rebuildOrderedConfig(config);
93
+ const output = {
94
+ _resolved: {
95
+ env,
96
+ resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
97
+ extendsChain: extendsChain ?? [],
98
+ ...source ? { source } : {}
99
+ },
100
+ ...ordered
101
+ };
102
+ const content = `${JSON.stringify(output, null, 2)}\n`;
103
+ try {
104
+ if ((0, node_fs.readFileSync)(resolvedPath, "utf-8") === content) return;
105
+ } catch {}
106
+ (0, node_fs.writeFileSync)(resolvedPath, content);
107
+ }
108
+ function resolveBosConfigPath(configDir) {
109
+ const resolvedPath = getResolvedConfigPath(configDir);
110
+ if ((0, node_fs.existsSync)(resolvedPath)) return resolvedPath;
111
+ return (0, node_path.join)(configDir, "bos.config.json");
112
+ }
113
+ function readBosConfigForBuild(configDir) {
114
+ const resolvedPath = getResolvedConfigPath(configDir);
115
+ if ((0, node_fs.existsSync)(resolvedPath)) try {
116
+ const raw = JSON.parse((0, node_fs.readFileSync)(resolvedPath, "utf-8"));
117
+ if (require_merge.isPlainObject(raw)) {
118
+ const { _resolved, ...configData } = raw;
119
+ return configData;
120
+ }
121
+ } catch {}
122
+ const bosConfigPath = (0, node_path.join)(configDir, "bos.config.json");
123
+ return JSON.parse((0, node_fs.readFileSync)(bosConfigPath, "utf-8"));
124
+ }
125
+ function resolveDevelopmentTarget(development, production, baseDir, forceSource) {
126
+ if (forceSource === "remote") return resolveRuntimeTarget(production, baseDir, "remote");
71
127
  const devTarget = resolveRuntimeTarget(development, baseDir);
72
128
  if (devTarget.source === "local" && (!devTarget.localPath || !(0, node_fs.existsSync)(devTarget.localPath))) return resolveRuntimeTarget(production, baseDir, "remote");
73
129
  return devTarget;
@@ -76,12 +132,15 @@ function buildRuntimeConfig(config, baseDir, env, options) {
76
132
  const uiConfig = config.app.ui;
77
133
  const apiConfig = config.app.api;
78
134
  const authConfig = config.app.auth;
79
- const uiRuntime = env === "development" ? resolveDevelopmentTarget(uiConfig.development, uiConfig.production, baseDir) : resolveRuntimeTarget(uiConfig.production, baseDir, "remote");
80
- const apiRuntime = env === "development" ? resolveDevelopmentTarget(apiConfig.development, apiConfig.production, baseDir) : resolveRuntimeTarget(apiConfig.production, baseDir, "remote");
81
- const authRuntime = authConfig ? env === "development" ? resolveDevelopmentTarget(authConfig.development, authConfig.production, baseDir) : resolveRuntimeTarget(authConfig.production, baseDir, "remote") : void 0;
135
+ const uiRuntime = env === "development" ? resolveDevelopmentTarget(uiConfig.development, uiConfig.production, baseDir, options?.uiSource) : resolveRuntimeTarget(uiConfig.production, baseDir, "remote");
136
+ const apiRuntime = env === "development" ? resolveDevelopmentTarget(apiConfig.development, apiConfig.production, baseDir, options?.apiSource) : resolveRuntimeTarget(apiConfig.production, baseDir, "remote");
137
+ const authRuntime = authConfig ? env === "development" ? resolveDevelopmentTarget(authConfig.development, authConfig.production, baseDir, options?.authSource) : resolveRuntimeTarget(authConfig.production, baseDir, "remote") : void 0;
82
138
  const hostConfig = config.app.host;
83
- const hostRuntime = env === "development" ? resolveDevelopmentTarget(hostConfig.development, hostConfig.production, baseDir) : resolveRuntimeTarget(hostConfig.production, baseDir, "remote");
84
- const hostListeningUrl = resolveDevelopmentHostUrl(hostConfig.development);
139
+ const hostRuntime = env === "development" ? resolveDevelopmentTarget(hostConfig.development, hostConfig.production, baseDir, options?.hostSource) : resolveRuntimeTarget(hostConfig.production, baseDir, "remote");
140
+ const hostListeningUrl = env === "development" ? resolveDevelopmentHostUrl(hostConfig.development) : `http://localhost:${hostRuntime.port ?? DEFAULT_HOST_PORT}`;
141
+ const hostIsRemote = hostRuntime.source === "remote";
142
+ const uiIsRemote = uiRuntime.source === "remote";
143
+ const apiIsRemote = apiRuntime.source === "remote";
85
144
  return {
86
145
  env,
87
146
  account: config.account,
@@ -95,9 +154,9 @@ function buildRuntimeConfig(config, baseDir, env, options) {
95
154
  localPath: hostRuntime.localPath,
96
155
  port: hostRuntime.port ?? DEFAULT_HOST_PORT,
97
156
  secrets: hostConfig.secrets,
98
- integrity: env === "production" ? hostConfig.integrity : void 0,
157
+ integrity: hostIsRemote ? hostConfig.integrity : void 0,
99
158
  source: hostRuntime.source,
100
- remoteUrl: hostRuntime.source === "remote" ? hostRuntime.url : void 0
159
+ remoteUrl: hostIsRemote ? hostRuntime.url : void 0
101
160
  },
102
161
  shared: config.shared,
103
162
  ui: {
@@ -106,9 +165,9 @@ function buildRuntimeConfig(config, baseDir, env, options) {
106
165
  entry: uiRuntime.url ? `${uiRuntime.url}/mf-manifest.json` : "/mf-manifest.json",
107
166
  localPath: uiRuntime.localPath,
108
167
  port: uiRuntime.port,
109
- ssrUrl: uiConfig.ssr,
110
- ssrIntegrity: env === "production" ? uiConfig.ssrIntegrity : void 0,
111
- integrity: env === "production" ? uiConfig.integrity : void 0,
168
+ ssrUrl: uiIsRemote ? uiConfig.ssr : void 0,
169
+ ssrIntegrity: uiIsRemote ? uiConfig.ssrIntegrity : void 0,
170
+ integrity: uiIsRemote ? uiConfig.integrity : void 0,
112
171
  source: uiRuntime.source
113
172
  },
114
173
  api: {
@@ -118,23 +177,31 @@ function buildRuntimeConfig(config, baseDir, env, options) {
118
177
  localPath: apiRuntime.localPath,
119
178
  port: apiRuntime.port,
120
179
  source: apiRuntime.source,
121
- proxy: apiConfig.proxy,
180
+ proxy: options?.proxy ?? apiConfig.proxy,
122
181
  variables: apiConfig.variables,
123
182
  secrets: apiConfig.secrets,
124
- integrity: env === "production" ? apiConfig.integrity : void 0
183
+ integrity: apiIsRemote ? apiConfig.integrity : void 0
125
184
  },
126
- auth: authConfig ? {
127
- name: resolvePluginRuntimeName(void 0, authRuntime.localPath, authConfig.name),
128
- url: authRuntime.url,
129
- entry: authRuntime.url ? `${authRuntime.url}/mf-manifest.json` : "/mf-manifest.json",
130
- localPath: authRuntime.localPath,
131
- port: authRuntime.port,
132
- source: authRuntime.source,
133
- proxy: authConfig.proxy,
134
- variables: authConfig.variables,
135
- secrets: authConfig.secrets,
136
- integrity: env === "production" ? authConfig.integrity : void 0
137
- } : void 0,
185
+ auth: (() => {
186
+ if (!authConfig || !authRuntime) return void 0;
187
+ return {
188
+ name: resolvePluginRuntimeName(void 0, authRuntime.localPath, authConfig.name),
189
+ url: authRuntime.url,
190
+ entry: authRuntime.url ? `${authRuntime.url}/mf-manifest.json` : "/mf-manifest.json",
191
+ localPath: authRuntime.localPath,
192
+ port: authRuntime.port,
193
+ source: authRuntime.source,
194
+ proxy: authConfig.proxy,
195
+ variables: authConfig.variables,
196
+ secrets: authConfig.secrets,
197
+ integrity: authRuntime.source === "remote" ? authConfig.integrity : void 0,
198
+ sidebar: authConfig.sidebar?.map((item) => ({
199
+ ...item,
200
+ to: item.to ?? "/auth",
201
+ roleRequired: item.roleRequired ?? "member"
202
+ }))
203
+ };
204
+ })(),
138
205
  plugins: options?.plugins && Object.keys(options.plugins).length > 0 ? options.plugins : void 0
139
206
  };
140
207
  }
@@ -143,42 +210,89 @@ async function loadConfigFile(configPath, baseDir) {
143
210
  const resolvedPath = (0, node_path.isAbsolute)(configPath) ? configPath : (0, node_path.resolve)(baseDir, configPath);
144
211
  return JSON.parse((0, node_fs.readFileSync)(resolvedPath, "utf-8"));
145
212
  }
146
- async function resolveConfigWithExtends(configPath, baseDir, visited, chain) {
213
+ async function resolveConfigWithExtends(configPath, baseDir, visited, chain, env = "development") {
147
214
  if (visited.has(configPath)) throw new Error(`Circular extends detected: ${[...visited, configPath].join(" -> ")}`);
148
215
  const config = await loadConfigFile(configPath, baseDir);
149
- if (configPath.startsWith("bos://")) chain.push(configPath);
216
+ chain.push(configPath);
150
217
  if (!config.extends) return config;
218
+ const extendsRef = require_merge.resolveExtendsRef(config.extends, env);
219
+ if (!extendsRef) return config;
151
220
  const nextVisited = new Set(visited);
152
221
  nextVisited.add(configPath);
153
- const parentPath = config.extends;
154
- return mergeConfigs(await resolveConfigWithExtends(parentPath, parentPath.startsWith("bos://") ? baseDir : (0, node_path.isAbsolute)(parentPath) ? (0, node_path.dirname)(parentPath) : baseDir, nextVisited, chain), config);
222
+ return require_merge.mergeBosConfigWithExtends(await resolveConfigWithExtends(extendsRef, extendsRef.startsWith("bos://") ? baseDir : (0, node_path.isAbsolute)(extendsRef) ? (0, node_path.dirname)(extendsRef) : baseDir, nextVisited, chain, env), config);
155
223
  }
156
- function mergeConfigs(parent, child) {
157
- const result = mergeValues(parent, child);
158
- if (child.plugins !== void 0) result.plugins = child.plugins;
159
- return result;
224
+ function normalizePluginEntry(raw) {
225
+ if (raw === null || raw === false) return raw;
226
+ if (typeof raw === "string") return { extends: raw };
227
+ return raw;
160
228
  }
161
- async function resolveRuntimePlugins(plugins, baseDir, env, prefix = []) {
229
+ async function resolveRuntimePlugins(plugins, baseDir, env) {
162
230
  const out = {};
163
- for (const [pluginId, pluginInput] of Object.entries(plugins)) {
164
- const runtimeKey = [...prefix, pluginId].join("/");
165
- const { config: resolvedConfig, baseDir: pluginBaseDir } = await resolveBosConfigInput(pluginInput, baseDir, /* @__PURE__ */ new Set(), []);
166
- const pluginRuntime = buildRuntimePluginConfig(runtimeKey, resolvedConfig, pluginBaseDir, env, pluginInput);
167
- if (pluginInput.name && typeof pluginInput.name === "string" && !pluginRuntime.name.includes("/")) pluginRuntime.name = pluginInput.name;
168
- const integrity = pluginInput.integrity;
169
- if (env === "production" && integrity) pluginRuntime.integrity = integrity;
170
- if (pluginRuntime.source === "remote" && pluginRuntime.url && !pluginRuntime.localPath && typeof resolvedConfig.app?.api?.name !== "string" && !pluginInput.name) pluginRuntime.name = await resolveRemotePluginRuntimeName(pluginRuntime.url, pluginRuntime.name);
171
- out[runtimeKey] = pluginRuntime;
172
- if (resolvedConfig.plugins && Object.keys(resolvedConfig.plugins).length > 0) {
173
- const nested = await resolveRuntimePlugins(resolvedConfig.plugins, pluginBaseDir, env, [...prefix, pluginId]);
174
- Object.assign(out, nested);
231
+ for (const [pluginId, rawInput] of Object.entries(plugins)) {
232
+ const normalized = normalizePluginEntry(rawInput);
233
+ if (normalized === null || normalized === false) continue;
234
+ let resolvedConfig = {};
235
+ let pluginBaseDir = baseDir;
236
+ if (normalized.extends) try {
237
+ const extendsUrl = require_merge.resolveExtendsRef(normalized.extends, env);
238
+ if (extendsUrl) resolvedConfig = await require_fastkv.fetchBosConfigFromFastKv(extendsUrl);
239
+ } catch {
240
+ resolvedConfig = {};
175
241
  }
242
+ if (normalized.development?.startsWith(LOCAL_PREFIX)) {
243
+ const localPath = (0, node_path.resolve)(baseDir, normalized.development.slice(6).trim());
244
+ if ((0, node_fs.existsSync)(localPath)) {
245
+ const localConfigPath = (0, node_path.join)(localPath, "bos.config.json");
246
+ if ((0, node_fs.existsSync)(localConfigPath)) try {
247
+ const localRaw = JSON.parse((0, node_fs.readFileSync)(localConfigPath, "utf-8"));
248
+ resolvedConfig = require_merge.mergeBosConfigWithExtends(resolvedConfig, localRaw);
249
+ pluginBaseDir = localPath;
250
+ } catch {}
251
+ }
252
+ }
253
+ if (normalized.app && require_merge.isPlainObject(normalized.app)) {
254
+ const mergedApp = {
255
+ ...resolvedConfig.app ?? {},
256
+ ...normalized.app
257
+ };
258
+ resolvedConfig = {
259
+ ...resolvedConfig,
260
+ app: mergedApp
261
+ };
262
+ }
263
+ if (normalized.shared && require_merge.isPlainObject(normalized.shared)) {
264
+ const mergedShared = {
265
+ ...resolvedConfig.shared ?? {},
266
+ ...normalized.shared
267
+ };
268
+ resolvedConfig = {
269
+ ...resolvedConfig,
270
+ shared: mergedShared
271
+ };
272
+ }
273
+ if (normalized.sidebar) resolvedConfig = {
274
+ ...resolvedConfig,
275
+ sidebar: normalized.sidebar
276
+ };
277
+ if (normalized.routes) resolvedConfig = {
278
+ ...resolvedConfig,
279
+ routes: normalized.routes
280
+ };
281
+ const pluginRuntime = await buildRuntimePluginConfig(pluginId, resolvedConfig, pluginBaseDir, env, normalized);
282
+ if (normalized.name && typeof normalized.name === "string" && !pluginRuntime.name.includes("/")) pluginRuntime.name = normalized.name;
283
+ const integrity = normalized.integrity;
284
+ if (env === "production" && integrity) pluginRuntime.integrity = integrity;
285
+ if (pluginRuntime.source === "remote" && pluginRuntime.url && !pluginRuntime.localPath && typeof resolvedConfig.app?.api?.name !== "string" && !normalized.name) pluginRuntime.name = await resolveRemotePluginRuntimeName(pluginRuntime.url, pluginRuntime.name);
286
+ out[pluginId] = pluginRuntime;
176
287
  }
177
288
  return out;
178
289
  }
179
290
  async function resolveRemotePluginRuntimeName(baseUrl, fallback) {
180
291
  try {
181
- const response = await fetch(`${baseUrl.replace(/\/$/, "")}/plugin.manifest.json`);
292
+ const controller = new AbortController();
293
+ const timeout = setTimeout(() => controller.abort(), 5e3);
294
+ const response = await fetch(`${baseUrl.replace(/\/$/, "")}/plugin.manifest.json`, { signal: controller.signal });
295
+ clearTimeout(timeout);
182
296
  if (!response.ok) return fallback;
183
297
  const manifest = await response.json();
184
298
  return typeof manifest.plugin?.name === "string" && manifest.plugin.name.length > 0 ? manifest.plugin.name : fallback;
@@ -186,7 +300,23 @@ async function resolveRemotePluginRuntimeName(baseUrl, fallback) {
186
300
  return fallback;
187
301
  }
188
302
  }
189
- function buildRuntimePluginConfig(pluginId, config, baseDir, env, source) {
303
+ async function resolveBosPluginUrl(bosUrl) {
304
+ const parsed = require_fastkv.parsePluginBosUrl(bosUrl);
305
+ if (!parsed) return null;
306
+ try {
307
+ const entry = await require_fastkv.fetchPluginFromRegistry(parsed.accountId, parsed.pluginName);
308
+ if (!entry) return null;
309
+ const cdnUrl = entry.metadata.cdnUrl;
310
+ if (!cdnUrl) return null;
311
+ return {
312
+ url: cdnUrl,
313
+ integrity: entry.metadata.integrity ?? void 0
314
+ };
315
+ } catch {
316
+ return null;
317
+ }
318
+ }
319
+ async function buildRuntimePluginConfig(pluginId, config, baseDir, env, source) {
190
320
  const apiConfig = config.app?.api ?? {};
191
321
  const apiDevelopment = typeof apiConfig.development === "string" ? apiConfig.development : void 0;
192
322
  const apiProduction = typeof apiConfig.production === "string" ? apiConfig.production : void 0;
@@ -194,10 +324,28 @@ function buildRuntimePluginConfig(pluginId, config, baseDir, env, source) {
194
324
  const sourceProduction = typeof source.production === "string" ? source.production : void 0;
195
325
  const proxy = typeof apiConfig.proxy === "string" ? apiConfig.proxy : void 0;
196
326
  const development = apiDevelopment ?? sourceDevelopment;
197
- const production = apiProduction ?? sourceProduction;
327
+ let production = apiProduction ?? sourceProduction;
328
+ if (production?.startsWith("bos://")) {
329
+ const resolved = await resolveBosPluginUrl(production);
330
+ if (resolved) {
331
+ production = resolved.url;
332
+ if (resolved.integrity && env === "production") source.integrity = resolved.integrity;
333
+ }
334
+ }
198
335
  const runtimeTarget = env === "development" ? resolveDevelopmentTarget(development, production, baseDir) : resolveRuntimeTarget(production, baseDir, "remote");
336
+ const apiName = resolvePluginRuntimeName(typeof apiConfig.name === "string" ? apiConfig.name : void 0, runtimeTarget.localPath, pluginId);
337
+ const uiConfig = config.app?.ui;
338
+ const uiDevelopment = typeof uiConfig?.development === "string" ? uiConfig.development : void 0;
339
+ const uiProduction = typeof uiConfig?.production === "string" ? uiConfig.production : void 0;
340
+ const uiRuntime = uiConfig && (uiDevelopment || uiProduction) ? env === "development" ? resolveDevelopmentTarget(uiDevelopment, uiProduction, baseDir) : resolveRuntimeTarget(uiProduction, baseDir, "remote") : void 0;
341
+ const sidebar = (config.sidebar ?? source.sidebar)?.map((item) => ({
342
+ ...item,
343
+ to: item.to ?? `/${pluginId}`,
344
+ roleRequired: item.roleRequired ?? "member"
345
+ }));
346
+ const routes = config.routes ?? source.routes;
199
347
  return {
200
- name: resolvePluginRuntimeName(typeof apiConfig.name === "string" ? apiConfig.name : void 0, runtimeTarget.localPath, pluginId),
348
+ name: apiName,
201
349
  url: runtimeTarget.url,
202
350
  entry: runtimeTarget.url ? `${runtimeTarget.url.replace(/\/$/, "")}/mf-manifest.json` : "/mf-manifest.json",
203
351
  source: runtimeTarget.source,
@@ -205,7 +353,18 @@ function buildRuntimePluginConfig(pluginId, config, baseDir, env, source) {
205
353
  port: runtimeTarget.port,
206
354
  proxy: proxy ?? (typeof source.proxy === "string" ? source.proxy : void 0),
207
355
  variables: normalizeStringRecord(apiConfig.variables ?? source.variables),
208
- secrets: normalizeStringArray(apiConfig.secrets ?? source.secrets)
356
+ secrets: normalizeStringArray(apiConfig.secrets ?? source.secrets),
357
+ ui: uiRuntime ? {
358
+ name: typeof uiConfig?.name === "string" ? uiConfig.name : `${apiName}-ui`,
359
+ url: uiRuntime.url,
360
+ entry: uiRuntime.url ? `${uiRuntime.url.replace(/\/$/, "")}/mf-manifest.json` : "/mf-manifest.json",
361
+ source: uiRuntime.source,
362
+ localPath: uiRuntime.localPath,
363
+ port: uiRuntime.port,
364
+ integrity: uiRuntime.source === "remote" && typeof uiConfig?.integrity === "string" ? uiConfig.integrity : void 0
365
+ } : void 0,
366
+ sidebar,
367
+ routes
209
368
  };
210
369
  }
211
370
  function resolvePluginRuntimeName(explicitName, localPath, fallback) {
@@ -218,33 +377,8 @@ function resolvePluginRuntimeName(explicitName, localPath, fallback) {
218
377
  } catch {}
219
378
  return fallback;
220
379
  }
221
- async function resolveBosConfigInput(input, baseDir, visited, chain) {
222
- if (input.extends) {
223
- const parentBaseDir = input.extends.startsWith("bos://") ? baseDir : (0, node_path.isAbsolute)(input.extends) ? (0, node_path.dirname)(input.extends) : baseDir;
224
- return {
225
- config: mergeConfigs(await resolveConfigWithExtends(input.extends, parentBaseDir, visited, chain), input),
226
- baseDir: parentBaseDir
227
- };
228
- }
229
- return {
230
- config: input,
231
- baseDir
232
- };
233
- }
234
- function mergeValues(parent, child) {
235
- if (Array.isArray(parent) && Array.isArray(child)) return child;
236
- if (isPlainObject(parent) && isPlainObject(child)) {
237
- const merged = { ...parent };
238
- for (const [key, value] of Object.entries(child)) merged[key] = key in merged ? mergeValues(merged[key], value) : value;
239
- return merged;
240
- }
241
- return child ?? parent;
242
- }
243
- function isPlainObject(value) {
244
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
245
- }
246
380
  function normalizeStringRecord(value) {
247
- if (!isPlainObject(value)) return void 0;
381
+ if (!require_merge.isPlainObject(value)) return void 0;
248
382
  const out = {};
249
383
  for (const [key, raw] of Object.entries(value)) if (typeof raw === "string") out[key] = raw;
250
384
  return Object.keys(out).length > 0 ? out : void 0;
@@ -260,7 +394,7 @@ function resolveRuntimeTarget(value, baseDir, defaultSource = "remote") {
260
394
  url: ""
261
395
  };
262
396
  if (value.startsWith(LOCAL_PREFIX)) {
263
- const localTarget = value.slice(6).trim();
397
+ const localTarget = value?.slice(6).trim();
264
398
  if (!localTarget) throw new Error(`Invalid local development target: ${value}`);
265
399
  const localPath = (0, node_path.resolve)(baseDir, localTarget);
266
400
  if (!(0, node_fs.existsSync)(localPath)) return {
@@ -304,18 +438,26 @@ function parsePort(url) {
304
438
  }
305
439
 
306
440
  //#endregion
441
+ exports.BOS_CONFIG_ORDER = require_merge.BOS_CONFIG_ORDER;
307
442
  exports.BosConfigSchema = require_types.BosConfigSchema;
443
+ exports.buildRuntimeConfig = buildRuntimeConfig;
308
444
  exports.buildRuntimePluginsForConfig = buildRuntimePluginsForConfig;
309
445
  exports.clearConfigCache = clearConfigCache;
310
446
  exports.findConfigPath = findConfigPath;
311
447
  exports.getConfig = getConfig;
312
448
  exports.getHostDevelopmentPort = getHostDevelopmentPort;
313
449
  exports.getProjectRoot = getProjectRoot;
450
+ exports.getResolvedConfigPath = getResolvedConfigPath;
314
451
  exports.isLocalDevelopmentTarget = isLocalDevelopmentTarget;
315
452
  exports.loadBosConfig = loadBosConfig;
316
453
  exports.loadConfig = loadConfig;
454
+ exports.loadResolvedConfig = loadResolvedConfig;
317
455
  exports.parsePort = parsePort;
456
+ exports.readBosConfigForBuild = readBosConfigForBuild;
457
+ exports.rebuildOrderedConfig = require_merge.rebuildOrderedConfig;
458
+ exports.resolveBosConfigPath = resolveBosConfigPath;
318
459
  exports.resolveDevelopmentHostUrl = resolveDevelopmentHostUrl;
319
460
  exports.resolveLocalDevelopmentPath = resolveLocalDevelopmentPath;
320
461
  exports.resolvePluginRuntimeName = resolvePluginRuntimeName;
462
+ exports.writeResolvedConfig = writeResolvedConfig;
321
463
  //# sourceMappingURL=config.cjs.map