everything-dev 1.51.6 → 1.52.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.
- package/dist/_virtual/_rolldown/runtime.cjs +0 -2
- package/dist/api-contract.cjs +61 -16
- package/dist/api-contract.cjs.map +1 -1
- package/dist/api-contract.mjs +60 -17
- package/dist/api-contract.mjs.map +1 -1
- package/dist/app.cjs +1 -1
- package/dist/app.cjs.map +1 -1
- package/dist/app.mjs +1 -1
- package/dist/app.mjs.map +1 -1
- package/dist/cli/db-doctor.cjs +1 -1
- package/dist/cli/db-doctor.cjs.map +1 -1
- package/dist/cli/db-doctor.mjs +1 -1
- package/dist/cli/db-repair.cjs +1 -1
- package/dist/cli/db-repair.cjs.map +1 -1
- package/dist/cli/db-repair.mjs +1 -1
- package/dist/cli/init.cjs +76 -52
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +15 -7
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +15 -7
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +70 -47
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/sync.cjs +34 -5
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +35 -6
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +151 -93
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +138 -80
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/cli/utils/helpers.cjs +25 -0
- package/dist/cli/utils/helpers.cjs.map +1 -0
- package/dist/cli/utils/helpers.mjs +23 -0
- package/dist/cli/utils/helpers.mjs.map +1 -0
- package/dist/cli.cjs +84 -72
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +84 -72
- package/dist/cli.mjs.map +1 -1
- package/dist/code-artifacts.cjs +1 -1
- package/dist/code-artifacts.mjs +1 -1
- package/dist/config.cjs +44 -4
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +1 -1
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +44 -4
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +9 -4
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +23 -13
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +23 -13
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.meta.cjs +2 -1
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +3 -0
- package/dist/contract.meta.d.mts +3 -0
- package/dist/contract.meta.mjs +2 -1
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +9 -4
- package/dist/contract.mjs.map +1 -1
- package/dist/dag.cjs +176 -0
- package/dist/dag.cjs.map +1 -0
- package/dist/dag.d.cts +24 -0
- package/dist/dag.d.cts.map +1 -0
- package/dist/dag.d.mts +24 -0
- package/dist/dag.d.mts.map +1 -0
- package/dist/dag.mjs +167 -0
- package/dist/dag.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/infra/planner.cjs +1 -1
- package/dist/infra/planner.mjs +1 -1
- package/dist/infra/preflight.cjs +1 -1
- package/dist/infra/preflight.cjs.map +1 -1
- package/dist/infra/preflight.mjs +1 -1
- package/dist/infra/preflight.mjs.map +1 -1
- package/dist/near-cli.cjs +1 -1
- package/dist/near-cli.mjs +1 -1
- package/dist/plugin.cjs +27 -18
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +52 -6
- package/dist/plugin.d.mts +52 -6
- package/dist/plugin.mjs +28 -19
- package/dist/plugin.mjs.map +1 -1
- package/dist/types.cjs +41 -6
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +116 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +116 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +40 -7
- package/dist/types.mjs.map +1 -1
- package/package.json +8 -2
- package/dist/_virtual/_rolldown/runtime.mjs +0 -32
package/dist/cli/sync.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { isPlainObject, mergeBosConfigWithTemplate, resolveExtendsRef } from "..
|
|
|
2
2
|
import { loadResolvedConfig } from "../config.mjs";
|
|
3
3
|
import { syncResolvedSharedDeps } from "../shared-deps.mjs";
|
|
4
4
|
import { writeGeneratedInfra } from "./infra.mjs";
|
|
5
|
-
import { writeSnapshot } from "./snapshot.mjs";
|
|
5
|
+
import { readSnapshot, writeSnapshot } from "./snapshot.mjs";
|
|
6
6
|
import { buildChildAgentsMd, extractSkillsBlock, personalizeConfig, resolveSourceDir, runBunInstall, runTypesGen } from "./init.mjs";
|
|
7
7
|
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
@@ -228,6 +228,7 @@ async function syncTemplate(projectDir, options) {
|
|
|
228
228
|
updated: [],
|
|
229
229
|
skipped: [],
|
|
230
230
|
added: [],
|
|
231
|
+
conflicted: [],
|
|
231
232
|
error: "No extends field found in bos.config.json — cannot determine parent"
|
|
232
233
|
};
|
|
233
234
|
const extendsMatch = extendsRef.match(/^bos:\/\/([^/]+)\/(.+)$/);
|
|
@@ -236,6 +237,7 @@ async function syncTemplate(projectDir, options) {
|
|
|
236
237
|
updated: [],
|
|
237
238
|
skipped: [],
|
|
238
239
|
added: [],
|
|
240
|
+
conflicted: [],
|
|
239
241
|
error: `Invalid extends reference: ${extendsRef}`
|
|
240
242
|
};
|
|
241
243
|
const extendsAccount = extendsMatch[1];
|
|
@@ -314,6 +316,8 @@ async function syncTemplate(projectDir, options) {
|
|
|
314
316
|
const updated = [];
|
|
315
317
|
const skipped = [];
|
|
316
318
|
const added = [];
|
|
319
|
+
const conflicted = [];
|
|
320
|
+
const snapshotFiles = (await readSnapshot(projectDir))?.files ?? {};
|
|
317
321
|
for (const [destPath, filePath] of destToSource.entries()) {
|
|
318
322
|
const localHash = computeLocalHash(projectDir, destPath);
|
|
319
323
|
const sourceHash = computeHash(buildSyncedFileContent(sourceDir, projectDir, filePath));
|
|
@@ -321,7 +325,24 @@ async function syncTemplate(projectDir, options) {
|
|
|
321
325
|
added.push(destPath);
|
|
322
326
|
continue;
|
|
323
327
|
}
|
|
324
|
-
if (localHash
|
|
328
|
+
if (localHash === sourceHash) {
|
|
329
|
+
skipped.push(destPath);
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
const snapshotHash = snapshotFiles[destPath];
|
|
333
|
+
if (!snapshotHash) {
|
|
334
|
+
updated.push(destPath);
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (localHash === snapshotHash) {
|
|
338
|
+
updated.push(destPath);
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (sourceHash === snapshotHash) {
|
|
342
|
+
skipped.push(destPath);
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
conflicted.push(destPath);
|
|
325
346
|
}
|
|
326
347
|
const account = localConfig.account || extendsAccount;
|
|
327
348
|
const domain = localConfig.domain || extendsGateway;
|
|
@@ -346,12 +367,18 @@ async function syncTemplate(projectDir, options) {
|
|
|
346
367
|
status: "dry-run",
|
|
347
368
|
updated,
|
|
348
369
|
skipped,
|
|
349
|
-
added
|
|
370
|
+
added,
|
|
371
|
+
conflicted
|
|
350
372
|
};
|
|
351
373
|
}
|
|
352
|
-
const filesToWrite = [
|
|
374
|
+
const filesToWrite = [
|
|
375
|
+
...updated,
|
|
376
|
+
...added,
|
|
377
|
+
...conflicted
|
|
378
|
+
];
|
|
379
|
+
let backupDir;
|
|
353
380
|
if (filesToWrite.length > 0) {
|
|
354
|
-
backupFiles(projectDir, filesToWrite);
|
|
381
|
+
backupDir = backupFiles(projectDir, filesToWrite) ?? void 0;
|
|
355
382
|
for (const destPath of filesToWrite) writeSyncedFile(sourceDir, projectDir, destToSource.get(destPath) ?? destPath, destPath);
|
|
356
383
|
}
|
|
357
384
|
await personalizeConfig(projectDir, {
|
|
@@ -404,7 +431,9 @@ async function syncTemplate(projectDir, options) {
|
|
|
404
431
|
status: "synced",
|
|
405
432
|
updated,
|
|
406
433
|
skipped,
|
|
407
|
-
added
|
|
434
|
+
added,
|
|
435
|
+
conflicted,
|
|
436
|
+
backupDir
|
|
408
437
|
};
|
|
409
438
|
} finally {
|
|
410
439
|
await cleanup();
|
package/dist/cli/sync.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 { glob } from \"glob\";\nimport { loadResolvedConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { syncResolvedSharedDeps } from \"../shared-deps\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n buildChildAgentsMd,\n extractSkillsBlock,\n personalizeConfig,\n resolveSourceDir,\n runBunInstall,\n runTypesGen,\n} from \"./init\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst FRAMEWORK_OWNED_SYNC_FILES = new Set([\n \".env.example\",\n \".gitignore\",\n \"biome.json\",\n \"bos.config.json\",\n \"bunfig.toml\",\n \"package.json\",\n \".changeset/config.json\",\n \".changeset/README.md\",\n \".github/workflows/ci.yml\",\n \".github/workflows/deploy.yml\",\n \".github/workflows/staging.yml\",\n \".github/workflows/release.yml\",\n \"railway.toml\",\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 \"api/src/lib/context.ts\",\n \"api/drizzle.config.ts\",\n \"api/src/db/index.ts\",\n \"api/src/db/layer.ts\",\n \"api/src/db/migrate.ts\",\n \"api/src/global.d.ts\",\n \"api/tests/types.d.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nfunction computeHash(content: string | Uint8Array): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n}\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n if (FRAMEWORK_OWNED_SYNC_FILES.has(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/lib\\/(auth|context)\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/db\\/(index|layer|migrate)\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/rspack\\.config\\.js$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/drizzle\\.config\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/global\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tests\\/types\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.json$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.contract\\.json$/.test(filePath)) return true;\n return false;\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 computeHash(content);\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 toSourcePath(sourceDir: string, destPath: string): string | null {\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 const directPath = join(sourceDir, destPath);\n if (existsSync(directPath)) {\n return destPath;\n }\n\n return null;\n}\n\nfunction buildSyncedFileContent(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n): string | Uint8Array {\n const src = join(sourceDir, filePath);\n const destPath =\n explicitDestPath ??\n (filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath);\n const dest = join(projectDir, destPath);\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 return `${JSON.stringify(merged, null, 2)}\\n`;\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 return `${JSON.stringify(merged, null, 2)}\\n`;\n }\n }\n\n return readFileSync(src);\n}\n\nfunction writeSyncedFile(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n): void {\n const destPath =\n explicitDestPath ??\n (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 writeFileSync(dest, buildSyncedFileContent(sourceDir, projectDir, filePath, destPath));\n}\n\nasync function getSelectedChildPlugins(\n projectDir: string,\n localConfig: Record<string, unknown>,\n): Promise<string[]> {\n if (!localConfig.plugins || typeof localConfig.plugins !== \"object\") {\n return [];\n }\n\n const pluginDirs = new Set(\n (\n await glob(\"plugins/*/package.json\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n })\n )\n .map((file) => file.match(/^plugins\\/([^/]+)\\/package\\.json$/)?.[1])\n .filter((key): key is string => Boolean(key)),\n );\n\n const selected: string[] = [];\n for (const [pluginKey, rawEntry] of Object.entries(\n localConfig.plugins as Record<string, unknown>,\n )) {\n if (typeof rawEntry === \"string\") {\n if (!rawEntry.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, rawEntry.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n continue;\n }\n\n if (!rawEntry || typeof rawEntry !== \"object\") {\n selected.push(pluginKey);\n continue;\n }\n\n const entry = rawEntry as Record<string, unknown>;\n const development = typeof entry.development === \"string\" ? entry.development : undefined;\n if (!development?.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, development.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n }\n\n return selected;\n}\n\nfunction hasPluginsWorkspace(projectDir: string): boolean {\n const packageJsonPath = join(projectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) return false;\n\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as {\n workspaces?: { packages?: string[] } | string[];\n };\n const workspaces = pkg.workspaces;\n const packages = Array.isArray(workspaces)\n ? workspaces\n : Array.isArray(workspaces?.packages)\n ? workspaces.packages\n : [];\n return packages.includes(\"plugins/*\");\n } catch {\n return false;\n }\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 = await getSelectedChildPlugins(projectDir, localConfig);\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 const withPlugins = childPlugins.length > 0 || hasPluginsWorkspace(projectDir);\n\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 destToSource.set(destPath, sourcePath);\n }\n\n // Sync api/src/lib/{auth,context}.ts into each plugin's src/lib/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n for (const libFile of [\"auth.ts\", \"context.ts\"]) {\n const sourceFile = `api/src/lib/${libFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/lib/${libFile}`, sourceFile);\n }\n }\n\n // Sync api/src/global.d.ts into each plugin's src/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n const sourceFile = \"api/src/global.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/global.d.ts`, sourceFile);\n }\n\n // Sync tests/types.d.ts into each plugin's tests/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/tests/types.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/tests/types.d.ts`, sourceFile);\n }\n\n // Sync api/src/db/{index,layer,migrate}.ts into each plugin's src/db/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n for (const dbFile of [\"index.ts\", \"layer.ts\", \"migrate.ts\"]) {\n const sourceFile = `api/src/db/${dbFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/db/${dbFile}`, sourceFile);\n }\n }\n\n // Sync rspack.config.js from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/rspack.config.js\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/rspack.config.js`, sourceFile);\n }\n\n // Sync drizzle.config.ts from api into each DB-enabled plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n const sourceFile = \"api/drizzle.config.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/drizzle.config.ts`, sourceFile);\n }\n\n // Sync tsconfig files from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n for (const tsconfigFile of [\"tsconfig.json\", \"tsconfig.contract.json\"]) {\n const sourceFile = `plugins/_template/${tsconfigFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/${tsconfigFile}`, sourceFile);\n }\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 sourceHash = computeHash(buildSyncedFileContent(sourceDir, projectDir, filePath));\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 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 (withPlugins) overrides.push(\"plugins\");\n\n if (options.dryRun) {\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n updated.push(\"AGENTS.md\");\n }\n }\n }\n\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, destPath);\n }\n }\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 existingConfig: localConfig,\n });\n\n await syncResolvedSharedDeps({\n configDir: projectDir,\n hostMode: \"local\",\n });\n\n const syncedConfig = await loadResolvedConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(projectDir, syncedConfig.runtime);\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const destPath of destToSource.keys()) {\n const hash = computeLocalHash(projectDir, destPath);\n if (hash) {\n newSnapshotFiles[destPath] = hash;\n }\n }\n\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n writeFileSync(join(projectDir, \"AGENTS.md\"), expectedContent);\n updated.push(\"AGENTS.md\");\n }\n\n newSnapshotFiles[\"AGENTS.md\"] = expectedHash;\n }\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\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 { glob } from \"glob\";\nimport { loadResolvedConfig } from \"../config\";\nimport type { SyncOptions, SyncResult } from \"../contract\";\nimport {\n isPlainObject as isPlainObjectFromMerge,\n mergeBosConfigWithTemplate,\n resolveExtendsRef,\n} from \"../merge\";\nimport { syncResolvedSharedDeps } from \"../shared-deps\";\nimport { writeGeneratedInfra } from \"./infra\";\nimport {\n buildChildAgentsMd,\n extractSkillsBlock,\n personalizeConfig,\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 \"bunfig.toml\",\n \"package.json\",\n \".changeset/config.json\",\n \".changeset/README.md\",\n \".github/workflows/ci.yml\",\n \".github/workflows/deploy.yml\",\n \".github/workflows/staging.yml\",\n \".github/workflows/release.yml\",\n \"railway.toml\",\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 \"api/src/lib/context.ts\",\n \"api/drizzle.config.ts\",\n \"api/src/db/index.ts\",\n \"api/src/db/layer.ts\",\n \"api/src/db/migrate.ts\",\n \"api/src/global.d.ts\",\n \"api/tests/types.d.ts\",\n]);\n\ntype PackageJson = Record<string, unknown>;\n\nfunction computeHash(content: string | Uint8Array): string {\n return createHash(\"sha256\").update(content).digest(\"hex\").substring(0, 16);\n}\n\nexport function isFrameworkOwnedSyncFile(filePath: string): boolean {\n if (FRAMEWORK_OWNED_SYNC_FILES.has(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/lib\\/(auth|context)\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/db\\/(index|layer|migrate)\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/rspack\\.config\\.js$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/drizzle\\.config\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/src\\/global\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tests\\/types\\.d\\.ts$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.json$/.test(filePath)) return true;\n if (/^plugins\\/[^/]+\\/tsconfig\\.contract\\.json$/.test(filePath)) return true;\n return false;\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 computeHash(content);\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 toSourcePath(sourceDir: string, destPath: string): string | null {\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 const directPath = join(sourceDir, destPath);\n if (existsSync(directPath)) {\n return destPath;\n }\n\n return null;\n}\n\nfunction buildSyncedFileContent(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n): string | Uint8Array {\n const src = join(sourceDir, filePath);\n const destPath =\n explicitDestPath ??\n (filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath);\n const dest = join(projectDir, destPath);\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 return `${JSON.stringify(merged, null, 2)}\\n`;\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 return `${JSON.stringify(merged, null, 2)}\\n`;\n }\n }\n\n return readFileSync(src);\n}\n\nfunction writeSyncedFile(\n sourceDir: string,\n projectDir: string,\n filePath: string,\n explicitDestPath?: string,\n): void {\n const destPath =\n explicitDestPath ??\n (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 writeFileSync(dest, buildSyncedFileContent(sourceDir, projectDir, filePath, destPath));\n}\n\nasync function getSelectedChildPlugins(\n projectDir: string,\n localConfig: Record<string, unknown>,\n): Promise<string[]> {\n if (!localConfig.plugins || typeof localConfig.plugins !== \"object\") {\n return [];\n }\n\n const pluginDirs = new Set(\n (\n await glob(\"plugins/*/package.json\", {\n cwd: projectDir,\n nodir: true,\n dot: false,\n absolute: false,\n })\n )\n .map((file) => file.match(/^plugins\\/([^/]+)\\/package\\.json$/)?.[1])\n .filter((key): key is string => Boolean(key)),\n );\n\n const selected: string[] = [];\n for (const [pluginKey, rawEntry] of Object.entries(\n localConfig.plugins as Record<string, unknown>,\n )) {\n if (typeof rawEntry === \"string\") {\n if (!rawEntry.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, rawEntry.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n continue;\n }\n\n if (!rawEntry || typeof rawEntry !== \"object\") {\n selected.push(pluginKey);\n continue;\n }\n\n const entry = rawEntry as Record<string, unknown>;\n const development = typeof entry.development === \"string\" ? entry.development : undefined;\n if (!development?.startsWith(\"local:\")) {\n selected.push(pluginKey);\n continue;\n }\n\n const localPath = join(projectDir, development.slice(\"local:\".length).trim());\n if (existsSync(localPath) || pluginDirs.has(pluginKey)) {\n selected.push(pluginKey);\n }\n }\n\n return selected;\n}\n\nfunction hasPluginsWorkspace(projectDir: string): boolean {\n const packageJsonPath = join(projectDir, \"package.json\");\n if (!existsSync(packageJsonPath)) return false;\n\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as {\n workspaces?: { packages?: string[] } | string[];\n };\n const workspaces = pkg.workspaces;\n const packages = Array.isArray(workspaces)\n ? workspaces\n : Array.isArray(workspaces?.packages)\n ? workspaces.packages\n : [];\n return packages.includes(\"plugins/*\");\n } catch {\n return false;\n }\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 conflicted: [],\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 conflicted: [],\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 = await getSelectedChildPlugins(projectDir, localConfig);\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 const withPlugins = childPlugins.length > 0 || hasPluginsWorkspace(projectDir);\n\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 destToSource.set(destPath, sourcePath);\n }\n\n // Sync api/src/lib/{auth,context}.ts into each plugin's src/lib/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n for (const libFile of [\"auth.ts\", \"context.ts\"]) {\n const sourceFile = `api/src/lib/${libFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/lib/${libFile}`, sourceFile);\n }\n }\n\n // Sync api/src/global.d.ts into each plugin's src/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\"))) continue;\n const sourceFile = \"api/src/global.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/global.d.ts`, sourceFile);\n }\n\n // Sync tests/types.d.ts into each plugin's tests/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/tests/types.d.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/tests/types.d.ts`, sourceFile);\n }\n\n // Sync api/src/db/{index,layer,migrate}.ts into each plugin's src/db/\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n for (const dbFile of [\"index.ts\", \"layer.ts\", \"migrate.ts\"]) {\n const sourceFile = `api/src/db/${dbFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/src/db/${dbFile}`, sourceFile);\n }\n }\n\n // Sync rspack.config.js from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n const sourceFile = \"plugins/_template/rspack.config.js\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/rspack.config.js`, sourceFile);\n }\n\n // Sync drizzle.config.ts from api into each DB-enabled plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey, \"src\", \"db\"))) continue;\n const sourceFile = \"api/drizzle.config.ts\";\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/drizzle.config.ts`, sourceFile);\n }\n\n // Sync tsconfig files from the template into each plugin\n for (const pluginKey of childPlugins) {\n if (!existsSync(join(projectDir, \"plugins\", pluginKey))) continue;\n for (const tsconfigFile of [\"tsconfig.json\", \"tsconfig.contract.json\"]) {\n const sourceFile = `plugins/_template/${tsconfigFile}`;\n if (!existsSync(join(sourceDir, sourceFile))) continue;\n destToSource.set(`plugins/${pluginKey}/${tsconfigFile}`, sourceFile);\n }\n }\n\n const updated: string[] = [];\n const skipped: string[] = [];\n const added: string[] = [];\n const conflicted: string[] = [];\n\n const snapshot = await readSnapshot(projectDir);\n const snapshotFiles = snapshot?.files ?? {};\n\n for (const [destPath, filePath] of destToSource.entries()) {\n const localHash = computeLocalHash(projectDir, destPath);\n const sourceHash = computeHash(buildSyncedFileContent(sourceDir, projectDir, filePath));\n\n if (localHash === null) {\n added.push(destPath);\n continue;\n }\n\n if (localHash === sourceHash) {\n skipped.push(destPath);\n continue;\n }\n\n const snapshotHash = snapshotFiles[destPath];\n if (!snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (localHash === snapshotHash) {\n updated.push(destPath);\n continue;\n }\n\n if (sourceHash === snapshotHash) {\n skipped.push(destPath);\n continue;\n }\n\n conflicted.push(destPath);\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 (withPlugins) overrides.push(\"plugins\");\n\n if (options.dryRun) {\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n updated.push(\"AGENTS.md\");\n }\n }\n }\n\n return {\n status: \"dry-run\",\n updated,\n skipped,\n added,\n conflicted,\n };\n }\n\n const filesToWrite = [...updated, ...added, ...conflicted];\n\n let backupDir: string | undefined;\n if (filesToWrite.length > 0) {\n backupDir = backupFiles(projectDir, filesToWrite) ?? undefined;\n\n for (const destPath of filesToWrite) {\n const sourcePath = destToSource.get(destPath) ?? destPath;\n writeSyncedFile(sourceDir, projectDir, sourcePath, destPath);\n }\n }\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 existingConfig: localConfig,\n });\n\n await syncResolvedSharedDeps({\n configDir: projectDir,\n hostMode: \"local\",\n });\n\n const syncedConfig = await loadResolvedConfig({ cwd: projectDir });\n if (syncedConfig?.runtime) {\n writeGeneratedInfra(projectDir, syncedConfig.runtime);\n }\n\n const newSnapshotFiles: Record<string, string> = {};\n for (const destPath of destToSource.keys()) {\n const hash = computeLocalHash(projectDir, destPath);\n if (hash) {\n newSnapshotFiles[destPath] = hash;\n }\n }\n\n const agentsMdSourcePath = toSourcePath(sourceDir, \"AGENTS.md\");\n if (agentsMdSourcePath) {\n const agentsMdSourceContent = readFileSync(join(sourceDir, agentsMdSourcePath), \"utf-8\");\n const skillsBlock = extractSkillsBlock(agentsMdSourceContent);\n if (skillsBlock) {\n const expectedContent = buildChildAgentsMd(skillsBlock, {\n overrides,\n plugins: childPlugins,\n });\n const expectedHash = computeHash(expectedContent);\n\n const agentsMdLocalHash = computeLocalHash(projectDir, \"AGENTS.md\");\n if (agentsMdLocalHash !== expectedHash) {\n writeFileSync(join(projectDir, \"AGENTS.md\"), expectedContent);\n updated.push(\"AGENTS.md\");\n }\n\n newSnapshotFiles[\"AGENTS.md\"] = expectedHash;\n }\n }\n\n await writeSnapshot(projectDir, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: newSnapshotFiles,\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 conflicted,\n backupDir,\n };\n } finally {\n await cleanup();\n }\n}\n"],"mappings":"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"}
|
package/dist/cli/upgrade.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
|
-
const require_merge = require('../merge.cjs');
|
|
3
2
|
const require_config = require('../config.cjs');
|
|
4
3
|
const require_timing = require('./timing.cjs');
|
|
5
4
|
const require_shared_deps = require('../shared-deps.cjs');
|
|
6
5
|
const require_save_config = require('../utils/save-config.cjs');
|
|
6
|
+
const require_helpers = require('./utils/helpers.cjs');
|
|
7
7
|
const require_cli_init = require('./init.cjs');
|
|
8
8
|
const require_framework_version = require('./framework-version.cjs');
|
|
9
9
|
const require_sync = require('./sync.cjs');
|
|
@@ -14,6 +14,7 @@ node_process = require_runtime.__toESM(node_process, 1);
|
|
|
14
14
|
let _clack_prompts = require("@clack/prompts");
|
|
15
15
|
_clack_prompts = require_runtime.__toESM(_clack_prompts, 1);
|
|
16
16
|
let glob = require("glob");
|
|
17
|
+
let node_child_process = require("node:child_process");
|
|
17
18
|
|
|
18
19
|
//#region src/cli/upgrade.ts
|
|
19
20
|
const FRAMEWORK_PACKAGES = ["everything-dev", "every-plugin"];
|
|
@@ -48,7 +49,6 @@ const OBSOLETE_FILES = [
|
|
|
48
49
|
"ui/scripts/generate-metadata.ts",
|
|
49
50
|
".github/dependabot.yml",
|
|
50
51
|
".github/templates/dependabot.yml",
|
|
51
|
-
".github/renovate.json",
|
|
52
52
|
".github/workflows/packages-release.yml",
|
|
53
53
|
".github/workflows/publish.yml",
|
|
54
54
|
".github/workflows/release-sync.yml",
|
|
@@ -62,11 +62,8 @@ function extractSemver(value) {
|
|
|
62
62
|
if (!value) return null;
|
|
63
63
|
return value.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/)?.[0] ?? null;
|
|
64
64
|
}
|
|
65
|
-
function readJsonFile(filePath) {
|
|
66
|
-
return JSON.parse((0, node_fs.readFileSync)(filePath, "utf-8"));
|
|
67
|
-
}
|
|
68
65
|
function readRootPackageJson(projectDir) {
|
|
69
|
-
return readJsonFile((0, node_path.join)(projectDir, "package.json"));
|
|
66
|
+
return require_helpers.readJsonFile((0, node_path.join)(projectDir, "package.json"));
|
|
70
67
|
}
|
|
71
68
|
function readRootCatalogEntry(projectDir, packageName) {
|
|
72
69
|
return readRootPackageJson(projectDir).workspaces?.catalog?.[packageName];
|
|
@@ -148,23 +145,23 @@ function packageObjectNeedsCatalogRefs(pkg, packageNames) {
|
|
|
148
145
|
return false;
|
|
149
146
|
}
|
|
150
147
|
function packageFileNeedsCatalogRefs(filePath, packageNames) {
|
|
151
|
-
return packageObjectNeedsCatalogRefs(readJsonFile(filePath), packageNames);
|
|
148
|
+
return packageObjectNeedsCatalogRefs(require_helpers.readJsonFile(filePath), packageNames);
|
|
152
149
|
}
|
|
153
150
|
function updatePackageFileCatalogRefs(filePath, packageNames) {
|
|
154
|
-
const pkg = readJsonFile(filePath);
|
|
151
|
+
const pkg = require_helpers.readJsonFile(filePath);
|
|
155
152
|
const modified = syncPackageObjectCatalogRefs(pkg, packageNames);
|
|
156
153
|
if (modified) (0, node_fs.writeFileSync)(filePath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
157
154
|
return modified;
|
|
158
155
|
}
|
|
159
156
|
function updatePackageFileAuthCoreRef(filePath) {
|
|
160
|
-
const pkg = readJsonFile(filePath);
|
|
157
|
+
const pkg = require_helpers.readJsonFile(filePath);
|
|
161
158
|
const modified = ensureAuthCoreCatalogRef(pkg);
|
|
162
159
|
if (modified) (0, node_fs.writeFileSync)(filePath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
163
160
|
return modified;
|
|
164
161
|
}
|
|
165
162
|
function syncRootCatalogWithParent(projectDir, parentCatalog) {
|
|
166
163
|
const pkgPath = (0, node_path.join)(projectDir, "package.json");
|
|
167
|
-
const pkg = readJsonFile(pkgPath);
|
|
164
|
+
const pkg = require_helpers.readJsonFile(pkgPath);
|
|
168
165
|
let modified = syncPackageObjectCatalogRefs(pkg, Object.keys(parentCatalog));
|
|
169
166
|
if (!pkg.workspaces || typeof pkg.workspaces !== "object") {
|
|
170
167
|
pkg.workspaces = {
|
|
@@ -192,7 +189,7 @@ async function readExtendedRootSource(projectDir) {
|
|
|
192
189
|
extendsChain: []
|
|
193
190
|
};
|
|
194
191
|
const localConfig = JSON.parse((0, node_fs.readFileSync)(configPath, "utf-8"));
|
|
195
|
-
let extendsRef = getExtendsRef(localConfig);
|
|
192
|
+
let extendsRef = require_helpers.getExtendsRef(localConfig);
|
|
196
193
|
if (!extendsRef?.startsWith("bos://")) return {
|
|
197
194
|
catalog: {},
|
|
198
195
|
repository: typeof localConfig.repository === "string" ? localConfig.repository : void 0,
|
|
@@ -206,7 +203,7 @@ async function readExtendedRootSource(projectDir) {
|
|
|
206
203
|
if (visited.has(extendsRef)) throw new Error(`Circular extends detected while resolving upgrade source: ${extendsRef}`);
|
|
207
204
|
visited.add(extendsRef);
|
|
208
205
|
extendsChain.push(extendsRef);
|
|
209
|
-
const parsed = parseBosRef(extendsRef);
|
|
206
|
+
const parsed = require_helpers.parseBosRef(extendsRef);
|
|
210
207
|
if (!parsed) break;
|
|
211
208
|
rootRef = extendsRef;
|
|
212
209
|
let parentConfig;
|
|
@@ -216,11 +213,11 @@ async function readExtendedRootSource(projectDir) {
|
|
|
216
213
|
break;
|
|
217
214
|
}
|
|
218
215
|
if (typeof parentConfig.repository === "string") repository = parentConfig.repository;
|
|
219
|
-
const nextExtendsRef = getExtendsRef(parentConfig);
|
|
216
|
+
const nextExtendsRef = require_helpers.getExtendsRef(parentConfig);
|
|
220
217
|
if (!nextExtendsRef?.startsWith("bos://")) break;
|
|
221
218
|
extendsRef = nextExtendsRef;
|
|
222
219
|
}
|
|
223
|
-
const parsed = parseBosRef(rootRef);
|
|
220
|
+
const parsed = require_helpers.parseBosRef(rootRef);
|
|
224
221
|
if (!parsed) return {
|
|
225
222
|
catalog: {},
|
|
226
223
|
repository,
|
|
@@ -236,18 +233,6 @@ async function readExtendedRootSource(projectDir) {
|
|
|
236
233
|
extendsChain: source.extendsChain.length > 0 ? source.extendsChain : extendsChain
|
|
237
234
|
};
|
|
238
235
|
}
|
|
239
|
-
function getExtendsRef(config) {
|
|
240
|
-
if (typeof config.extends === "string") return config.extends;
|
|
241
|
-
if (config.extends && typeof config.extends === "object") return require_merge.resolveExtendsRef(config.extends, "production");
|
|
242
|
-
}
|
|
243
|
-
function parseBosRef(ref) {
|
|
244
|
-
const match = ref.match(/^bos:\/\/([^/]+)\/(.+)$/);
|
|
245
|
-
if (!match?.[1] || !match[2]) return null;
|
|
246
|
-
return {
|
|
247
|
-
account: match[1],
|
|
248
|
-
gateway: match[2]
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
236
|
function parseTargetedRef(ref) {
|
|
252
237
|
const hashIndex = ref.indexOf("#");
|
|
253
238
|
if (hashIndex === -1) return { configRef: ref };
|
|
@@ -446,9 +431,9 @@ async function loadParentPluginOptions(projectDir) {
|
|
|
446
431
|
const configPath = (0, node_path.join)(projectDir, "bos.config.json");
|
|
447
432
|
if (!(0, node_fs.existsSync)(configPath)) return null;
|
|
448
433
|
const localConfig = JSON.parse((0, node_fs.readFileSync)(configPath, "utf-8"));
|
|
449
|
-
const extendsRef = getExtendsRef(localConfig);
|
|
434
|
+
const extendsRef = require_helpers.getExtendsRef(localConfig);
|
|
450
435
|
if (!extendsRef?.startsWith("bos://")) return null;
|
|
451
|
-
const parsed = parseBosRef(extendsRef);
|
|
436
|
+
const parsed = require_helpers.parseBosRef(extendsRef);
|
|
452
437
|
if (!parsed) return null;
|
|
453
438
|
let parentConfig;
|
|
454
439
|
try {
|
|
@@ -528,8 +513,8 @@ async function migrateChildRootPackageJson(projectDir) {
|
|
|
528
513
|
const configPath = (0, node_path.join)(projectDir, "bos.config.json");
|
|
529
514
|
const pkgPath = (0, node_path.join)(projectDir, "package.json");
|
|
530
515
|
if (!(0, node_fs.existsSync)(configPath) || !(0, node_fs.existsSync)(pkgPath)) return false;
|
|
531
|
-
if (!getExtendsRef(readJsonFile(configPath))?.startsWith("bos://")) return false;
|
|
532
|
-
const pkg = readJsonFile(pkgPath);
|
|
516
|
+
if (!require_helpers.getExtendsRef(require_helpers.readJsonFile(configPath))?.startsWith("bos://")) return false;
|
|
517
|
+
const pkg = require_helpers.readJsonFile(pkgPath);
|
|
533
518
|
let changed = false;
|
|
534
519
|
if (pkg.private !== true) {
|
|
535
520
|
pkg.private = true;
|
|
@@ -564,7 +549,11 @@ async function migrateChildRootPackageJson(projectDir) {
|
|
|
564
549
|
scripts[key] = value;
|
|
565
550
|
changed = true;
|
|
566
551
|
}
|
|
567
|
-
for (const obsoleteScript of [
|
|
552
|
+
for (const obsoleteScript of [
|
|
553
|
+
...require_cli_init.getParentOnlyScriptKeys(projectDir),
|
|
554
|
+
"sync-catalog",
|
|
555
|
+
"init"
|
|
556
|
+
]) if (obsoleteScript in scripts) {
|
|
568
557
|
delete scripts[obsoleteScript];
|
|
569
558
|
changed = true;
|
|
570
559
|
}
|
|
@@ -630,7 +619,7 @@ async function rewriteLegacyUiImports(projectDir) {
|
|
|
630
619
|
}
|
|
631
620
|
return migrated;
|
|
632
621
|
}
|
|
633
|
-
const LEGACY_DIST_IMPORT_REWRITES = [["from \"everything-dev/
|
|
622
|
+
const LEGACY_DIST_IMPORT_REWRITES = [["from \"everything-dev/", "from \"everything-dev/"], ["from 'everything-dev/", "from 'everything-dev/"]];
|
|
634
623
|
function escapeRegex(s) {
|
|
635
624
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
636
625
|
}
|
|
@@ -775,6 +764,73 @@ async function rewriteLegacyDistImports(projectDir) {
|
|
|
775
764
|
}
|
|
776
765
|
return migrated;
|
|
777
766
|
}
|
|
767
|
+
async function runMigrationPhase(projectDir, options, parentSource) {
|
|
768
|
+
const timings = [];
|
|
769
|
+
const migratedBosConfigs = await require_timing.timePhase(timings, "migrate bos configs", () => migrateBosConfigFiles(projectDir));
|
|
770
|
+
const migratedRootPackageJson = await require_timing.timePhase(timings, "migrate root package", () => migrateChildRootPackageJson(projectDir));
|
|
771
|
+
let syncResult;
|
|
772
|
+
let addedPlugins = [];
|
|
773
|
+
if (!options.noSync && parentSource.extendsChain.length > 0) {
|
|
774
|
+
addedPlugins = await require_timing.timePhase(timings, "discover parent plugins", async () => {
|
|
775
|
+
if (options.dryRun) return [];
|
|
776
|
+
return addSelectedParentPlugins(projectDir);
|
|
777
|
+
});
|
|
778
|
+
syncResult = await require_timing.timePhase(timings, "sync template", () => require_sync.syncTemplate(projectDir, {
|
|
779
|
+
dryRun: false,
|
|
780
|
+
noInstall: true,
|
|
781
|
+
json: false
|
|
782
|
+
}));
|
|
783
|
+
}
|
|
784
|
+
await require_timing.timePhase(timings, "sync shared deps", async () => {
|
|
785
|
+
const configResult = await require_config.loadResolvedConfig({ cwd: projectDir });
|
|
786
|
+
if (!configResult) throw new Error("No bos.config.json found in current directory");
|
|
787
|
+
return require_shared_deps.syncResolvedSharedDeps({
|
|
788
|
+
configDir: projectDir,
|
|
789
|
+
hostMode: "local",
|
|
790
|
+
bosConfig: configResult.config
|
|
791
|
+
});
|
|
792
|
+
});
|
|
793
|
+
if (!options.noInstall) await require_timing.timePhase(timings, "generate types", () => require_cli_init.runTypesGen(projectDir));
|
|
794
|
+
const migratedFiles = await require_timing.timePhase(timings, "clean obsolete files", async () => {
|
|
795
|
+
const nextMigratedFiles = [
|
|
796
|
+
...migratedBosConfigs,
|
|
797
|
+
...migratedRootPackageJson ? ["package.json"] : [],
|
|
798
|
+
...await rewriteLegacyUiImports(projectDir),
|
|
799
|
+
...await rewriteLegacyPluginScopedLayerPatterns(projectDir),
|
|
800
|
+
...await rewriteLegacyDistImports(projectDir)
|
|
801
|
+
];
|
|
802
|
+
for (const file of OBSOLETE_FILES) {
|
|
803
|
+
const filePath = (0, node_path.join)(projectDir, file);
|
|
804
|
+
if ((0, node_fs.existsSync)(filePath)) {
|
|
805
|
+
(0, node_fs.rmSync)(filePath);
|
|
806
|
+
nextMigratedFiles.push(file);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
const legacyPluginDbFiles = await (0, glob.glob)("plugins/*/src/db/{migrator,load-migrations}.ts", {
|
|
810
|
+
cwd: projectDir,
|
|
811
|
+
nodir: true,
|
|
812
|
+
dot: false,
|
|
813
|
+
absolute: false
|
|
814
|
+
});
|
|
815
|
+
for (const file of legacyPluginDbFiles) {
|
|
816
|
+
(0, node_fs.rmSync)((0, node_path.join)(projectDir, file));
|
|
817
|
+
nextMigratedFiles.push(file);
|
|
818
|
+
}
|
|
819
|
+
return nextMigratedFiles;
|
|
820
|
+
});
|
|
821
|
+
let changelogUrl;
|
|
822
|
+
const mainPkg = parentSource.catalog["everything-dev"];
|
|
823
|
+
if (mainPkg) changelogUrl = buildChangelogUrl(void 0, mainPkg, parentSource.repository);
|
|
824
|
+
return {
|
|
825
|
+
status: "upgraded",
|
|
826
|
+
packages: [],
|
|
827
|
+
sync: syncResult,
|
|
828
|
+
migrated: migratedFiles.length > 0 ? migratedFiles : void 0,
|
|
829
|
+
selectedPlugins: addedPlugins.length > 0 ? addedPlugins : void 0,
|
|
830
|
+
timings,
|
|
831
|
+
changelogUrl
|
|
832
|
+
};
|
|
833
|
+
}
|
|
778
834
|
async function upgradeTemplate(projectDir, options) {
|
|
779
835
|
const timings = [];
|
|
780
836
|
if (!(0, node_fs.existsSync)((0, node_path.join)(projectDir, "package.json"))) return {
|
|
@@ -789,7 +845,7 @@ async function upgradeTemplate(projectDir, options) {
|
|
|
789
845
|
const currentCatalogEntries = readRootPackageJson(projectDir).workspaces?.catalog ?? {};
|
|
790
846
|
const workspacePkgPaths = await findWorkspacePackageJsons(projectDir);
|
|
791
847
|
const hasCatalogRefRewrites = inheritedCatalogPackageNames.length > 0 && (packageObjectNeedsCatalogRefs(readRootPackageJson(projectDir), inheritedCatalogPackageNames) || workspacePkgPaths.some((pkgPath) => packageFileNeedsCatalogRefs(pkgPath, inheritedCatalogPackageNames)));
|
|
792
|
-
const hasAuthCoreRefRewrites = packageObjectNeedsAuthCoreCatalogRef(readRootPackageJson(projectDir)) || workspacePkgPaths.some((pkgPath) => packageObjectNeedsAuthCoreCatalogRef(readJsonFile(pkgPath)));
|
|
848
|
+
const hasAuthCoreRefRewrites = packageObjectNeedsAuthCoreCatalogRef(readRootPackageJson(projectDir)) || workspacePkgPaths.some((pkgPath) => packageObjectNeedsAuthCoreCatalogRef(require_helpers.readJsonFile(pkgPath)));
|
|
793
849
|
const { packages, catalogVersionUpdates } = await require_timing.timePhase(timings, "check package versions", async () => {
|
|
794
850
|
const nextPackages = [];
|
|
795
851
|
for (const name of FRAMEWORK_PACKAGES) {
|
|
@@ -839,79 +895,81 @@ async function upgradeTemplate(projectDir, options) {
|
|
|
839
895
|
changelogUrl
|
|
840
896
|
};
|
|
841
897
|
}
|
|
898
|
+
if (options.migrationsOnly) return await runMigrationPhase(projectDir, options, parentSource);
|
|
842
899
|
await require_timing.timePhase(timings, "apply package updates", async () => {
|
|
843
900
|
if (inheritedCatalogPackageNames.length > 0) syncRootCatalogWithParent(projectDir, sourceRootCatalog);
|
|
844
901
|
if (inheritedCatalogPackageNames.length > 0) for (const pkgPath of workspacePkgPaths) updatePackageFileCatalogRefs(pkgPath, inheritedCatalogPackageNames);
|
|
845
902
|
});
|
|
846
|
-
const
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
dryRun: false,
|
|
857
|
-
noInstall: true
|
|
858
|
-
}));
|
|
859
|
-
if (inheritedCatalogPackageNames.length > 0) syncRootCatalogWithParent(projectDir, sourceRootCatalog);
|
|
860
|
-
}
|
|
861
|
-
const sharedSync = await require_timing.timePhase(timings, "sync shared deps", async () => {
|
|
862
|
-
const configResult = await require_config.loadResolvedConfig({ cwd: projectDir });
|
|
863
|
-
if (!configResult) throw new Error("No bos.config.json found in current directory");
|
|
864
|
-
return require_shared_deps.syncResolvedSharedDeps({
|
|
865
|
-
configDir: projectDir,
|
|
866
|
-
hostMode: "local",
|
|
867
|
-
bosConfig: configResult.config
|
|
868
|
-
});
|
|
869
|
-
});
|
|
870
|
-
if ((hasUpdates || addedPlugins.length > 0 || sharedSync.catalogChanged) && !options.noInstall) {
|
|
871
|
-
await require_timing.timePhase(timings, "install dependencies", () => require_cli_init.runBunInstallForUpgrade(projectDir));
|
|
872
|
-
await require_timing.timePhase(timings, "generate types", () => require_cli_init.runTypesGen(projectDir));
|
|
873
|
-
}
|
|
874
|
-
const migratedFiles = await require_timing.timePhase(timings, "clean obsolete files", async () => {
|
|
875
|
-
const nextMigratedFiles = [
|
|
876
|
-
...migratedBosConfigs,
|
|
877
|
-
...migratedRootPackageJson ? ["package.json"] : [],
|
|
878
|
-
...await rewriteLegacyUiImports(projectDir),
|
|
879
|
-
...await rewriteLegacyPluginScopedLayerPatterns(projectDir),
|
|
880
|
-
...await rewriteLegacyDistImports(projectDir)
|
|
881
|
-
];
|
|
882
|
-
for (const file of OBSOLETE_FILES) {
|
|
883
|
-
const filePath = (0, node_path.join)(projectDir, file);
|
|
884
|
-
if ((0, node_fs.existsSync)(filePath)) {
|
|
885
|
-
(0, node_fs.rmSync)(filePath);
|
|
886
|
-
nextMigratedFiles.push(file);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
const legacyPluginDbFiles = await (0, glob.glob)("plugins/*/src/db/{migrator,load-migrations}.ts", {
|
|
903
|
+
const needsInstall = (hasUpdates || hasCatalogUpdates) && !options.noInstall;
|
|
904
|
+
if (needsInstall) await require_timing.timePhase(timings, "install dependencies", () => require_cli_init.runBunInstallForUpgrade(projectDir));
|
|
905
|
+
if (needsInstall && hasFrameworkUpdates) {
|
|
906
|
+
const childResult = (0, node_child_process.spawnSync)((0, node_path.join)(projectDir, "node_modules", ".bin", "bos"), [
|
|
907
|
+
"upgrade",
|
|
908
|
+
"--migrations-only",
|
|
909
|
+
"--no-install",
|
|
910
|
+
...options.noSync ? ["--no-sync"] : [],
|
|
911
|
+
"--json"
|
|
912
|
+
], {
|
|
890
913
|
cwd: projectDir,
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
914
|
+
stdio: [
|
|
915
|
+
"inherit",
|
|
916
|
+
"pipe",
|
|
917
|
+
"pipe"
|
|
918
|
+
],
|
|
919
|
+
encoding: "utf-8",
|
|
920
|
+
env: {
|
|
921
|
+
...node_process.default.env,
|
|
922
|
+
BOS_NO_BANNER: "1"
|
|
923
|
+
}
|
|
894
924
|
});
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
925
|
+
if (childResult.status !== 0) return {
|
|
926
|
+
status: "error",
|
|
927
|
+
packages: [...packages, ...catalogVersionUpdates.map((u) => ({
|
|
928
|
+
name: u.name,
|
|
929
|
+
from: u.from,
|
|
930
|
+
to: u.to
|
|
931
|
+
}))],
|
|
932
|
+
timings,
|
|
933
|
+
error: `Migration phase failed: ${childResult.stderr || childResult.stdout || "Unknown error"}`
|
|
934
|
+
};
|
|
935
|
+
try {
|
|
936
|
+
const childUpgrade = JSON.parse(childResult.stdout);
|
|
937
|
+
const mainPkg = packages.find((p) => p.name === "everything-dev");
|
|
938
|
+
const changelogUrl = mainPkg?.from && mainPkg.from !== mainPkg.to ? buildChangelogUrl(mainPkg.from, mainPkg.to, parentSource.repository) : void 0;
|
|
939
|
+
return {
|
|
940
|
+
...childUpgrade,
|
|
941
|
+
packages: [...packages, ...catalogVersionUpdates.map((u) => ({
|
|
942
|
+
name: u.name,
|
|
943
|
+
from: u.from,
|
|
944
|
+
to: u.to
|
|
945
|
+
}))],
|
|
946
|
+
timings: [...timings, ...childUpgrade.timings ?? []],
|
|
947
|
+
changelogUrl
|
|
948
|
+
};
|
|
949
|
+
} catch {
|
|
950
|
+
return {
|
|
951
|
+
status: "error",
|
|
952
|
+
packages: [...packages, ...catalogVersionUpdates.map((u) => ({
|
|
953
|
+
name: u.name,
|
|
954
|
+
from: u.from,
|
|
955
|
+
to: u.to
|
|
956
|
+
}))],
|
|
957
|
+
timings,
|
|
958
|
+
error: "Failed to parse migration phase output"
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
const migrationResult = await runMigrationPhase(projectDir, options, parentSource);
|
|
902
963
|
const mainPkg = packages.find((p) => p.name === "everything-dev");
|
|
903
|
-
|
|
964
|
+
const changelogUrl = mainPkg?.from && mainPkg.from !== mainPkg.to ? buildChangelogUrl(mainPkg.from, mainPkg.to, parentSource.repository) : void 0;
|
|
904
965
|
return {
|
|
905
|
-
|
|
966
|
+
...migrationResult,
|
|
906
967
|
packages: [...packages, ...catalogVersionUpdates.map((u) => ({
|
|
907
968
|
name: u.name,
|
|
908
969
|
from: u.from,
|
|
909
970
|
to: u.to
|
|
910
971
|
}))],
|
|
911
|
-
|
|
912
|
-
migrated: migratedFiles.length > 0 ? migratedFiles : void 0,
|
|
913
|
-
selectedPlugins: addedPlugins.length > 0 ? addedPlugins : void 0,
|
|
914
|
-
timings,
|
|
972
|
+
timings: [...timings, ...migrationResult.timings ?? []],
|
|
915
973
|
changelogUrl
|
|
916
974
|
};
|
|
917
975
|
}
|