everything-dev 1.8.11 → 1.8.13
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/cli/init.cjs +34 -5
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +1 -0
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +1 -0
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +34 -5
- package/dist/cli/init.mjs.map +1 -1
- package/dist/dev-session.cjs +4 -7
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +4 -7
- package/dist/dev-session.mjs.map +1 -1
- package/dist/orchestrator.cjs +10 -2
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.d.cts.map +1 -1
- package/dist/orchestrator.d.mts.map +1 -1
- package/dist/orchestrator.mjs +10 -2
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs +2 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.mjs +2 -1
- package/dist/plugin.mjs.map +1 -1
- package/package.json +2 -2
- package/skills/dev-workflow/SKILL.md +24 -0
- package/src/cli/init.ts +66 -12
- package/src/dev-session.ts +7 -11
- package/src/orchestrator.ts +10 -2
- package/src/plugin.ts +1 -0
package/dist/cli/init.cjs
CHANGED
|
@@ -205,6 +205,8 @@ async function personalizeConfig(destination, opts) {
|
|
|
205
205
|
if (opts.domain) config.domain = opts.domain;
|
|
206
206
|
if (isInit && config.app && typeof config.app === "object") {
|
|
207
207
|
const app = config.app;
|
|
208
|
+
const authClientPath = (0, node_path.join)(destination, "ui", "src", "lib", "auth-client.ts");
|
|
209
|
+
if ((0, node_fs.existsSync)(authClientPath)) (0, node_fs.writeFileSync)(authClientPath, (0, node_fs.readFileSync)(authClientPath, "utf-8").split("\n").filter((line) => !line.includes("inferAdditionalFields") && !line.includes("createAuthInstance")).join("\n"));
|
|
208
210
|
for (const entryKey of Object.keys(app)) {
|
|
209
211
|
const entry = app[entryKey];
|
|
210
212
|
if (entry && typeof entry === "object") {
|
|
@@ -238,10 +240,13 @@ async function personalizeConfig(destination, opts) {
|
|
|
238
240
|
const pkg = JSON.parse((0, node_fs.readFileSync)(pkgPath, "utf-8"));
|
|
239
241
|
if (pkg.workspaces && typeof pkg.workspaces === "object") {
|
|
240
242
|
const ws = pkg.workspaces;
|
|
241
|
-
if (Array.isArray(ws.packages)) ws.packages = ws.packages.filter((p) =>
|
|
243
|
+
if (Array.isArray(ws.packages)) ws.packages = ws.packages.filter((p) => {
|
|
244
|
+
if (p.startsWith("packages/")) return false;
|
|
245
|
+
if (p === "host") return opts.withHost ?? false;
|
|
246
|
+
if (p === "plugins/*") return (opts.plugins?.length ?? 0) > 0;
|
|
242
247
|
const pluginMatch = p.match(/^plugins\/([^/]+)/);
|
|
243
|
-
if (
|
|
244
|
-
return
|
|
248
|
+
if (pluginMatch) return opts.plugins?.includes(pluginMatch[1]) ?? true;
|
|
249
|
+
return true;
|
|
245
250
|
});
|
|
246
251
|
}
|
|
247
252
|
if (pkg.scripts && typeof pkg.scripts === "object") {
|
|
@@ -257,9 +262,11 @@ async function personalizeConfig(destination, opts) {
|
|
|
257
262
|
rewrite("deploy", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
|
|
258
263
|
rewrite("publish", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
|
|
259
264
|
rewrite("start", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
|
|
260
|
-
if (scripts["sync:api-contract"]) delete scripts["sync:api-contract"];
|
|
261
265
|
if (scripts.postinstall) delete scripts.postinstall;
|
|
262
|
-
if (scripts.typecheck
|
|
266
|
+
if (scripts.typecheck) {
|
|
267
|
+
scripts.typecheck = scripts.typecheck.replace("bun run sync:api-contract && ", "").replace(/bun run --cwd packages\/everything-dev typecheck & ?/, "");
|
|
268
|
+
if (!opts.withHost) scripts.typecheck = scripts.typecheck.replace(/bun run --cwd host tsc --noEmit & ?/, "");
|
|
269
|
+
}
|
|
263
270
|
}
|
|
264
271
|
if (pkg.devDependencies && typeof pkg.devDependencies === "object") {
|
|
265
272
|
const deps = pkg.devDependencies;
|
|
@@ -273,12 +280,34 @@ async function personalizeConfig(destination, opts) {
|
|
|
273
280
|
if (!deps["every-plugin"] && spec) deps["every-plugin"] = spec.rootCatalog["every-plugin"];
|
|
274
281
|
(0, node_fs.writeFileSync)(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
275
282
|
}
|
|
283
|
+
const apiTsConfigPath = (0, node_path.join)(destination, "api", "tsconfig.json");
|
|
284
|
+
if ((0, node_fs.existsSync)(apiTsConfigPath)) {
|
|
285
|
+
const apiTsConfig = JSON.parse((0, node_fs.readFileSync)(apiTsConfigPath, "utf-8"));
|
|
286
|
+
if (apiTsConfig.files) {
|
|
287
|
+
const validFiles = apiTsConfig.files.filter((f) => (0, node_fs.existsSync)((0, node_path.join)(destination, "api", f)));
|
|
288
|
+
if (validFiles.length !== apiTsConfig.files.length) {
|
|
289
|
+
if (validFiles.length === 0) delete apiTsConfig.files;
|
|
290
|
+
else apiTsConfig.files = validFiles;
|
|
291
|
+
(0, node_fs.writeFileSync)(apiTsConfigPath, `${JSON.stringify(apiTsConfig, null, 2)}\n`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
276
295
|
await resolveWorkspaceRefs(destination, opts.workspaceOpts);
|
|
277
296
|
const genContractPath = (0, node_path.join)(destination, "ui", "src", "api-contract.gen.ts");
|
|
278
297
|
if (!(0, node_fs.existsSync)(genContractPath)) {
|
|
279
298
|
(0, node_fs.mkdirSync)((0, node_path.dirname)(genContractPath), { recursive: true });
|
|
280
299
|
(0, node_fs.writeFileSync)(genContractPath, `export type ApiContract = Record<string, never>;\n`);
|
|
281
300
|
}
|
|
301
|
+
const authClientGenPath = (0, node_path.join)(destination, "api", "src", "auth-client.gen.ts");
|
|
302
|
+
if (!(0, node_fs.existsSync)(authClientGenPath)) {
|
|
303
|
+
(0, node_fs.mkdirSync)((0, node_path.dirname)(authClientGenPath), { recursive: true });
|
|
304
|
+
(0, node_fs.writeFileSync)(authClientGenPath, `import type { ContractRouterClient, AnyContractRouter } from "@orpc/contract";\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\nexport type AuthClient = ClientFactory<any>;\n`);
|
|
305
|
+
}
|
|
306
|
+
const pluginsClientGenPath = (0, node_path.join)(destination, "api", "src", "plugins-client.gen.ts");
|
|
307
|
+
if (!(0, node_fs.existsSync)(pluginsClientGenPath)) {
|
|
308
|
+
(0, node_fs.mkdirSync)((0, node_path.dirname)(pluginsClientGenPath), { recursive: true });
|
|
309
|
+
(0, node_fs.writeFileSync)(pluginsClientGenPath, `import type { ContractRouterClient, AnyContractRouter } from "@orpc/contract";\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\nexport type PluginsClient = Record<string, never>;\n`);
|
|
310
|
+
}
|
|
282
311
|
}
|
|
283
312
|
async function runBunInstall(destination) {
|
|
284
313
|
await execCommand("bun", ["install"], destination);
|
package/dist/cli/init.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.cjs","names":["require","fetchBosConfigFromFastKv","loadManifestNormalizationSpec","normalizePackageManifestsInTree","writeSnapshot"],"sources":["../../src/cli/init.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n createWriteStream,\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { glob } from \"glob\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport {\n loadManifestNormalizationSpec,\n normalizePackageManifestsInTree,\n} from \"../internal/manifest-normalizer\";\nimport type { BosConfig } from \"../types\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst require = createRequire(import.meta.url);\n\nconst BOS_CONFIG_ORDER = [\n \"extends\",\n \"account\",\n \"domain\",\n \"testnet\",\n \"staging\",\n \"repository\",\n \"app\",\n \"plugins\",\n \"shared\",\n];\n\nfunction rebuildOrderedConfig(config: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n\n for (const key of BOS_CONFIG_ORDER) {\n if (key in config) {\n ordered[key] = config[key];\n }\n }\n\n for (const key of Object.keys(config)) {\n if (!BOS_CONFIG_ORDER.includes(key)) {\n ordered[key] = config[key];\n }\n }\n\n return ordered;\n}\n\ninterface SourceResult {\n sourceDir: string;\n parentConfig: BosConfig;\n cleanup: () => Promise<void>;\n}\n\nexport async function resolveSourceDir(opts: {\n extendsAccount: string;\n extendsGateway: string;\n source?: string;\n}): Promise<SourceResult> {\n if (opts.source) {\n const sourceDir = resolve(opts.source);\n if (!existsSync(join(sourceDir, \"bos.config.json\"))) {\n throw new Error(`No bos.config.json found in source directory: ${sourceDir}`);\n }\n const parentConfig = JSON.parse(\n readFileSync(join(sourceDir, \"bos.config.json\"), \"utf-8\"),\n ) as BosConfig;\n return { sourceDir, parentConfig, cleanup: async () => {} };\n }\n\n const parentConfig = await fetchParentConfig(opts.extendsAccount, opts.extendsGateway);\n\n if (!parentConfig.repository) {\n throw new Error(\"Parent config has no repository field — cannot locate template source\");\n }\n\n const { dir: sourceDir, cleanup } = await downloadTarball(parentConfig.repository);\n return { sourceDir, parentConfig, cleanup };\n}\n\nexport async function fetchParentConfig(\n extendsAccount: string,\n extendsGateway: string,\n): Promise<BosConfig> {\n const bosUrl = `bos://${extendsAccount}/${extendsGateway}`;\n return fetchBosConfigFromFastKv<BosConfig>(bosUrl);\n}\n\nexport async function downloadTarball(\n repoUrl: string,\n): Promise<{ dir: string; cleanup: () => Promise<void> }> {\n const parsed = parseGitHubUrl(repoUrl);\n if (!parsed) {\n throw new Error(`Cannot parse repository URL: ${repoUrl}`);\n }\n\n const { owner, repo, branch } = parsed;\n const tarballUrl = `https://api.github.com/repos/${owner}/${repo}/tarball/${branch}`;\n\n const tmpDir = mkTmpDir(\"bos-init-tarball-\");\n const tarballPath = join(tmpDir, \"source.tar.gz\");\n\n const response = await fetch(tarballUrl, {\n headers: { \"User-Agent\": \"everything-dev\" },\n redirect: \"follow\",\n });\n\n if (!response.ok) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(`GitHub tarball download failed: ${response.status} ${response.statusText}`);\n }\n\n if (!response.body) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(\"GitHub tarball download returned empty body\");\n }\n\n const fileStream = createWriteStream(tarballPath);\n const reader = response.body as unknown as NodeJS.ReadableStream;\n await pipeline(reader, fileStream);\n\n const extractDir = mkTmpDir(\"bos-init-extract-\");\n try {\n const tar = require(\"tar\") as {\n extract: (opts: { cwd: string; file: string; strip: number }) => Promise<void>;\n };\n await tar.extract({ cwd: extractDir, file: tarballPath, strip: 1 });\n } catch {\n await execCommand(\"tar\", [\"-xzf\", tarballPath, \"--strip-components=1\", \"-C\", extractDir]);\n }\n\n rmSync(tmpDir, { recursive: true, force: true });\n\n return {\n dir: extractDir,\n cleanup: async () => {\n rmSync(extractDir, { recursive: true, force: true });\n },\n };\n}\n\nfunction parseGitHubUrl(url: string): { owner: string; repo: string; branch: string } | null {\n const httpsMatch = url.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:\\/.*)?$/);\n if (httpsMatch) {\n return { owner: httpsMatch[1], repo: httpsMatch[2], branch: \"main\" };\n }\n\n const sshMatch = url.match(/^git@github\\.com:([^/]+)\\/([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return { owner: sshMatch[1], repo: sshMatch[2], branch: \"main\" };\n }\n\n return null;\n}\n\nexport async function readTemplatekeep(sourceDir: string): Promise<string[]> {\n const keepFile = join(sourceDir, \".templatekeep\");\n if (!existsSync(keepFile)) {\n return [];\n }\n\n const content = readFileSync(keepFile, \"utf-8\");\n return content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nexport async function copyFilteredFiles(\n sourceDir: string,\n destination: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<number> {\n if (patterns.length === 0) {\n return 0;\n }\n\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const filteredPatterns = effectivePatterns.filter((p) => {\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (!pluginMatch) return true;\n const pluginName = pluginMatch[1];\n return options.plugins?.includes(pluginName) ?? true;\n });\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of filteredPatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch) {\n const pluginName = pluginMatch[1];\n if (!(options.plugins?.includes(pluginName) ?? true)) continue;\n }\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n const routeFiles = new Set<string>();\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n routeFiles.add(match);\n }\n }\n }\n }\n }\n\n for (const f of routeFiles) allFiles.add(f);\n\n mkdirSync(destination, { recursive: true });\n\n let count = 0;\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(destination, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nfunction isRouteExcluded(filePath: string, excludedPatterns: string[]): boolean {\n if (excludedPatterns.length === 0) return false;\n for (const pattern of excludedPatterns) {\n if (pattern.endsWith(\"/**\")) {\n const prefix = pattern.slice(0, -3);\n if (filePath.startsWith(`${prefix}/`) || filePath === prefix) return true;\n } else if (filePath === pattern || filePath.startsWith(`${pattern}/`)) {\n return true;\n }\n }\n return false;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n extendsAccount: string;\n extendsGateway: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n pluginRoutes?: Record<string, string[]>;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n mode?: \"init\" | \"sync\";\n },\n): Promise<void> {\n const isInit = opts.mode !== \"sync\";\n const configPath = join(destination, \"bos.config.json\");\n if (existsSync(configPath)) {\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n config.extends = `bos://${opts.extendsAccount}/${opts.extendsGateway}`;\n\n if (opts.account) {\n config.account = opts.account;\n }\n if (opts.domain) {\n config.domain = opts.domain;\n }\n\n if (isInit && config.app && typeof config.app === \"object\") {\n const app = config.app as Record<string, unknown>;\n for (const entryKey of Object.keys(app)) {\n const entry = app[entryKey];\n if (entry && typeof entry === \"object\") {\n const e = entry as Record<string, unknown>;\n delete e.production;\n delete e.integrity;\n delete e.ssr;\n delete e.ssrIntegrity;\n }\n }\n }\n\n if (config.plugins && typeof config.plugins === \"object\") {\n const plugins = config.plugins as Record<string, unknown>;\n\n if (opts.plugins && opts.plugins.length > 0) {\n for (const pluginKey of Object.keys(plugins)) {\n if (!opts.plugins.includes(pluginKey)) {\n delete plugins[pluginKey];\n }\n }\n }\n\n if (isInit) {\n for (const pluginKey of Object.keys(plugins)) {\n const plugin = plugins[pluginKey];\n if (plugin && typeof plugin === \"object\") {\n const p = plugin as Record<string, unknown>;\n delete p.production;\n delete p.integrity;\n }\n }\n }\n\n if (Object.keys(plugins).length === 0) {\n config.plugins = {};\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(rebuildOrderedConfig(config), null, 2)}\\n`);\n }\n\n const pkgPath = join(destination, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const ws = pkg.workspaces as { packages?: string[] };\n if (Array.isArray(ws.packages)) {\n ws.packages = ws.packages\n .filter((p: string) => p !== \"host\" && !p.startsWith(\"packages/\"))\n .filter((p: string) => {\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (!pluginMatch) return true;\n return opts.plugins?.includes(pluginMatch[1]) ?? true;\n });\n }\n }\n\n if (pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n const rewrite = (key: string, from: string, to: string) => {\n if (scripts[key]?.includes(from)) {\n scripts[key] = scripts[key].replaceAll(from, to);\n }\n };\n rewrite(\"dev\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:ui\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:api\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:proxy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"build\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"deploy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"publish\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"start\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n\n if (scripts[\"sync:api-contract\"]) {\n delete scripts[\"sync:api-contract\"];\n }\n if (scripts.postinstall) {\n delete scripts.postinstall;\n }\n if (scripts.typecheck?.includes(\"sync:api-contract\")) {\n scripts.typecheck = scripts.typecheck.replace(\"bun run sync:api-contract && \", \"\");\n }\n }\n\n if (pkg.devDependencies && typeof pkg.devDependencies === \"object\") {\n const deps = pkg.devDependencies as Record<string, string>;\n delete deps[\"every-plugin\"];\n delete deps[\"everything-dev\"];\n }\n\n if (!pkg.dependencies) pkg.dependencies = {};\n const deps = pkg.dependencies as Record<string, string>;\n const spec = opts.workspaceOpts?.sourceDir\n ? loadManifestNormalizationSpec(opts.workspaceOpts.sourceDir)\n : null;\n if (!deps[\"everything-dev\"] && spec)\n deps[\"everything-dev\"] = spec.rootCatalog[\"everything-dev\"];\n if (!deps[\"every-plugin\"] && spec) deps[\"every-plugin\"] = spec.rootCatalog[\"every-plugin\"];\n\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n await resolveWorkspaceRefs(destination, opts.workspaceOpts);\n\n const genContractPath = join(destination, \"ui\", \"src\", \"api-contract.gen.ts\");\n if (!existsSync(genContractPath)) {\n mkdirSync(dirname(genContractPath), { recursive: true });\n writeFileSync(genContractPath, `export type ApiContract = Record<string, never>;\\n`);\n }\n}\n\nexport async function runBunInstall(destination: string): Promise<void> {\n await execCommand(\"bun\", [\"install\"], destination);\n}\n\nconst WORKSPACE_LOCAL_PATHS: Record<string, string> = {\n \"everything-dev\": \"packages/everything-dev\",\n \"every-plugin\": \"packages/every-plugin\",\n};\n\nasync function resolveWorkspaceRefs(\n destination: string,\n options?: { localOverrides?: boolean; sourceDir?: string },\n): Promise<void> {\n await normalizePackageManifestsInTree({\n sourceRootDir: options?.sourceDir ?? destination,\n targetDir: destination,\n resolveCatalogRefs: true,\n removeWorkspaceDeps: [\"host\"],\n });\n\n if (options?.localOverrides && options.sourceDir) {\n const rootPkgPath = join(destination, \"package.json\");\n if (existsSync(rootPkgPath)) {\n const pkg = JSON.parse(readFileSync(rootPkgPath, \"utf-8\")) as Record<string, unknown>;\n if (!pkg.overrides) pkg.overrides = {};\n const overrides = pkg.overrides as Record<string, string>;\n\n const rootWorkspaces = ((pkg.workspaces as Record<string, string[]>)?.packages ?? []).filter(\n Boolean,\n );\n\n for (const [name, relPath] of Object.entries(WORKSPACE_LOCAL_PATHS)) {\n if (!rootWorkspaces.some((ws) => ws === relPath || ws === `plugins/${name}`)) {\n const srcPkgPath = join(options.sourceDir, relPath, \"package.json\");\n if (existsSync(srcPkgPath)) {\n overrides[name] = `file:${relPath}`;\n rootWorkspaces.push(relPath);\n }\n }\n }\n\n if (rootWorkspaces.length > 0) {\n if (!pkg.workspaces) pkg.workspaces = {};\n (pkg.workspaces as Record<string, string[]>).packages = rootWorkspaces;\n }\n\n writeFileSync(rootPkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n }\n}\n\nexport async function writeInitSnapshot(\n destination: string,\n extendsAccount: string,\n extendsGateway: string,\n sourceDir: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<void> {\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of effectivePatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch && !(options.plugins?.includes(pluginMatch[1]) ?? true)) continue;\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n allFiles.add(match);\n }\n }\n }\n }\n }\n\n const fileHashes: Record<string, string> = {};\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n const content = readFileSync(src);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n fileHashes[destPath] = computeHash(content);\n }\n\n await writeSnapshot(destination, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: fileHashes,\n });\n}\n\nfunction computeHash(data: Uint8Array): string {\n return createHash(\"sha256\").update(data).digest(\"hex\").substring(0, 16);\n}\n\nfunction mkTmpDir(prefix: string): string {\n const base = join(tmpdir(), prefix);\n let attempt = 0;\n while (true) {\n const dir = `${base}-${Date.now()}-${attempt}`;\n try {\n mkdirSync(dir, { recursive: true });\n return dir;\n } catch {\n attempt++;\n if (attempt > 10) throw new Error(\"Failed to create temp directory\");\n }\n }\n}\n\nfunction execCommand(command: string, args: string[], cwd?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"pipe\",\n shell: true,\n });\n let stderr = \"\";\n child.stderr?.on(\"data\", (data: Buffer) => {\n stderr += data.toString();\n });\n child.on(\"close\", (code) => {\n if (code === 0) resolve();\n else\n reject(\n new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${code}: ${stderr}`,\n ),\n );\n });\n child.on(\"error\", reject);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"init.cjs","names":["require","fetchBosConfigFromFastKv","loadManifestNormalizationSpec","normalizePackageManifestsInTree","writeSnapshot"],"sources":["../../src/cli/init.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n createWriteStream,\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { glob } from \"glob\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport {\n loadManifestNormalizationSpec,\n normalizePackageManifestsInTree,\n} from \"../internal/manifest-normalizer\";\nimport type { BosConfig } from \"../types\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst require = createRequire(import.meta.url);\n\nconst BOS_CONFIG_ORDER = [\n \"extends\",\n \"account\",\n \"domain\",\n \"testnet\",\n \"staging\",\n \"repository\",\n \"app\",\n \"plugins\",\n \"shared\",\n];\n\nfunction rebuildOrderedConfig(config: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n\n for (const key of BOS_CONFIG_ORDER) {\n if (key in config) {\n ordered[key] = config[key];\n }\n }\n\n for (const key of Object.keys(config)) {\n if (!BOS_CONFIG_ORDER.includes(key)) {\n ordered[key] = config[key];\n }\n }\n\n return ordered;\n}\n\ninterface SourceResult {\n sourceDir: string;\n parentConfig: BosConfig;\n cleanup: () => Promise<void>;\n}\n\nexport async function resolveSourceDir(opts: {\n extendsAccount: string;\n extendsGateway: string;\n source?: string;\n}): Promise<SourceResult> {\n if (opts.source) {\n const sourceDir = resolve(opts.source);\n if (!existsSync(join(sourceDir, \"bos.config.json\"))) {\n throw new Error(`No bos.config.json found in source directory: ${sourceDir}`);\n }\n const parentConfig = JSON.parse(\n readFileSync(join(sourceDir, \"bos.config.json\"), \"utf-8\"),\n ) as BosConfig;\n return { sourceDir, parentConfig, cleanup: async () => {} };\n }\n\n const parentConfig = await fetchParentConfig(opts.extendsAccount, opts.extendsGateway);\n\n if (!parentConfig.repository) {\n throw new Error(\"Parent config has no repository field — cannot locate template source\");\n }\n\n const { dir: sourceDir, cleanup } = await downloadTarball(parentConfig.repository);\n return { sourceDir, parentConfig, cleanup };\n}\n\nexport async function fetchParentConfig(\n extendsAccount: string,\n extendsGateway: string,\n): Promise<BosConfig> {\n const bosUrl = `bos://${extendsAccount}/${extendsGateway}`;\n return fetchBosConfigFromFastKv<BosConfig>(bosUrl);\n}\n\nexport async function downloadTarball(\n repoUrl: string,\n): Promise<{ dir: string; cleanup: () => Promise<void> }> {\n const parsed = parseGitHubUrl(repoUrl);\n if (!parsed) {\n throw new Error(`Cannot parse repository URL: ${repoUrl}`);\n }\n\n const { owner, repo, branch } = parsed;\n const tarballUrl = `https://api.github.com/repos/${owner}/${repo}/tarball/${branch}`;\n\n const tmpDir = mkTmpDir(\"bos-init-tarball-\");\n const tarballPath = join(tmpDir, \"source.tar.gz\");\n\n const response = await fetch(tarballUrl, {\n headers: { \"User-Agent\": \"everything-dev\" },\n redirect: \"follow\",\n });\n\n if (!response.ok) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(`GitHub tarball download failed: ${response.status} ${response.statusText}`);\n }\n\n if (!response.body) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(\"GitHub tarball download returned empty body\");\n }\n\n const fileStream = createWriteStream(tarballPath);\n const reader = response.body as unknown as NodeJS.ReadableStream;\n await pipeline(reader, fileStream);\n\n const extractDir = mkTmpDir(\"bos-init-extract-\");\n try {\n const tar = require(\"tar\") as {\n extract: (opts: { cwd: string; file: string; strip: number }) => Promise<void>;\n };\n await tar.extract({ cwd: extractDir, file: tarballPath, strip: 1 });\n } catch {\n await execCommand(\"tar\", [\"-xzf\", tarballPath, \"--strip-components=1\", \"-C\", extractDir]);\n }\n\n rmSync(tmpDir, { recursive: true, force: true });\n\n return {\n dir: extractDir,\n cleanup: async () => {\n rmSync(extractDir, { recursive: true, force: true });\n },\n };\n}\n\nfunction parseGitHubUrl(url: string): { owner: string; repo: string; branch: string } | null {\n const httpsMatch = url.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:\\/.*)?$/);\n if (httpsMatch) {\n return { owner: httpsMatch[1], repo: httpsMatch[2], branch: \"main\" };\n }\n\n const sshMatch = url.match(/^git@github\\.com:([^/]+)\\/([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return { owner: sshMatch[1], repo: sshMatch[2], branch: \"main\" };\n }\n\n return null;\n}\n\nexport async function readTemplatekeep(sourceDir: string): Promise<string[]> {\n const keepFile = join(sourceDir, \".templatekeep\");\n if (!existsSync(keepFile)) {\n return [];\n }\n\n const content = readFileSync(keepFile, \"utf-8\");\n return content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nexport async function copyFilteredFiles(\n sourceDir: string,\n destination: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<number> {\n if (patterns.length === 0) {\n return 0;\n }\n\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const filteredPatterns = effectivePatterns.filter((p) => {\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (!pluginMatch) return true;\n const pluginName = pluginMatch[1];\n return options.plugins?.includes(pluginName) ?? true;\n });\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of filteredPatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch) {\n const pluginName = pluginMatch[1];\n if (!(options.plugins?.includes(pluginName) ?? true)) continue;\n }\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n const routeFiles = new Set<string>();\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n routeFiles.add(match);\n }\n }\n }\n }\n }\n\n for (const f of routeFiles) allFiles.add(f);\n\n mkdirSync(destination, { recursive: true });\n\n let count = 0;\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(destination, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nfunction isRouteExcluded(filePath: string, excludedPatterns: string[]): boolean {\n if (excludedPatterns.length === 0) return false;\n for (const pattern of excludedPatterns) {\n if (pattern.endsWith(\"/**\")) {\n const prefix = pattern.slice(0, -3);\n if (filePath.startsWith(`${prefix}/`) || filePath === prefix) return true;\n } else if (filePath === pattern || filePath.startsWith(`${pattern}/`)) {\n return true;\n }\n }\n return false;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n extendsAccount: string;\n extendsGateway: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n pluginRoutes?: Record<string, string[]>;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n mode?: \"init\" | \"sync\";\n withHost?: boolean;\n },\n): Promise<void> {\n const isInit = opts.mode !== \"sync\";\n const configPath = join(destination, \"bos.config.json\");\n if (existsSync(configPath)) {\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n config.extends = `bos://${opts.extendsAccount}/${opts.extendsGateway}`;\n\n if (opts.account) {\n config.account = opts.account;\n }\n if (opts.domain) {\n config.domain = opts.domain;\n }\n\n if (isInit && config.app && typeof config.app === \"object\") {\n const app = config.app as Record<string, unknown>;\n\n const authClientPath = join(destination, \"ui\", \"src\", \"lib\", \"auth-client.ts\");\n if (existsSync(authClientPath)) {\n const authClientContent = readFileSync(authClientPath, \"utf-8\")\n .split(\"\\n\")\n .filter(\n (line) =>\n !line.includes(\"inferAdditionalFields\") && !line.includes(\"createAuthInstance\"),\n )\n .join(\"\\n\");\n writeFileSync(authClientPath, authClientContent);\n }\n\n for (const entryKey of Object.keys(app)) {\n const entry = app[entryKey];\n if (entry && typeof entry === \"object\") {\n const e = entry as Record<string, unknown>;\n delete e.production;\n delete e.integrity;\n delete e.ssr;\n delete e.ssrIntegrity;\n }\n }\n }\n\n if (config.plugins && typeof config.plugins === \"object\") {\n const plugins = config.plugins as Record<string, unknown>;\n\n if (opts.plugins && opts.plugins.length > 0) {\n for (const pluginKey of Object.keys(plugins)) {\n if (!opts.plugins.includes(pluginKey)) {\n delete plugins[pluginKey];\n }\n }\n }\n\n if (isInit) {\n for (const pluginKey of Object.keys(plugins)) {\n const plugin = plugins[pluginKey];\n if (plugin && typeof plugin === \"object\") {\n const p = plugin as Record<string, unknown>;\n delete p.production;\n delete p.integrity;\n }\n }\n }\n\n if (Object.keys(plugins).length === 0) {\n config.plugins = {};\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(rebuildOrderedConfig(config), null, 2)}\\n`);\n }\n\n const pkgPath = join(destination, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const ws = pkg.workspaces as { packages?: string[] };\n if (Array.isArray(ws.packages)) {\n ws.packages = ws.packages.filter((p: string) => {\n if (p.startsWith(\"packages/\")) return false;\n if (p === \"host\") return opts.withHost ?? false;\n if (p === \"plugins/*\") return (opts.plugins?.length ?? 0) > 0;\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (pluginMatch) return opts.plugins?.includes(pluginMatch[1]) ?? true;\n return true;\n });\n }\n }\n\n if (pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n const rewrite = (key: string, from: string, to: string) => {\n if (scripts[key]?.includes(from)) {\n scripts[key] = scripts[key].replaceAll(from, to);\n }\n };\n rewrite(\"dev\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:ui\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:api\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:proxy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"build\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"deploy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"publish\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"start\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n\n if (scripts.postinstall) {\n delete scripts.postinstall;\n }\n if (scripts.typecheck) {\n scripts.typecheck = scripts.typecheck\n .replace(\"bun run sync:api-contract && \", \"\")\n .replace(/bun run --cwd packages\\/everything-dev typecheck & ?/, \"\");\n if (!opts.withHost) {\n scripts.typecheck = scripts.typecheck.replace(/bun run --cwd host tsc --noEmit & ?/, \"\");\n }\n }\n }\n\n if (pkg.devDependencies && typeof pkg.devDependencies === \"object\") {\n const deps = pkg.devDependencies as Record<string, string>;\n delete deps[\"every-plugin\"];\n delete deps[\"everything-dev\"];\n }\n\n if (!pkg.dependencies) pkg.dependencies = {};\n const deps = pkg.dependencies as Record<string, string>;\n const spec = opts.workspaceOpts?.sourceDir\n ? loadManifestNormalizationSpec(opts.workspaceOpts.sourceDir)\n : null;\n if (!deps[\"everything-dev\"] && spec)\n deps[\"everything-dev\"] = spec.rootCatalog[\"everything-dev\"];\n if (!deps[\"every-plugin\"] && spec) deps[\"every-plugin\"] = spec.rootCatalog[\"every-plugin\"];\n\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n const apiTsConfigPath = join(destination, \"api\", \"tsconfig.json\");\n if (existsSync(apiTsConfigPath)) {\n const apiTsConfig = JSON.parse(readFileSync(apiTsConfigPath, \"utf-8\")) as {\n files?: string[];\n [key: string]: unknown;\n };\n if (apiTsConfig.files) {\n const validFiles = apiTsConfig.files.filter((f) => existsSync(join(destination, \"api\", f)));\n if (validFiles.length !== apiTsConfig.files.length) {\n if (validFiles.length === 0) {\n delete apiTsConfig.files;\n } else {\n apiTsConfig.files = validFiles;\n }\n writeFileSync(apiTsConfigPath, `${JSON.stringify(apiTsConfig, null, 2)}\\n`);\n }\n }\n }\n\n await resolveWorkspaceRefs(destination, opts.workspaceOpts);\n\n const genContractPath = join(destination, \"ui\", \"src\", \"api-contract.gen.ts\");\n if (!existsSync(genContractPath)) {\n mkdirSync(dirname(genContractPath), { recursive: true });\n writeFileSync(genContractPath, `export type ApiContract = Record<string, never>;\\n`);\n }\n\n const authClientGenPath = join(destination, \"api\", \"src\", \"auth-client.gen.ts\");\n if (!existsSync(authClientGenPath)) {\n mkdirSync(dirname(authClientGenPath), { recursive: true });\n writeFileSync(\n authClientGenPath,\n `import type { ContractRouterClient, AnyContractRouter } from \"@orpc/contract\";\\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\\nexport type AuthClient = ClientFactory<any>;\\n`,\n );\n }\n\n const pluginsClientGenPath = join(destination, \"api\", \"src\", \"plugins-client.gen.ts\");\n if (!existsSync(pluginsClientGenPath)) {\n mkdirSync(dirname(pluginsClientGenPath), { recursive: true });\n writeFileSync(\n pluginsClientGenPath,\n `import type { ContractRouterClient, AnyContractRouter } from \"@orpc/contract\";\\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\\nexport type PluginsClient = Record<string, never>;\\n`,\n );\n }\n}\n\nexport async function runBunInstall(destination: string): Promise<void> {\n await execCommand(\"bun\", [\"install\"], destination);\n}\n\nconst WORKSPACE_LOCAL_PATHS: Record<string, string> = {\n \"everything-dev\": \"packages/everything-dev\",\n \"every-plugin\": \"packages/every-plugin\",\n};\n\nasync function resolveWorkspaceRefs(\n destination: string,\n options?: { localOverrides?: boolean; sourceDir?: string },\n): Promise<void> {\n await normalizePackageManifestsInTree({\n sourceRootDir: options?.sourceDir ?? destination,\n targetDir: destination,\n resolveCatalogRefs: true,\n removeWorkspaceDeps: [\"host\"],\n });\n\n if (options?.localOverrides && options.sourceDir) {\n const rootPkgPath = join(destination, \"package.json\");\n if (existsSync(rootPkgPath)) {\n const pkg = JSON.parse(readFileSync(rootPkgPath, \"utf-8\")) as Record<string, unknown>;\n if (!pkg.overrides) pkg.overrides = {};\n const overrides = pkg.overrides as Record<string, string>;\n\n const rootWorkspaces = ((pkg.workspaces as Record<string, string[]>)?.packages ?? []).filter(\n Boolean,\n );\n\n for (const [name, relPath] of Object.entries(WORKSPACE_LOCAL_PATHS)) {\n if (!rootWorkspaces.some((ws) => ws === relPath || ws === `plugins/${name}`)) {\n const srcPkgPath = join(options.sourceDir, relPath, \"package.json\");\n if (existsSync(srcPkgPath)) {\n overrides[name] = `file:${relPath}`;\n rootWorkspaces.push(relPath);\n }\n }\n }\n\n if (rootWorkspaces.length > 0) {\n if (!pkg.workspaces) pkg.workspaces = {};\n (pkg.workspaces as Record<string, string[]>).packages = rootWorkspaces;\n }\n\n writeFileSync(rootPkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n }\n}\n\nexport async function writeInitSnapshot(\n destination: string,\n extendsAccount: string,\n extendsGateway: string,\n sourceDir: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<void> {\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of effectivePatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch && !(options.plugins?.includes(pluginMatch[1]) ?? true)) continue;\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n allFiles.add(match);\n }\n }\n }\n }\n }\n\n const fileHashes: Record<string, string> = {};\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n const content = readFileSync(src);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n fileHashes[destPath] = computeHash(content);\n }\n\n await writeSnapshot(destination, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: fileHashes,\n });\n}\n\nfunction computeHash(data: Uint8Array): string {\n return createHash(\"sha256\").update(data).digest(\"hex\").substring(0, 16);\n}\n\nfunction mkTmpDir(prefix: string): string {\n const base = join(tmpdir(), prefix);\n let attempt = 0;\n while (true) {\n const dir = `${base}-${Date.now()}-${attempt}`;\n try {\n mkdirSync(dir, { recursive: true });\n return dir;\n } catch {\n attempt++;\n if (attempt > 10) throw new Error(\"Failed to create temp directory\");\n }\n }\n}\n\nfunction execCommand(command: string, args: string[], cwd?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"pipe\",\n shell: true,\n });\n let stderr = \"\";\n child.stderr?.on(\"data\", (data: Buffer) => {\n stderr += data.toString();\n });\n child.on(\"close\", (code) => {\n if (code === 0) resolve();\n else\n reject(\n new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${code}: ${stderr}`,\n ),\n );\n });\n child.on(\"error\", reject);\n });\n}\n"],"mappings":"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"}
|
package/dist/cli/init.d.cts
CHANGED
|
@@ -34,6 +34,7 @@ declare function personalizeConfig(destination: string, opts: {
|
|
|
34
34
|
sourceDir?: string;
|
|
35
35
|
};
|
|
36
36
|
mode?: "init" | "sync";
|
|
37
|
+
withHost?: boolean;
|
|
37
38
|
}): Promise<void>;
|
|
38
39
|
declare function runBunInstall(destination: string): Promise<void>;
|
|
39
40
|
declare function writeInitSnapshot(destination: string, extendsAccount: string, extendsGateway: string, sourceDir: string, patterns: string[], options: {
|
package/dist/cli/init.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.cts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UAwDU,YAAA;EACR,SAAA;EACA,YAAA,EAAc,SAAA;EACd,OAAA,QAAe,OAAA;AAAA;AAAA,iBAGK,gBAAA,CAAiB,IAAA;EACrC,cAAA;EACA,cAAA;EACA,MAAA;AAAA,IACE,OAAA,CAAQ,YAAA;AAAA,iBAsBU,iBAAA,CACpB,cAAA,UACA,cAAA,WACC,OAAA,CAAQ,SAAA;AAAA,iBAKW,eAAA,CACpB,OAAA,WACC,OAAA;EAAU,GAAA;EAAa,OAAA,QAAe,OAAA;AAAA;AAAA,iBAiEnB,gBAAA,CAAiB,SAAA,WAAoB,OAAA;AAAA,iBAarC,iBAAA,CACpB,SAAA,UACA,WAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;EAAmB,OAAA;EAAoB,YAAA,GAAe,MAAA;AAAA,IAChE,OAAA;AAAA,iBAoGmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,cAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,YAAA,GAAe,MAAA;EACf,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;EAC5C,IAAA;AAAA,IAED,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"init.d.cts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UAwDU,YAAA;EACR,SAAA;EACA,YAAA,EAAc,SAAA;EACd,OAAA,QAAe,OAAA;AAAA;AAAA,iBAGK,gBAAA,CAAiB,IAAA;EACrC,cAAA;EACA,cAAA;EACA,MAAA;AAAA,IACE,OAAA,CAAQ,YAAA;AAAA,iBAsBU,iBAAA,CACpB,cAAA,UACA,cAAA,WACC,OAAA,CAAQ,SAAA;AAAA,iBAKW,eAAA,CACpB,OAAA,WACC,OAAA;EAAU,GAAA;EAAa,OAAA,QAAe,OAAA;AAAA;AAAA,iBAiEnB,gBAAA,CAAiB,SAAA,WAAoB,OAAA;AAAA,iBAarC,iBAAA,CACpB,SAAA,UACA,WAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;EAAmB,OAAA;EAAoB,YAAA,GAAe,MAAA;AAAA,IAChE,OAAA;AAAA,iBAoGmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,cAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,YAAA,GAAe,MAAA;EACf,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;EAC5C,IAAA;EACA,QAAA;AAAA,IAED,OAAA;AAAA,iBAuLmB,aAAA,CAAc,WAAA,WAAsB,OAAA;AAAA,iBAmDpC,iBAAA,CACpB,WAAA,UACA,cAAA,UACA,cAAA,UACA,SAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;EAAmB,OAAA;EAAoB,YAAA,GAAe,MAAA;AAAA,IAChE,OAAA"}
|
package/dist/cli/init.d.mts
CHANGED
|
@@ -34,6 +34,7 @@ declare function personalizeConfig(destination: string, opts: {
|
|
|
34
34
|
sourceDir?: string;
|
|
35
35
|
};
|
|
36
36
|
mode?: "init" | "sync";
|
|
37
|
+
withHost?: boolean;
|
|
37
38
|
}): Promise<void>;
|
|
38
39
|
declare function runBunInstall(destination: string): Promise<void>;
|
|
39
40
|
declare function writeInitSnapshot(destination: string, extendsAccount: string, extendsGateway: string, sourceDir: string, patterns: string[], options: {
|
package/dist/cli/init.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.mts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UAwDU,YAAA;EACR,SAAA;EACA,YAAA,EAAc,SAAA;EACd,OAAA,QAAe,OAAA;AAAA;AAAA,iBAGK,gBAAA,CAAiB,IAAA;EACrC,cAAA;EACA,cAAA;EACA,MAAA;AAAA,IACE,OAAA,CAAQ,YAAA;AAAA,iBAsBU,iBAAA,CACpB,cAAA,UACA,cAAA,WACC,OAAA,CAAQ,SAAA;AAAA,iBAKW,eAAA,CACpB,OAAA,WACC,OAAA;EAAU,GAAA;EAAa,OAAA,QAAe,OAAA;AAAA;AAAA,iBAiEnB,gBAAA,CAAiB,SAAA,WAAoB,OAAA;AAAA,iBAarC,iBAAA,CACpB,SAAA,UACA,WAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;EAAmB,OAAA;EAAoB,YAAA,GAAe,MAAA;AAAA,IAChE,OAAA;AAAA,iBAoGmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,cAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,YAAA,GAAe,MAAA;EACf,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;EAC5C,IAAA;AAAA,IAED,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"init.d.mts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UAwDU,YAAA;EACR,SAAA;EACA,YAAA,EAAc,SAAA;EACd,OAAA,QAAe,OAAA;AAAA;AAAA,iBAGK,gBAAA,CAAiB,IAAA;EACrC,cAAA;EACA,cAAA;EACA,MAAA;AAAA,IACE,OAAA,CAAQ,YAAA;AAAA,iBAsBU,iBAAA,CACpB,cAAA,UACA,cAAA,WACC,OAAA,CAAQ,SAAA;AAAA,iBAKW,eAAA,CACpB,OAAA,WACC,OAAA;EAAU,GAAA;EAAa,OAAA,QAAe,OAAA;AAAA;AAAA,iBAiEnB,gBAAA,CAAiB,SAAA,WAAoB,OAAA;AAAA,iBAarC,iBAAA,CACpB,SAAA,UACA,WAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;EAAmB,OAAA;EAAoB,YAAA,GAAe,MAAA;AAAA,IAChE,OAAA;AAAA,iBAoGmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,cAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAA;EACA,YAAA,GAAe,MAAA;EACf,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;EAC5C,IAAA;EACA,QAAA;AAAA,IAED,OAAA;AAAA,iBAuLmB,aAAA,CAAc,WAAA,WAAsB,OAAA;AAAA,iBAmDpC,iBAAA,CACpB,WAAA,UACA,cAAA,UACA,cAAA,UACA,SAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;EAAmB,OAAA;EAAoB,YAAA,GAAe,MAAA;AAAA,IAChE,OAAA"}
|
package/dist/cli/init.mjs
CHANGED
|
@@ -203,6 +203,8 @@ async function personalizeConfig(destination, opts) {
|
|
|
203
203
|
if (opts.domain) config.domain = opts.domain;
|
|
204
204
|
if (isInit && config.app && typeof config.app === "object") {
|
|
205
205
|
const app = config.app;
|
|
206
|
+
const authClientPath = join(destination, "ui", "src", "lib", "auth-client.ts");
|
|
207
|
+
if (existsSync(authClientPath)) writeFileSync(authClientPath, readFileSync(authClientPath, "utf-8").split("\n").filter((line) => !line.includes("inferAdditionalFields") && !line.includes("createAuthInstance")).join("\n"));
|
|
206
208
|
for (const entryKey of Object.keys(app)) {
|
|
207
209
|
const entry = app[entryKey];
|
|
208
210
|
if (entry && typeof entry === "object") {
|
|
@@ -236,10 +238,13 @@ async function personalizeConfig(destination, opts) {
|
|
|
236
238
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
237
239
|
if (pkg.workspaces && typeof pkg.workspaces === "object") {
|
|
238
240
|
const ws = pkg.workspaces;
|
|
239
|
-
if (Array.isArray(ws.packages)) ws.packages = ws.packages.filter((p) =>
|
|
241
|
+
if (Array.isArray(ws.packages)) ws.packages = ws.packages.filter((p) => {
|
|
242
|
+
if (p.startsWith("packages/")) return false;
|
|
243
|
+
if (p === "host") return opts.withHost ?? false;
|
|
244
|
+
if (p === "plugins/*") return (opts.plugins?.length ?? 0) > 0;
|
|
240
245
|
const pluginMatch = p.match(/^plugins\/([^/]+)/);
|
|
241
|
-
if (
|
|
242
|
-
return
|
|
246
|
+
if (pluginMatch) return opts.plugins?.includes(pluginMatch[1]) ?? true;
|
|
247
|
+
return true;
|
|
243
248
|
});
|
|
244
249
|
}
|
|
245
250
|
if (pkg.scripts && typeof pkg.scripts === "object") {
|
|
@@ -255,9 +260,11 @@ async function personalizeConfig(destination, opts) {
|
|
|
255
260
|
rewrite("deploy", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
|
|
256
261
|
rewrite("publish", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
|
|
257
262
|
rewrite("start", "packages/everything-dev/cli.js", "node_modules/.bin/bos");
|
|
258
|
-
if (scripts["sync:api-contract"]) delete scripts["sync:api-contract"];
|
|
259
263
|
if (scripts.postinstall) delete scripts.postinstall;
|
|
260
|
-
if (scripts.typecheck
|
|
264
|
+
if (scripts.typecheck) {
|
|
265
|
+
scripts.typecheck = scripts.typecheck.replace("bun run sync:api-contract && ", "").replace(/bun run --cwd packages\/everything-dev typecheck & ?/, "");
|
|
266
|
+
if (!opts.withHost) scripts.typecheck = scripts.typecheck.replace(/bun run --cwd host tsc --noEmit & ?/, "");
|
|
267
|
+
}
|
|
261
268
|
}
|
|
262
269
|
if (pkg.devDependencies && typeof pkg.devDependencies === "object") {
|
|
263
270
|
const deps = pkg.devDependencies;
|
|
@@ -271,12 +278,34 @@ async function personalizeConfig(destination, opts) {
|
|
|
271
278
|
if (!deps["every-plugin"] && spec) deps["every-plugin"] = spec.rootCatalog["every-plugin"];
|
|
272
279
|
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
273
280
|
}
|
|
281
|
+
const apiTsConfigPath = join(destination, "api", "tsconfig.json");
|
|
282
|
+
if (existsSync(apiTsConfigPath)) {
|
|
283
|
+
const apiTsConfig = JSON.parse(readFileSync(apiTsConfigPath, "utf-8"));
|
|
284
|
+
if (apiTsConfig.files) {
|
|
285
|
+
const validFiles = apiTsConfig.files.filter((f) => existsSync(join(destination, "api", f)));
|
|
286
|
+
if (validFiles.length !== apiTsConfig.files.length) {
|
|
287
|
+
if (validFiles.length === 0) delete apiTsConfig.files;
|
|
288
|
+
else apiTsConfig.files = validFiles;
|
|
289
|
+
writeFileSync(apiTsConfigPath, `${JSON.stringify(apiTsConfig, null, 2)}\n`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
274
293
|
await resolveWorkspaceRefs(destination, opts.workspaceOpts);
|
|
275
294
|
const genContractPath = join(destination, "ui", "src", "api-contract.gen.ts");
|
|
276
295
|
if (!existsSync(genContractPath)) {
|
|
277
296
|
mkdirSync(dirname(genContractPath), { recursive: true });
|
|
278
297
|
writeFileSync(genContractPath, `export type ApiContract = Record<string, never>;\n`);
|
|
279
298
|
}
|
|
299
|
+
const authClientGenPath = join(destination, "api", "src", "auth-client.gen.ts");
|
|
300
|
+
if (!existsSync(authClientGenPath)) {
|
|
301
|
+
mkdirSync(dirname(authClientGenPath), { recursive: true });
|
|
302
|
+
writeFileSync(authClientGenPath, `import type { ContractRouterClient, AnyContractRouter } from "@orpc/contract";\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\nexport type AuthClient = ClientFactory<any>;\n`);
|
|
303
|
+
}
|
|
304
|
+
const pluginsClientGenPath = join(destination, "api", "src", "plugins-client.gen.ts");
|
|
305
|
+
if (!existsSync(pluginsClientGenPath)) {
|
|
306
|
+
mkdirSync(dirname(pluginsClientGenPath), { recursive: true });
|
|
307
|
+
writeFileSync(pluginsClientGenPath, `import type { ContractRouterClient, AnyContractRouter } from "@orpc/contract";\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\nexport type PluginsClient = Record<string, never>;\n`);
|
|
308
|
+
}
|
|
280
309
|
}
|
|
281
310
|
async function runBunInstall(destination) {
|
|
282
311
|
await execCommand("bun", ["install"], destination);
|
package/dist/cli/init.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.mjs","names":[],"sources":["../../src/cli/init.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n createWriteStream,\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { glob } from \"glob\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport {\n loadManifestNormalizationSpec,\n normalizePackageManifestsInTree,\n} from \"../internal/manifest-normalizer\";\nimport type { BosConfig } from \"../types\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst require = createRequire(import.meta.url);\n\nconst BOS_CONFIG_ORDER = [\n \"extends\",\n \"account\",\n \"domain\",\n \"testnet\",\n \"staging\",\n \"repository\",\n \"app\",\n \"plugins\",\n \"shared\",\n];\n\nfunction rebuildOrderedConfig(config: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n\n for (const key of BOS_CONFIG_ORDER) {\n if (key in config) {\n ordered[key] = config[key];\n }\n }\n\n for (const key of Object.keys(config)) {\n if (!BOS_CONFIG_ORDER.includes(key)) {\n ordered[key] = config[key];\n }\n }\n\n return ordered;\n}\n\ninterface SourceResult {\n sourceDir: string;\n parentConfig: BosConfig;\n cleanup: () => Promise<void>;\n}\n\nexport async function resolveSourceDir(opts: {\n extendsAccount: string;\n extendsGateway: string;\n source?: string;\n}): Promise<SourceResult> {\n if (opts.source) {\n const sourceDir = resolve(opts.source);\n if (!existsSync(join(sourceDir, \"bos.config.json\"))) {\n throw new Error(`No bos.config.json found in source directory: ${sourceDir}`);\n }\n const parentConfig = JSON.parse(\n readFileSync(join(sourceDir, \"bos.config.json\"), \"utf-8\"),\n ) as BosConfig;\n return { sourceDir, parentConfig, cleanup: async () => {} };\n }\n\n const parentConfig = await fetchParentConfig(opts.extendsAccount, opts.extendsGateway);\n\n if (!parentConfig.repository) {\n throw new Error(\"Parent config has no repository field — cannot locate template source\");\n }\n\n const { dir: sourceDir, cleanup } = await downloadTarball(parentConfig.repository);\n return { sourceDir, parentConfig, cleanup };\n}\n\nexport async function fetchParentConfig(\n extendsAccount: string,\n extendsGateway: string,\n): Promise<BosConfig> {\n const bosUrl = `bos://${extendsAccount}/${extendsGateway}`;\n return fetchBosConfigFromFastKv<BosConfig>(bosUrl);\n}\n\nexport async function downloadTarball(\n repoUrl: string,\n): Promise<{ dir: string; cleanup: () => Promise<void> }> {\n const parsed = parseGitHubUrl(repoUrl);\n if (!parsed) {\n throw new Error(`Cannot parse repository URL: ${repoUrl}`);\n }\n\n const { owner, repo, branch } = parsed;\n const tarballUrl = `https://api.github.com/repos/${owner}/${repo}/tarball/${branch}`;\n\n const tmpDir = mkTmpDir(\"bos-init-tarball-\");\n const tarballPath = join(tmpDir, \"source.tar.gz\");\n\n const response = await fetch(tarballUrl, {\n headers: { \"User-Agent\": \"everything-dev\" },\n redirect: \"follow\",\n });\n\n if (!response.ok) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(`GitHub tarball download failed: ${response.status} ${response.statusText}`);\n }\n\n if (!response.body) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(\"GitHub tarball download returned empty body\");\n }\n\n const fileStream = createWriteStream(tarballPath);\n const reader = response.body as unknown as NodeJS.ReadableStream;\n await pipeline(reader, fileStream);\n\n const extractDir = mkTmpDir(\"bos-init-extract-\");\n try {\n const tar = require(\"tar\") as {\n extract: (opts: { cwd: string; file: string; strip: number }) => Promise<void>;\n };\n await tar.extract({ cwd: extractDir, file: tarballPath, strip: 1 });\n } catch {\n await execCommand(\"tar\", [\"-xzf\", tarballPath, \"--strip-components=1\", \"-C\", extractDir]);\n }\n\n rmSync(tmpDir, { recursive: true, force: true });\n\n return {\n dir: extractDir,\n cleanup: async () => {\n rmSync(extractDir, { recursive: true, force: true });\n },\n };\n}\n\nfunction parseGitHubUrl(url: string): { owner: string; repo: string; branch: string } | null {\n const httpsMatch = url.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:\\/.*)?$/);\n if (httpsMatch) {\n return { owner: httpsMatch[1], repo: httpsMatch[2], branch: \"main\" };\n }\n\n const sshMatch = url.match(/^git@github\\.com:([^/]+)\\/([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return { owner: sshMatch[1], repo: sshMatch[2], branch: \"main\" };\n }\n\n return null;\n}\n\nexport async function readTemplatekeep(sourceDir: string): Promise<string[]> {\n const keepFile = join(sourceDir, \".templatekeep\");\n if (!existsSync(keepFile)) {\n return [];\n }\n\n const content = readFileSync(keepFile, \"utf-8\");\n return content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nexport async function copyFilteredFiles(\n sourceDir: string,\n destination: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<number> {\n if (patterns.length === 0) {\n return 0;\n }\n\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const filteredPatterns = effectivePatterns.filter((p) => {\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (!pluginMatch) return true;\n const pluginName = pluginMatch[1];\n return options.plugins?.includes(pluginName) ?? true;\n });\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of filteredPatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch) {\n const pluginName = pluginMatch[1];\n if (!(options.plugins?.includes(pluginName) ?? true)) continue;\n }\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n const routeFiles = new Set<string>();\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n routeFiles.add(match);\n }\n }\n }\n }\n }\n\n for (const f of routeFiles) allFiles.add(f);\n\n mkdirSync(destination, { recursive: true });\n\n let count = 0;\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(destination, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nfunction isRouteExcluded(filePath: string, excludedPatterns: string[]): boolean {\n if (excludedPatterns.length === 0) return false;\n for (const pattern of excludedPatterns) {\n if (pattern.endsWith(\"/**\")) {\n const prefix = pattern.slice(0, -3);\n if (filePath.startsWith(`${prefix}/`) || filePath === prefix) return true;\n } else if (filePath === pattern || filePath.startsWith(`${pattern}/`)) {\n return true;\n }\n }\n return false;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n extendsAccount: string;\n extendsGateway: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n pluginRoutes?: Record<string, string[]>;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n mode?: \"init\" | \"sync\";\n },\n): Promise<void> {\n const isInit = opts.mode !== \"sync\";\n const configPath = join(destination, \"bos.config.json\");\n if (existsSync(configPath)) {\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n config.extends = `bos://${opts.extendsAccount}/${opts.extendsGateway}`;\n\n if (opts.account) {\n config.account = opts.account;\n }\n if (opts.domain) {\n config.domain = opts.domain;\n }\n\n if (isInit && config.app && typeof config.app === \"object\") {\n const app = config.app as Record<string, unknown>;\n for (const entryKey of Object.keys(app)) {\n const entry = app[entryKey];\n if (entry && typeof entry === \"object\") {\n const e = entry as Record<string, unknown>;\n delete e.production;\n delete e.integrity;\n delete e.ssr;\n delete e.ssrIntegrity;\n }\n }\n }\n\n if (config.plugins && typeof config.plugins === \"object\") {\n const plugins = config.plugins as Record<string, unknown>;\n\n if (opts.plugins && opts.plugins.length > 0) {\n for (const pluginKey of Object.keys(plugins)) {\n if (!opts.plugins.includes(pluginKey)) {\n delete plugins[pluginKey];\n }\n }\n }\n\n if (isInit) {\n for (const pluginKey of Object.keys(plugins)) {\n const plugin = plugins[pluginKey];\n if (plugin && typeof plugin === \"object\") {\n const p = plugin as Record<string, unknown>;\n delete p.production;\n delete p.integrity;\n }\n }\n }\n\n if (Object.keys(plugins).length === 0) {\n config.plugins = {};\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(rebuildOrderedConfig(config), null, 2)}\\n`);\n }\n\n const pkgPath = join(destination, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const ws = pkg.workspaces as { packages?: string[] };\n if (Array.isArray(ws.packages)) {\n ws.packages = ws.packages\n .filter((p: string) => p !== \"host\" && !p.startsWith(\"packages/\"))\n .filter((p: string) => {\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (!pluginMatch) return true;\n return opts.plugins?.includes(pluginMatch[1]) ?? true;\n });\n }\n }\n\n if (pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n const rewrite = (key: string, from: string, to: string) => {\n if (scripts[key]?.includes(from)) {\n scripts[key] = scripts[key].replaceAll(from, to);\n }\n };\n rewrite(\"dev\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:ui\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:api\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:proxy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"build\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"deploy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"publish\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"start\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n\n if (scripts[\"sync:api-contract\"]) {\n delete scripts[\"sync:api-contract\"];\n }\n if (scripts.postinstall) {\n delete scripts.postinstall;\n }\n if (scripts.typecheck?.includes(\"sync:api-contract\")) {\n scripts.typecheck = scripts.typecheck.replace(\"bun run sync:api-contract && \", \"\");\n }\n }\n\n if (pkg.devDependencies && typeof pkg.devDependencies === \"object\") {\n const deps = pkg.devDependencies as Record<string, string>;\n delete deps[\"every-plugin\"];\n delete deps[\"everything-dev\"];\n }\n\n if (!pkg.dependencies) pkg.dependencies = {};\n const deps = pkg.dependencies as Record<string, string>;\n const spec = opts.workspaceOpts?.sourceDir\n ? loadManifestNormalizationSpec(opts.workspaceOpts.sourceDir)\n : null;\n if (!deps[\"everything-dev\"] && spec)\n deps[\"everything-dev\"] = spec.rootCatalog[\"everything-dev\"];\n if (!deps[\"every-plugin\"] && spec) deps[\"every-plugin\"] = spec.rootCatalog[\"every-plugin\"];\n\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n await resolveWorkspaceRefs(destination, opts.workspaceOpts);\n\n const genContractPath = join(destination, \"ui\", \"src\", \"api-contract.gen.ts\");\n if (!existsSync(genContractPath)) {\n mkdirSync(dirname(genContractPath), { recursive: true });\n writeFileSync(genContractPath, `export type ApiContract = Record<string, never>;\\n`);\n }\n}\n\nexport async function runBunInstall(destination: string): Promise<void> {\n await execCommand(\"bun\", [\"install\"], destination);\n}\n\nconst WORKSPACE_LOCAL_PATHS: Record<string, string> = {\n \"everything-dev\": \"packages/everything-dev\",\n \"every-plugin\": \"packages/every-plugin\",\n};\n\nasync function resolveWorkspaceRefs(\n destination: string,\n options?: { localOverrides?: boolean; sourceDir?: string },\n): Promise<void> {\n await normalizePackageManifestsInTree({\n sourceRootDir: options?.sourceDir ?? destination,\n targetDir: destination,\n resolveCatalogRefs: true,\n removeWorkspaceDeps: [\"host\"],\n });\n\n if (options?.localOverrides && options.sourceDir) {\n const rootPkgPath = join(destination, \"package.json\");\n if (existsSync(rootPkgPath)) {\n const pkg = JSON.parse(readFileSync(rootPkgPath, \"utf-8\")) as Record<string, unknown>;\n if (!pkg.overrides) pkg.overrides = {};\n const overrides = pkg.overrides as Record<string, string>;\n\n const rootWorkspaces = ((pkg.workspaces as Record<string, string[]>)?.packages ?? []).filter(\n Boolean,\n );\n\n for (const [name, relPath] of Object.entries(WORKSPACE_LOCAL_PATHS)) {\n if (!rootWorkspaces.some((ws) => ws === relPath || ws === `plugins/${name}`)) {\n const srcPkgPath = join(options.sourceDir, relPath, \"package.json\");\n if (existsSync(srcPkgPath)) {\n overrides[name] = `file:${relPath}`;\n rootWorkspaces.push(relPath);\n }\n }\n }\n\n if (rootWorkspaces.length > 0) {\n if (!pkg.workspaces) pkg.workspaces = {};\n (pkg.workspaces as Record<string, string[]>).packages = rootWorkspaces;\n }\n\n writeFileSync(rootPkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n }\n}\n\nexport async function writeInitSnapshot(\n destination: string,\n extendsAccount: string,\n extendsGateway: string,\n sourceDir: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<void> {\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of effectivePatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch && !(options.plugins?.includes(pluginMatch[1]) ?? true)) continue;\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n allFiles.add(match);\n }\n }\n }\n }\n }\n\n const fileHashes: Record<string, string> = {};\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n const content = readFileSync(src);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n fileHashes[destPath] = computeHash(content);\n }\n\n await writeSnapshot(destination, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: fileHashes,\n });\n}\n\nfunction computeHash(data: Uint8Array): string {\n return createHash(\"sha256\").update(data).digest(\"hex\").substring(0, 16);\n}\n\nfunction mkTmpDir(prefix: string): string {\n const base = join(tmpdir(), prefix);\n let attempt = 0;\n while (true) {\n const dir = `${base}-${Date.now()}-${attempt}`;\n try {\n mkdirSync(dir, { recursive: true });\n return dir;\n } catch {\n attempt++;\n if (attempt > 10) throw new Error(\"Failed to create temp directory\");\n }\n }\n}\n\nfunction execCommand(command: string, args: string[], cwd?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"pipe\",\n shell: true,\n });\n let stderr = \"\";\n child.stderr?.on(\"data\", (data: Buffer) => {\n stderr += data.toString();\n });\n child.on(\"close\", (code) => {\n if (code === 0) resolve();\n else\n reject(\n new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${code}: ${stderr}`,\n ),\n );\n });\n child.on(\"error\", reject);\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"init.mjs","names":[],"sources":["../../src/cli/init.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n createWriteStream,\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { pipeline } from \"node:stream/promises\";\nimport { glob } from \"glob\";\nimport { fetchBosConfigFromFastKv } from \"../fastkv\";\nimport {\n loadManifestNormalizationSpec,\n normalizePackageManifestsInTree,\n} from \"../internal/manifest-normalizer\";\nimport type { BosConfig } from \"../types\";\nimport { writeSnapshot } from \"./snapshot\";\n\nconst require = createRequire(import.meta.url);\n\nconst BOS_CONFIG_ORDER = [\n \"extends\",\n \"account\",\n \"domain\",\n \"testnet\",\n \"staging\",\n \"repository\",\n \"app\",\n \"plugins\",\n \"shared\",\n];\n\nfunction rebuildOrderedConfig(config: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n\n for (const key of BOS_CONFIG_ORDER) {\n if (key in config) {\n ordered[key] = config[key];\n }\n }\n\n for (const key of Object.keys(config)) {\n if (!BOS_CONFIG_ORDER.includes(key)) {\n ordered[key] = config[key];\n }\n }\n\n return ordered;\n}\n\ninterface SourceResult {\n sourceDir: string;\n parentConfig: BosConfig;\n cleanup: () => Promise<void>;\n}\n\nexport async function resolveSourceDir(opts: {\n extendsAccount: string;\n extendsGateway: string;\n source?: string;\n}): Promise<SourceResult> {\n if (opts.source) {\n const sourceDir = resolve(opts.source);\n if (!existsSync(join(sourceDir, \"bos.config.json\"))) {\n throw new Error(`No bos.config.json found in source directory: ${sourceDir}`);\n }\n const parentConfig = JSON.parse(\n readFileSync(join(sourceDir, \"bos.config.json\"), \"utf-8\"),\n ) as BosConfig;\n return { sourceDir, parentConfig, cleanup: async () => {} };\n }\n\n const parentConfig = await fetchParentConfig(opts.extendsAccount, opts.extendsGateway);\n\n if (!parentConfig.repository) {\n throw new Error(\"Parent config has no repository field — cannot locate template source\");\n }\n\n const { dir: sourceDir, cleanup } = await downloadTarball(parentConfig.repository);\n return { sourceDir, parentConfig, cleanup };\n}\n\nexport async function fetchParentConfig(\n extendsAccount: string,\n extendsGateway: string,\n): Promise<BosConfig> {\n const bosUrl = `bos://${extendsAccount}/${extendsGateway}`;\n return fetchBosConfigFromFastKv<BosConfig>(bosUrl);\n}\n\nexport async function downloadTarball(\n repoUrl: string,\n): Promise<{ dir: string; cleanup: () => Promise<void> }> {\n const parsed = parseGitHubUrl(repoUrl);\n if (!parsed) {\n throw new Error(`Cannot parse repository URL: ${repoUrl}`);\n }\n\n const { owner, repo, branch } = parsed;\n const tarballUrl = `https://api.github.com/repos/${owner}/${repo}/tarball/${branch}`;\n\n const tmpDir = mkTmpDir(\"bos-init-tarball-\");\n const tarballPath = join(tmpDir, \"source.tar.gz\");\n\n const response = await fetch(tarballUrl, {\n headers: { \"User-Agent\": \"everything-dev\" },\n redirect: \"follow\",\n });\n\n if (!response.ok) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(`GitHub tarball download failed: ${response.status} ${response.statusText}`);\n }\n\n if (!response.body) {\n rmSync(tmpDir, { recursive: true, force: true });\n throw new Error(\"GitHub tarball download returned empty body\");\n }\n\n const fileStream = createWriteStream(tarballPath);\n const reader = response.body as unknown as NodeJS.ReadableStream;\n await pipeline(reader, fileStream);\n\n const extractDir = mkTmpDir(\"bos-init-extract-\");\n try {\n const tar = require(\"tar\") as {\n extract: (opts: { cwd: string; file: string; strip: number }) => Promise<void>;\n };\n await tar.extract({ cwd: extractDir, file: tarballPath, strip: 1 });\n } catch {\n await execCommand(\"tar\", [\"-xzf\", tarballPath, \"--strip-components=1\", \"-C\", extractDir]);\n }\n\n rmSync(tmpDir, { recursive: true, force: true });\n\n return {\n dir: extractDir,\n cleanup: async () => {\n rmSync(extractDir, { recursive: true, force: true });\n },\n };\n}\n\nfunction parseGitHubUrl(url: string): { owner: string; repo: string; branch: string } | null {\n const httpsMatch = url.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?(?:\\/.*)?$/);\n if (httpsMatch) {\n return { owner: httpsMatch[1], repo: httpsMatch[2], branch: \"main\" };\n }\n\n const sshMatch = url.match(/^git@github\\.com:([^/]+)\\/([^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return { owner: sshMatch[1], repo: sshMatch[2], branch: \"main\" };\n }\n\n return null;\n}\n\nexport async function readTemplatekeep(sourceDir: string): Promise<string[]> {\n const keepFile = join(sourceDir, \".templatekeep\");\n if (!existsSync(keepFile)) {\n return [];\n }\n\n const content = readFileSync(keepFile, \"utf-8\");\n return content\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"));\n}\n\nexport async function copyFilteredFiles(\n sourceDir: string,\n destination: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<number> {\n if (patterns.length === 0) {\n return 0;\n }\n\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const filteredPatterns = effectivePatterns.filter((p) => {\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (!pluginMatch) return true;\n const pluginName = pluginMatch[1];\n return options.plugins?.includes(pluginName) ?? true;\n });\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of filteredPatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch) {\n const pluginName = pluginMatch[1];\n if (!(options.plugins?.includes(pluginName) ?? true)) continue;\n }\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n const routeFiles = new Set<string>();\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n routeFiles.add(match);\n }\n }\n }\n }\n }\n\n for (const f of routeFiles) allFiles.add(f);\n\n mkdirSync(destination, { recursive: true });\n\n let count = 0;\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n const dest = join(destination, destPath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nfunction isRouteExcluded(filePath: string, excludedPatterns: string[]): boolean {\n if (excludedPatterns.length === 0) return false;\n for (const pattern of excludedPatterns) {\n if (pattern.endsWith(\"/**\")) {\n const prefix = pattern.slice(0, -3);\n if (filePath.startsWith(`${prefix}/`) || filePath === prefix) return true;\n } else if (filePath === pattern || filePath.startsWith(`${pattern}/`)) {\n return true;\n }\n }\n return false;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n extendsAccount: string;\n extendsGateway: string;\n account?: string;\n domain?: string;\n plugins?: string[];\n pluginRoutes?: Record<string, string[]>;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n mode?: \"init\" | \"sync\";\n withHost?: boolean;\n },\n): Promise<void> {\n const isInit = opts.mode !== \"sync\";\n const configPath = join(destination, \"bos.config.json\");\n if (existsSync(configPath)) {\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as Record<string, unknown>;\n\n config.extends = `bos://${opts.extendsAccount}/${opts.extendsGateway}`;\n\n if (opts.account) {\n config.account = opts.account;\n }\n if (opts.domain) {\n config.domain = opts.domain;\n }\n\n if (isInit && config.app && typeof config.app === \"object\") {\n const app = config.app as Record<string, unknown>;\n\n const authClientPath = join(destination, \"ui\", \"src\", \"lib\", \"auth-client.ts\");\n if (existsSync(authClientPath)) {\n const authClientContent = readFileSync(authClientPath, \"utf-8\")\n .split(\"\\n\")\n .filter(\n (line) =>\n !line.includes(\"inferAdditionalFields\") && !line.includes(\"createAuthInstance\"),\n )\n .join(\"\\n\");\n writeFileSync(authClientPath, authClientContent);\n }\n\n for (const entryKey of Object.keys(app)) {\n const entry = app[entryKey];\n if (entry && typeof entry === \"object\") {\n const e = entry as Record<string, unknown>;\n delete e.production;\n delete e.integrity;\n delete e.ssr;\n delete e.ssrIntegrity;\n }\n }\n }\n\n if (config.plugins && typeof config.plugins === \"object\") {\n const plugins = config.plugins as Record<string, unknown>;\n\n if (opts.plugins && opts.plugins.length > 0) {\n for (const pluginKey of Object.keys(plugins)) {\n if (!opts.plugins.includes(pluginKey)) {\n delete plugins[pluginKey];\n }\n }\n }\n\n if (isInit) {\n for (const pluginKey of Object.keys(plugins)) {\n const plugin = plugins[pluginKey];\n if (plugin && typeof plugin === \"object\") {\n const p = plugin as Record<string, unknown>;\n delete p.production;\n delete p.integrity;\n }\n }\n }\n\n if (Object.keys(plugins).length === 0) {\n config.plugins = {};\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(rebuildOrderedConfig(config), null, 2)}\\n`);\n }\n\n const pkgPath = join(destination, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<string, unknown>;\n\n if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n const ws = pkg.workspaces as { packages?: string[] };\n if (Array.isArray(ws.packages)) {\n ws.packages = ws.packages.filter((p: string) => {\n if (p.startsWith(\"packages/\")) return false;\n if (p === \"host\") return opts.withHost ?? false;\n if (p === \"plugins/*\") return (opts.plugins?.length ?? 0) > 0;\n const pluginMatch = p.match(/^plugins\\/([^/]+)/);\n if (pluginMatch) return opts.plugins?.includes(pluginMatch[1]) ?? true;\n return true;\n });\n }\n }\n\n if (pkg.scripts && typeof pkg.scripts === \"object\") {\n const scripts = pkg.scripts as Record<string, string>;\n const rewrite = (key: string, from: string, to: string) => {\n if (scripts[key]?.includes(from)) {\n scripts[key] = scripts[key].replaceAll(from, to);\n }\n };\n rewrite(\"dev\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:ui\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:api\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"dev:proxy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"build\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"deploy\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"publish\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n rewrite(\"start\", \"packages/everything-dev/cli.js\", \"node_modules/.bin/bos\");\n\n if (scripts.postinstall) {\n delete scripts.postinstall;\n }\n if (scripts.typecheck) {\n scripts.typecheck = scripts.typecheck\n .replace(\"bun run sync:api-contract && \", \"\")\n .replace(/bun run --cwd packages\\/everything-dev typecheck & ?/, \"\");\n if (!opts.withHost) {\n scripts.typecheck = scripts.typecheck.replace(/bun run --cwd host tsc --noEmit & ?/, \"\");\n }\n }\n }\n\n if (pkg.devDependencies && typeof pkg.devDependencies === \"object\") {\n const deps = pkg.devDependencies as Record<string, string>;\n delete deps[\"every-plugin\"];\n delete deps[\"everything-dev\"];\n }\n\n if (!pkg.dependencies) pkg.dependencies = {};\n const deps = pkg.dependencies as Record<string, string>;\n const spec = opts.workspaceOpts?.sourceDir\n ? loadManifestNormalizationSpec(opts.workspaceOpts.sourceDir)\n : null;\n if (!deps[\"everything-dev\"] && spec)\n deps[\"everything-dev\"] = spec.rootCatalog[\"everything-dev\"];\n if (!deps[\"every-plugin\"] && spec) deps[\"every-plugin\"] = spec.rootCatalog[\"every-plugin\"];\n\n writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n\n const apiTsConfigPath = join(destination, \"api\", \"tsconfig.json\");\n if (existsSync(apiTsConfigPath)) {\n const apiTsConfig = JSON.parse(readFileSync(apiTsConfigPath, \"utf-8\")) as {\n files?: string[];\n [key: string]: unknown;\n };\n if (apiTsConfig.files) {\n const validFiles = apiTsConfig.files.filter((f) => existsSync(join(destination, \"api\", f)));\n if (validFiles.length !== apiTsConfig.files.length) {\n if (validFiles.length === 0) {\n delete apiTsConfig.files;\n } else {\n apiTsConfig.files = validFiles;\n }\n writeFileSync(apiTsConfigPath, `${JSON.stringify(apiTsConfig, null, 2)}\\n`);\n }\n }\n }\n\n await resolveWorkspaceRefs(destination, opts.workspaceOpts);\n\n const genContractPath = join(destination, \"ui\", \"src\", \"api-contract.gen.ts\");\n if (!existsSync(genContractPath)) {\n mkdirSync(dirname(genContractPath), { recursive: true });\n writeFileSync(genContractPath, `export type ApiContract = Record<string, never>;\\n`);\n }\n\n const authClientGenPath = join(destination, \"api\", \"src\", \"auth-client.gen.ts\");\n if (!existsSync(authClientGenPath)) {\n mkdirSync(dirname(authClientGenPath), { recursive: true });\n writeFileSync(\n authClientGenPath,\n `import type { ContractRouterClient, AnyContractRouter } from \"@orpc/contract\";\\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\\nexport type AuthClient = ClientFactory<any>;\\n`,\n );\n }\n\n const pluginsClientGenPath = join(destination, \"api\", \"src\", \"plugins-client.gen.ts\");\n if (!existsSync(pluginsClientGenPath)) {\n mkdirSync(dirname(pluginsClientGenPath), { recursive: true });\n writeFileSync(\n pluginsClientGenPath,\n `import type { ContractRouterClient, AnyContractRouter } from \"@orpc/contract\";\\ntype ClientFactory<C extends AnyContractRouter> = (context?: Record<string, unknown>) => ContractRouterClient<C>;\\nexport type PluginsClient = Record<string, never>;\\n`,\n );\n }\n}\n\nexport async function runBunInstall(destination: string): Promise<void> {\n await execCommand(\"bun\", [\"install\"], destination);\n}\n\nconst WORKSPACE_LOCAL_PATHS: Record<string, string> = {\n \"everything-dev\": \"packages/everything-dev\",\n \"every-plugin\": \"packages/every-plugin\",\n};\n\nasync function resolveWorkspaceRefs(\n destination: string,\n options?: { localOverrides?: boolean; sourceDir?: string },\n): Promise<void> {\n await normalizePackageManifestsInTree({\n sourceRootDir: options?.sourceDir ?? destination,\n targetDir: destination,\n resolveCatalogRefs: true,\n removeWorkspaceDeps: [\"host\"],\n });\n\n if (options?.localOverrides && options.sourceDir) {\n const rootPkgPath = join(destination, \"package.json\");\n if (existsSync(rootPkgPath)) {\n const pkg = JSON.parse(readFileSync(rootPkgPath, \"utf-8\")) as Record<string, unknown>;\n if (!pkg.overrides) pkg.overrides = {};\n const overrides = pkg.overrides as Record<string, string>;\n\n const rootWorkspaces = ((pkg.workspaces as Record<string, string[]>)?.packages ?? []).filter(\n Boolean,\n );\n\n for (const [name, relPath] of Object.entries(WORKSPACE_LOCAL_PATHS)) {\n if (!rootWorkspaces.some((ws) => ws === relPath || ws === `plugins/${name}`)) {\n const srcPkgPath = join(options.sourceDir, relPath, \"package.json\");\n if (existsSync(srcPkgPath)) {\n overrides[name] = `file:${relPath}`;\n rootWorkspaces.push(relPath);\n }\n }\n }\n\n if (rootWorkspaces.length > 0) {\n if (!pkg.workspaces) pkg.workspaces = {};\n (pkg.workspaces as Record<string, string[]>).packages = rootWorkspaces;\n }\n\n writeFileSync(rootPkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n }\n }\n}\n\nexport async function writeInitSnapshot(\n destination: string,\n extendsAccount: string,\n extendsGateway: string,\n sourceDir: string,\n patterns: string[],\n options: { withHost: boolean; plugins?: string[]; pluginRoutes?: Record<string, string[]> },\n): Promise<void> {\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\n\n const excludedRoutePatterns: string[] = [];\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) {\n excludedRoutePatterns.push(...routePatterns);\n }\n }\n }\n\n const allFiles = new Set<string>();\n for (const pattern of effectivePatterns) {\n const matches = await glob(pattern, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n const pluginMatch = match.match(/^plugins\\/([^/]+)/);\n if (pluginMatch && !(options.plugins?.includes(pluginMatch[1]) ?? true)) continue;\n if (isRouteExcluded(match, excludedRoutePatterns)) continue;\n allFiles.add(match);\n }\n }\n\n if (options.pluginRoutes) {\n for (const [pluginKey, routePatterns] of Object.entries(options.pluginRoutes)) {\n if (!(options.plugins?.includes(pluginKey) ?? true)) continue;\n for (const rp of routePatterns) {\n const matches = await glob(rp, {\n cwd: sourceDir,\n nodir: true,\n dot: true,\n absolute: false,\n });\n for (const match of matches) {\n if (!isRouteExcluded(match, excludedRoutePatterns)) {\n allFiles.add(match);\n }\n }\n }\n }\n }\n\n const fileHashes: Record<string, string> = {};\n for (const filePath of allFiles) {\n const src = join(sourceDir, filePath);\n const stat = lstatSync(src);\n if (!stat.isFile()) continue;\n const content = readFileSync(src);\n const destPath = filePath.startsWith(\".github/templates/\")\n ? filePath.replace(/^\\.github\\/templates\\//, \".github/\")\n : filePath;\n fileHashes[destPath] = computeHash(content);\n }\n\n await writeSnapshot(destination, {\n parentRef: `bos://${extendsAccount}/${extendsGateway}`,\n files: fileHashes,\n });\n}\n\nfunction computeHash(data: Uint8Array): string {\n return createHash(\"sha256\").update(data).digest(\"hex\").substring(0, 16);\n}\n\nfunction mkTmpDir(prefix: string): string {\n const base = join(tmpdir(), prefix);\n let attempt = 0;\n while (true) {\n const dir = `${base}-${Date.now()}-${attempt}`;\n try {\n mkdirSync(dir, { recursive: true });\n return dir;\n } catch {\n attempt++;\n if (attempt > 10) throw new Error(\"Failed to create temp directory\");\n }\n }\n}\n\nfunction execCommand(command: string, args: string[], cwd?: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"pipe\",\n shell: true,\n });\n let stderr = \"\";\n child.stderr?.on(\"data\", (data: Buffer) => {\n stderr += data.toString();\n });\n child.on(\"close\", (code) => {\n if (code === 0) resolve();\n else\n reject(\n new Error(\n `Command '${command} ${args.join(\" \")}' failed with exit code ${code}: ${stderr}`,\n ),\n );\n });\n child.on(\"error\", reject);\n });\n}\n"],"mappings":"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"}
|
package/dist/dev-session.cjs
CHANGED
|
@@ -104,7 +104,7 @@ const runDevSession = (orchestrator, onShutdownReady) => effect.Effect.gen(funct
|
|
|
104
104
|
})));
|
|
105
105
|
};
|
|
106
106
|
const startGroup = (packages) => effect.Effect.forEach(packages, startProcess, { concurrency: "unbounded" });
|
|
107
|
-
const awaitReady = (
|
|
107
|
+
const awaitReady = (_pkg, handle) => handle.waitForReady.pipe(effect.Effect.catchAll(() => effect.Effect.void));
|
|
108
108
|
const nonHostPackages = orderedPackages.filter((pkg) => pkg !== "host");
|
|
109
109
|
const hostPackages = orderedPackages.filter((pkg) => pkg === "host");
|
|
110
110
|
const nonHostHandles = yield* startGroup(nonHostPackages);
|
|
@@ -150,12 +150,9 @@ const runApp = (orchestrator, services, runtimeConfig) => {
|
|
|
150
150
|
};
|
|
151
151
|
const program = effect.Effect.scoped(runDevSession(orchestrator, (shutdown) => {
|
|
152
152
|
requestShutdown = shutdown;
|
|
153
|
-
})).pipe(effect.Effect.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (e.stack) console.error(e.stack);
|
|
157
|
-
} else console.error("App error:", e);
|
|
158
|
-
})), effect.Effect.provide(require_service_descriptor.ServiceDescriptorMapLive(services)), effect.Effect.provide(require_service_descriptor.DevRuntimeConfigLive(runtimeConfig)), effect.Effect.provide(_effect_platform_node.NodeContext.layer));
|
|
153
|
+
})).pipe(effect.Effect.provide(require_service_descriptor.ServiceDescriptorMapLive(services)), effect.Effect.provide(require_service_descriptor.DevRuntimeConfigLive(runtimeConfig)), effect.Effect.provide(_effect_platform_node.NodeContext.layer), effect.Effect.catchAllDefect((defect) => effect.Effect.sync(() => {
|
|
154
|
+
console.error("[Dev] Unhandled defect in orchestrator:", defect);
|
|
155
|
+
})));
|
|
159
156
|
const handleSignal = () => {
|
|
160
157
|
signalCount++;
|
|
161
158
|
if (signalCount > 1) {
|
package/dist/dev-session.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-session.cjs","names":["Effect","getProjectRoot","ServiceDescriptorMap","getProcessStates","createDevLogger","Deferred","renderDevView","renderStreamingView","makeDevProcess","ServiceDescriptorMapLive","DevRuntimeConfigLive","NodeContext","Exit"],"sources":["../src/dev-session.ts"],"sourcesContent":["import { NodeContext } from \"@effect/platform-node\";\nimport { Deferred, Effect, Exit } from \"effect\";\nimport {\n type DevViewHandle,\n type LogEntry,\n type ProcessState,\n renderDevView,\n} from \"./components/dev-view\";\nimport { renderStreamingView } from \"./components/streaming-view\";\nimport { getProjectRoot } from \"./config\";\nimport { createDevLogger } from \"./dev-logs\";\nimport {\n getProcessStates,\n makeDevProcess,\n type ProcessCallbacks,\n type ProcessHandle,\n} from \"./orchestrator\";\nimport {\n type AppOrchestrator,\n DevRuntimeConfigLive,\n type ServiceDescriptor,\n ServiceDescriptorMap,\n ServiceDescriptorMapLive,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\n\nconst LOG_NOISE_PATTERNS = [\n /\\[ Federation Runtime \\] Version .* from (host|ui) of shared singleton module/,\n /Executing an Effect versioned \\d+\\.\\d+\\.\\d+ with a Runtime of version/,\n /you may want to dedupe the effect dependencies/,\n];\n\nconst SSR_LOG_ALLOWLIST = [\n /\\bready\\s+built in\\b/i,\n /\\bcompiled\\b.*successfully/i,\n /\\berror\\b/i,\n /\\bfailed\\b/i,\n /\\bexception\\b/i,\n];\n\nconst shouldDisplayLog = (source: string, line: string, isError?: boolean): boolean => {\n if (process.env.DEBUG === \"true\" || process.env.DEBUG === \"1\") return true;\n if (source === \"ui-ssr\") {\n if (isError) return true;\n return SSR_LOG_ALLOWLIST.some((pattern) => pattern.test(line));\n }\n return !LOG_NOISE_PATTERNS.some((pattern) => pattern.test(line));\n};\n\nconst isInteractiveSupported = (): boolean => {\n return process.stdin.isTTY === true && process.stdout.isTTY === true;\n};\n\nconst STARTUP_ORDER = [\"ui-ssr\", \"ui\", \"auth\", \"api\", \"plugin\", \"host-build\", \"host\"];\n\nconst sortByOrder = (packages: string[]): string[] => {\n return [...packages].sort((a, b) => {\n const aIdx = a.startsWith(\"plugin:\")\n ? STARTUP_ORDER.indexOf(\"plugin\")\n : STARTUP_ORDER.indexOf(a);\n const bIdx = b.startsWith(\"plugin:\")\n ? STARTUP_ORDER.indexOf(\"plugin\")\n : STARTUP_ORDER.indexOf(b);\n if (aIdx === -1 && bIdx === -1) return 0;\n if (aIdx === -1) return 1;\n if (bIdx === -1) return -1;\n return aIdx - bIdx;\n });\n};\n\nfunction formatLogLine(entry: LogEntry): string {\n const ts = new Date(entry.timestamp).toISOString();\n const prefix = entry.isError ? \"ERR\" : \"OUT\";\n return `[${ts}] [${entry.source}] [${prefix}] ${entry.line}`;\n}\n\nexport const runDevSession = (\n orchestrator: AppOrchestrator,\n onShutdownReady?: (requestShutdown: () => void) => void,\n) =>\n Effect.gen(function* () {\n const configDir = getProjectRoot();\n const services = yield* ServiceDescriptorMap;\n const orderedPackages = sortByOrder(orchestrator.packages);\n const initialProcesses: ProcessState[] = getProcessStates(\n orderedPackages,\n services,\n orchestrator.port,\n );\n\n const logger = yield* Effect.promise(() =>\n createDevLogger(configDir, orchestrator.description),\n );\n\n const shutdown = yield* Deferred.make<void>();\n\n onShutdownReady?.(() => {\n void Effect.runPromise(Deferred.succeed(shutdown, undefined));\n });\n\n const allLogs: LogEntry[] = [];\n let view: DevViewHandle | null = null;\n let shouldExportLogs = false;\n\n const requestShutdownAndExport = () => {\n shouldExportLogs = true;\n void Effect.runPromise(Deferred.succeed(shutdown, undefined));\n };\n\n const useInteractive = orchestrator.interactive ?? isInteractiveSupported();\n view = useInteractive\n ? renderDevView(\n initialProcesses,\n orchestrator.description,\n orchestrator.env,\n () => void Effect.runPromise(Deferred.succeed(shutdown, undefined)),\n requestShutdownAndExport,\n )\n : renderStreamingView(\n initialProcesses,\n orchestrator.description,\n orchestrator.env,\n () => void Effect.runPromise(Deferred.succeed(shutdown, undefined)),\n );\n\n const callbacks: ProcessCallbacks = {\n onStatus: (name, status, message) => {\n view?.updateProcess(name, status, message);\n },\n onLog: (name, line, isError) => {\n const entry: LogEntry = {\n id: `${Date.now()}-${allLogs.length + 1}`,\n source: name,\n line,\n timestamp: Date.now(),\n isError,\n };\n allLogs.push(entry);\n if (shouldDisplayLog(name, line, isError)) {\n view?.addLog(name, line, isError);\n }\n if (!orchestrator.noLogs) {\n void logger.write(entry);\n }\n },\n };\n\n const startProcess = (pkg: string) => {\n const portOverride = pkg === \"host\" ? orchestrator.port : undefined;\n return makeDevProcess(pkg, callbacks, portOverride).pipe(\n Effect.tapError((err) =>\n Effect.sync(() => {\n callbacks.onLog(pkg, `Failed to start: ${err}`, true);\n callbacks.onStatus(pkg, \"error\");\n }),\n ),\n Effect.catchAll(() =>\n Effect.succeed({\n name: pkg,\n pid: undefined,\n kill: Effect.void,\n waitForReady: Effect.void,\n waitForExit: Effect.never,\n } satisfies ProcessHandle),\n ),\n );\n };\n\n const startGroup = (packages: string[]) =>\n Effect.forEach(packages, startProcess, { concurrency: \"unbounded\" });\n\n const awaitReady = (pkg: string, handle: ProcessHandle) => handle.waitForReady;\n\n const nonHostPackages = orderedPackages.filter((pkg) => pkg !== \"host\");\n const hostPackages = orderedPackages.filter((pkg) => pkg === \"host\");\n\n const nonHostHandles = yield* startGroup(nonHostPackages);\n\n yield* Effect.forEach(\n nonHostHandles.map((handle, index) => ({\n handle,\n pkg: nonHostPackages[index] ?? handle.name,\n })),\n ({ handle, pkg }) => awaitReady(pkg, handle),\n { concurrency: \"unbounded\" },\n );\n\n const hostHandles = yield* startGroup(hostPackages);\n\n yield* Effect.forEach(\n hostHandles.map((handle, index) => ({ handle, pkg: hostPackages[index] ?? handle.name })),\n ({ handle, pkg }) => awaitReady(pkg, handle),\n { concurrency: \"unbounded\" },\n );\n\n const allHandles = [...nonHostHandles, ...hostHandles];\n\n yield* Effect.addFinalizer(() =>\n Effect.gen(function* () {\n yield* Effect.forEach(allHandles, (h) => h.kill.pipe(Effect.ignore), {\n concurrency: \"unbounded\",\n });\n\n yield* Effect.sleep(\"200 millis\");\n\n view?.unmount();\n\n if (shouldExportLogs) {\n console.log(\"\\n\");\n console.log(\"═\".repeat(70));\n console.log(` SESSION LOGS: ${orchestrator.description}`);\n console.log(` Started: ${new Date(allLogs[0]?.timestamp || Date.now()).toISOString()}`);\n console.log(` Total entries: ${allLogs.length}`);\n console.log(\"═\".repeat(70));\n console.log(\"\");\n for (const entry of allLogs) {\n console.log(formatLogLine(entry));\n }\n console.log(\"\");\n console.log(\"═\".repeat(70));\n console.log(` Full logs saved to: ${logger.logFile}`);\n console.log(\"═\".repeat(70));\n console.log(\"\");\n }\n }),\n );\n\n yield* Deferred.await(shutdown);\n });\n\nconst runApp = (\n orchestrator: AppOrchestrator,\n services: Map<string, ServiceDescriptor>,\n runtimeConfig: RuntimeConfig,\n) => {\n let requestShutdown: (() => void) | null = null;\n let signalCount = 0;\n let forceExitTimer: ReturnType<typeof setTimeout> | null = null;\n\n const forceExit = () => {\n console.log(\"\\n[Dev] Force exit\");\n process.exit(0);\n };\n\n const program = Effect.scoped(\n runDevSession(orchestrator, (shutdown) => {\n requestShutdown = shutdown;\n }),\n ).pipe(\n Effect.catchAll((e) =>\n Effect.sync(() => {\n if (e instanceof Error) {\n console.error(\"App error:\", e.message);\n if (e.stack) console.error(e.stack);\n } else {\n console.error(\"App error:\", e);\n }\n }),\n ),\n Effect.provide(ServiceDescriptorMapLive(services)),\n Effect.provide(DevRuntimeConfigLive(runtimeConfig)),\n Effect.provide(NodeContext.layer),\n );\n\n const handleSignal = () => {\n signalCount++;\n if (signalCount > 1) {\n forceExit();\n return;\n }\n console.log(\"\\n[Dev] Shutting down...\");\n forceExitTimer = setTimeout(forceExit, 5000);\n requestShutdown?.();\n };\n\n process.on(\"SIGINT\", handleSignal);\n process.on(\"SIGTERM\", handleSignal);\n\n Effect.runPromiseExit(program).then((exit) => {\n if (forceExitTimer) clearTimeout(forceExitTimer);\n process.exit(Exit.isSuccess(exit) ? 0 : 0);\n });\n};\n\nexport const devApp = runApp;\n\nexport const startApp = runApp;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dev-session.cjs","names":["Effect","getProjectRoot","ServiceDescriptorMap","getProcessStates","createDevLogger","Deferred","renderDevView","renderStreamingView","makeDevProcess","ServiceDescriptorMapLive","DevRuntimeConfigLive","NodeContext","Exit"],"sources":["../src/dev-session.ts"],"sourcesContent":["import { NodeContext } from \"@effect/platform-node\";\nimport { Deferred, Effect, Exit } from \"effect\";\nimport {\n type DevViewHandle,\n type LogEntry,\n type ProcessState,\n renderDevView,\n} from \"./components/dev-view\";\nimport { renderStreamingView } from \"./components/streaming-view\";\nimport { getProjectRoot } from \"./config\";\nimport { createDevLogger } from \"./dev-logs\";\nimport {\n getProcessStates,\n makeDevProcess,\n type ProcessCallbacks,\n type ProcessHandle,\n} from \"./orchestrator\";\nimport {\n type AppOrchestrator,\n DevRuntimeConfigLive,\n type ServiceDescriptor,\n ServiceDescriptorMap,\n ServiceDescriptorMapLive,\n} from \"./service-descriptor\";\nimport type { RuntimeConfig } from \"./types\";\n\nconst LOG_NOISE_PATTERNS = [\n /\\[ Federation Runtime \\] Version .* from (host|ui) of shared singleton module/,\n /Executing an Effect versioned \\d+\\.\\d+\\.\\d+ with a Runtime of version/,\n /you may want to dedupe the effect dependencies/,\n];\n\nconst SSR_LOG_ALLOWLIST = [\n /\\bready\\s+built in\\b/i,\n /\\bcompiled\\b.*successfully/i,\n /\\berror\\b/i,\n /\\bfailed\\b/i,\n /\\bexception\\b/i,\n];\n\nconst shouldDisplayLog = (source: string, line: string, isError?: boolean): boolean => {\n if (process.env.DEBUG === \"true\" || process.env.DEBUG === \"1\") return true;\n if (source === \"ui-ssr\") {\n if (isError) return true;\n return SSR_LOG_ALLOWLIST.some((pattern) => pattern.test(line));\n }\n return !LOG_NOISE_PATTERNS.some((pattern) => pattern.test(line));\n};\n\nconst isInteractiveSupported = (): boolean => {\n return process.stdin.isTTY === true && process.stdout.isTTY === true;\n};\n\nconst STARTUP_ORDER = [\"ui-ssr\", \"ui\", \"auth\", \"api\", \"plugin\", \"host-build\", \"host\"];\n\nconst sortByOrder = (packages: string[]): string[] => {\n return [...packages].sort((a, b) => {\n const aIdx = a.startsWith(\"plugin:\")\n ? STARTUP_ORDER.indexOf(\"plugin\")\n : STARTUP_ORDER.indexOf(a);\n const bIdx = b.startsWith(\"plugin:\")\n ? STARTUP_ORDER.indexOf(\"plugin\")\n : STARTUP_ORDER.indexOf(b);\n if (aIdx === -1 && bIdx === -1) return 0;\n if (aIdx === -1) return 1;\n if (bIdx === -1) return -1;\n return aIdx - bIdx;\n });\n};\n\nfunction formatLogLine(entry: LogEntry): string {\n const ts = new Date(entry.timestamp).toISOString();\n const prefix = entry.isError ? \"ERR\" : \"OUT\";\n return `[${ts}] [${entry.source}] [${prefix}] ${entry.line}`;\n}\n\nexport const runDevSession = (\n orchestrator: AppOrchestrator,\n onShutdownReady?: (requestShutdown: () => void) => void,\n) =>\n Effect.gen(function* () {\n const configDir = getProjectRoot();\n const services = yield* ServiceDescriptorMap;\n const orderedPackages = sortByOrder(orchestrator.packages);\n const initialProcesses: ProcessState[] = getProcessStates(\n orderedPackages,\n services,\n orchestrator.port,\n );\n\n const logger = yield* Effect.promise(() =>\n createDevLogger(configDir, orchestrator.description),\n );\n\n const shutdown = yield* Deferred.make<void>();\n\n onShutdownReady?.(() => {\n void Effect.runPromise(Deferred.succeed(shutdown, undefined));\n });\n\n const allLogs: LogEntry[] = [];\n let view: DevViewHandle | null = null;\n let shouldExportLogs = false;\n\n const requestShutdownAndExport = () => {\n shouldExportLogs = true;\n void Effect.runPromise(Deferred.succeed(shutdown, undefined));\n };\n\n const useInteractive = orchestrator.interactive ?? isInteractiveSupported();\n view = useInteractive\n ? renderDevView(\n initialProcesses,\n orchestrator.description,\n orchestrator.env,\n () => void Effect.runPromise(Deferred.succeed(shutdown, undefined)),\n requestShutdownAndExport,\n )\n : renderStreamingView(\n initialProcesses,\n orchestrator.description,\n orchestrator.env,\n () => void Effect.runPromise(Deferred.succeed(shutdown, undefined)),\n );\n\n const callbacks: ProcessCallbacks = {\n onStatus: (name, status, message) => {\n view?.updateProcess(name, status, message);\n },\n onLog: (name, line, isError) => {\n const entry: LogEntry = {\n id: `${Date.now()}-${allLogs.length + 1}`,\n source: name,\n line,\n timestamp: Date.now(),\n isError,\n };\n allLogs.push(entry);\n if (shouldDisplayLog(name, line, isError)) {\n view?.addLog(name, line, isError);\n }\n if (!orchestrator.noLogs) {\n void logger.write(entry);\n }\n },\n };\n\n const startProcess = (pkg: string) => {\n const portOverride = pkg === \"host\" ? orchestrator.port : undefined;\n return makeDevProcess(pkg, callbacks, portOverride).pipe(\n Effect.tapError((err) =>\n Effect.sync(() => {\n callbacks.onLog(pkg, `Failed to start: ${err}`, true);\n callbacks.onStatus(pkg, \"error\");\n }),\n ),\n Effect.catchAll(() =>\n Effect.succeed({\n name: pkg,\n pid: undefined,\n kill: Effect.void,\n waitForReady: Effect.void,\n waitForExit: Effect.never,\n } satisfies ProcessHandle),\n ),\n );\n };\n\n const startGroup = (packages: string[]) =>\n Effect.forEach(packages, startProcess, { concurrency: \"unbounded\" });\n\n const awaitReady = (_pkg: string, handle: ProcessHandle) =>\n handle.waitForReady.pipe(Effect.catchAll(() => Effect.void));\n\n const nonHostPackages = orderedPackages.filter((pkg) => pkg !== \"host\");\n const hostPackages = orderedPackages.filter((pkg) => pkg === \"host\");\n\n const nonHostHandles = yield* startGroup(nonHostPackages);\n\n yield* Effect.forEach(\n nonHostHandles.map((handle, index) => ({\n handle,\n pkg: nonHostPackages[index] ?? handle.name,\n })),\n ({ handle, pkg }) => awaitReady(pkg, handle),\n { concurrency: \"unbounded\" },\n );\n\n const hostHandles = yield* startGroup(hostPackages);\n\n yield* Effect.forEach(\n hostHandles.map((handle, index) => ({ handle, pkg: hostPackages[index] ?? handle.name })),\n ({ handle, pkg }) => awaitReady(pkg, handle),\n { concurrency: \"unbounded\" },\n );\n\n const allHandles = [...nonHostHandles, ...hostHandles];\n\n yield* Effect.addFinalizer(() =>\n Effect.gen(function* () {\n yield* Effect.forEach(allHandles, (h) => h.kill.pipe(Effect.ignore), {\n concurrency: \"unbounded\",\n });\n\n yield* Effect.sleep(\"200 millis\");\n\n view?.unmount();\n\n if (shouldExportLogs) {\n console.log(\"\\n\");\n console.log(\"═\".repeat(70));\n console.log(` SESSION LOGS: ${orchestrator.description}`);\n console.log(` Started: ${new Date(allLogs[0]?.timestamp || Date.now()).toISOString()}`);\n console.log(` Total entries: ${allLogs.length}`);\n console.log(\"═\".repeat(70));\n console.log(\"\");\n for (const entry of allLogs) {\n console.log(formatLogLine(entry));\n }\n console.log(\"\");\n console.log(\"═\".repeat(70));\n console.log(` Full logs saved to: ${logger.logFile}`);\n console.log(\"═\".repeat(70));\n console.log(\"\");\n }\n }),\n );\n\n yield* Deferred.await(shutdown);\n });\n\nconst runApp = (\n orchestrator: AppOrchestrator,\n services: Map<string, ServiceDescriptor>,\n runtimeConfig: RuntimeConfig,\n) => {\n let requestShutdown: (() => void) | null = null;\n let signalCount = 0;\n let forceExitTimer: ReturnType<typeof setTimeout> | null = null;\n\n const forceExit = () => {\n console.log(\"\\n[Dev] Force exit\");\n process.exit(0);\n };\n\n const program = Effect.scoped(\n runDevSession(orchestrator, (shutdown) => {\n requestShutdown = shutdown;\n }),\n ).pipe(\n Effect.provide(ServiceDescriptorMapLive(services)),\n Effect.provide(DevRuntimeConfigLive(runtimeConfig)),\n Effect.provide(NodeContext.layer),\n Effect.catchAllDefect((defect) =>\n Effect.sync(() => {\n console.error(\"[Dev] Unhandled defect in orchestrator:\", defect);\n }),\n ),\n );\n\n const handleSignal = () => {\n signalCount++;\n if (signalCount > 1) {\n forceExit();\n return;\n }\n console.log(\"\\n[Dev] Shutting down...\");\n forceExitTimer = setTimeout(forceExit, 5000);\n requestShutdown?.();\n };\n\n process.on(\"SIGINT\", handleSignal);\n process.on(\"SIGTERM\", handleSignal);\n\n Effect.runPromiseExit(program).then((exit) => {\n if (forceExitTimer) clearTimeout(forceExitTimer);\n process.exit(Exit.isSuccess(exit) ? 0 : 0);\n });\n};\n\nexport const devApp = runApp;\n\nexport const startApp = runApp;\n"],"mappings":"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"}
|