everything-dev 1.3.6 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/cli/init.cjs +34 -5
  2. package/dist/cli/init.cjs.map +1 -1
  3. package/dist/cli/init.d.cts +10 -7
  4. package/dist/cli/init.d.cts.map +1 -1
  5. package/dist/cli/init.d.mts +10 -7
  6. package/dist/cli/init.d.mts.map +1 -1
  7. package/dist/cli/init.mjs +34 -6
  8. package/dist/cli/init.mjs.map +1 -1
  9. package/dist/cli/prompts.cjs +19 -9
  10. package/dist/cli/prompts.cjs.map +1 -1
  11. package/dist/cli/prompts.mjs +19 -9
  12. package/dist/cli/prompts.mjs.map +1 -1
  13. package/dist/cli/snapshot.cjs +35 -0
  14. package/dist/cli/snapshot.cjs.map +1 -0
  15. package/dist/cli/snapshot.mjs +33 -0
  16. package/dist/cli/snapshot.mjs.map +1 -0
  17. package/dist/cli/status.cjs +80 -0
  18. package/dist/cli/status.cjs.map +1 -0
  19. package/dist/cli/status.mjs +79 -0
  20. package/dist/cli/status.mjs.map +1 -0
  21. package/dist/cli/sync.cjs +170 -0
  22. package/dist/cli/sync.cjs.map +1 -0
  23. package/dist/cli/sync.mjs +169 -0
  24. package/dist/cli/sync.mjs.map +1 -0
  25. package/dist/cli/upgrade.cjs +123 -0
  26. package/dist/cli/upgrade.cjs.map +1 -0
  27. package/dist/cli/upgrade.mjs +122 -0
  28. package/dist/cli/upgrade.mjs.map +1 -0
  29. package/dist/cli.cjs +101 -5
  30. package/dist/cli.cjs.map +1 -1
  31. package/dist/cli.mjs +101 -5
  32. package/dist/cli.mjs.map +1 -1
  33. package/dist/contract.cjs +81 -8
  34. package/dist/contract.cjs.map +1 -1
  35. package/dist/contract.d.cts +156 -15
  36. package/dist/contract.d.cts.map +1 -1
  37. package/dist/contract.d.mts +156 -15
  38. package/dist/contract.d.mts.map +1 -1
  39. package/dist/contract.meta.cjs +32 -9
  40. package/dist/contract.meta.cjs.map +1 -1
  41. package/dist/contract.meta.d.cts +50 -11
  42. package/dist/contract.meta.d.mts +50 -11
  43. package/dist/contract.meta.mjs +32 -9
  44. package/dist/contract.meta.mjs.map +1 -1
  45. package/dist/contract.mjs +77 -9
  46. package/dist/contract.mjs.map +1 -1
  47. package/dist/index.cjs +5 -0
  48. package/dist/index.d.cts +2 -2
  49. package/dist/index.d.mts +2 -2
  50. package/dist/index.mjs +2 -2
  51. package/dist/plugin.cjs +123 -43
  52. package/dist/plugin.cjs.map +1 -1
  53. package/dist/plugin.d.cts +75 -8
  54. package/dist/plugin.d.cts.map +1 -1
  55. package/dist/plugin.d.mts +75 -8
  56. package/dist/plugin.d.mts.map +1 -1
  57. package/dist/plugin.mjs +126 -46
  58. package/dist/plugin.mjs.map +1 -1
  59. package/dist/types.d.cts +2 -2
  60. package/dist/types.d.mts +2 -2
  61. package/dist/utils/theme.cjs +1 -0
  62. package/dist/utils/theme.cjs.map +1 -1
  63. package/dist/utils/theme.mjs +1 -0
  64. package/dist/utils/theme.mjs.map +1 -1
  65. package/package.json +3 -3
  66. package/src/cli/init.ts +60 -11
  67. package/src/cli/prompts.ts +34 -16
  68. package/src/cli/snapshot.ts +46 -0
  69. package/src/cli/status.ts +85 -0
  70. package/src/cli/sync.ts +239 -0
  71. package/src/cli/upgrade.ts +165 -0
  72. package/src/cli.ts +152 -5
  73. package/src/contract.meta.ts +36 -6
  74. package/src/contract.ts +74 -7
  75. package/src/plugin.ts +156 -45
  76. package/src/utils/theme.ts +1 -0
package/dist/cli/init.cjs CHANGED
@@ -2,8 +2,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
3
  const require_fastkv = require('../fastkv.cjs');
4
4
  const require_manifest_normalizer = require('../internal/manifest-normalizer.cjs');
5
+ const require_snapshot = require('./snapshot.cjs');
5
6
  let node_fs = require("node:fs");
6
7
  let node_path = require("node:path");
8
+ let node_crypto = require("node:crypto");
7
9
  let node_child_process = require("node:child_process");
8
10
  let node_module = require("node:module");
9
11
  let node_os = require("node:os");
@@ -22,7 +24,7 @@ async function resolveSourceDir(opts) {
22
24
  cleanup: async () => {}
23
25
  };
24
26
  }
25
- const parentConfig = await fetchParentConfig(opts.account, opts.gateway);
27
+ const parentConfig = await fetchParentConfig(opts.extendsAccount, opts.extendsGateway);
26
28
  if (!parentConfig.repository) throw new Error("Parent config has no repository field — cannot locate template source");
27
29
  const { dir: sourceDir, cleanup } = await downloadTarball(parentConfig.repository);
28
30
  return {
@@ -31,8 +33,8 @@ async function resolveSourceDir(opts) {
31
33
  cleanup
32
34
  };
33
35
  }
34
- async function fetchParentConfig(account, gateway) {
35
- return require_fastkv.fetchBosConfigFromFastKv(`bos://${account}/${gateway}`);
36
+ async function fetchParentConfig(extendsAccount, extendsGateway) {
37
+ return require_fastkv.fetchBosConfigFromFastKv(`bos://${extendsAccount}/${extendsGateway}`);
36
38
  }
37
39
  async function downloadTarball(repoUrl) {
38
40
  const parsed = parseGitHubUrl(repoUrl);
@@ -141,8 +143,8 @@ async function personalizeConfig(destination, opts) {
141
143
  const configPath = (0, node_path.join)(destination, "bos.config.json");
142
144
  if ((0, node_fs.existsSync)(configPath)) {
143
145
  const config = JSON.parse((0, node_fs.readFileSync)(configPath, "utf-8"));
144
- config.extends = `bos://${opts.parentAccount}/${opts.parentGateway}`;
145
- if (opts.name) config.account = opts.name;
146
+ config.extends = `bos://${opts.extendsAccount}/${opts.extendsGateway}`;
147
+ if (opts.account) config.account = opts.account;
146
148
  if (opts.domain) config.domain = opts.domain;
147
149
  if (config.app && typeof config.app === "object") {
148
150
  const app = config.app;
@@ -248,6 +250,32 @@ async function resolveWorkspaceRefs(destination, options) {
248
250
  }
249
251
  }
250
252
  }
253
+ async function writeInitSnapshot(destination, extendsAccount, extendsGateway, sourceDir, patterns, options) {
254
+ const effectivePatterns = options.withHost ? [...patterns, "host/**"] : patterns.filter((p) => !p.startsWith("host/") && p !== "host/**");
255
+ const allFiles = /* @__PURE__ */ new Set();
256
+ for (const pattern of effectivePatterns) {
257
+ const matches = await (0, glob.glob)(pattern, {
258
+ cwd: sourceDir,
259
+ nodir: true,
260
+ dot: true,
261
+ absolute: false
262
+ });
263
+ for (const match of matches) allFiles.add(match);
264
+ }
265
+ const fileHashes = {};
266
+ for (const filePath of allFiles) {
267
+ const src = (0, node_path.join)(sourceDir, filePath);
268
+ if (!(0, node_fs.lstatSync)(src).isFile()) continue;
269
+ fileHashes[filePath] = computeHash((0, node_fs.readFileSync)(src));
270
+ }
271
+ await require_snapshot.writeSnapshot(destination, {
272
+ parentRef: `bos://${extendsAccount}/${extendsGateway}`,
273
+ files: fileHashes
274
+ });
275
+ }
276
+ function computeHash(data) {
277
+ return (0, node_crypto.createHash)("sha256").update(data).digest("hex").substring(0, 16);
278
+ }
251
279
  function mkTmpDir(prefix) {
252
280
  const base = (0, node_path.join)((0, node_os.tmpdir)(), prefix);
253
281
  let attempt = 0;
@@ -289,4 +317,5 @@ exports.personalizeConfig = personalizeConfig;
289
317
  exports.readTemplatekeep = readTemplatekeep;
290
318
  exports.resolveSourceDir = resolveSourceDir;
291
319
  exports.runBunInstall = runBunInstall;
320
+ exports.writeInitSnapshot = writeInitSnapshot;
292
321
  //# sourceMappingURL=init.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.cjs","names":["require","fetchBosConfigFromFastKv","loadManifestNormalizationSpec","normalizePackageManifestsInTree"],"sources":["../../src/cli/init.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\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\";\n\nconst require = createRequire(import.meta.url);\n\ninterface SourceResult {\n sourceDir: string;\n parentConfig: BosConfig;\n cleanup: () => Promise<void>;\n}\n\nexport async function resolveSourceDir(opts: {\n account: string;\n gateway: 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.account, opts.gateway);\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(account: string, gateway: string): Promise<BosConfig> {\n const bosUrl = `bos://${account}/${gateway}`;\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 },\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 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 allFiles.add(match);\n }\n }\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 dest = join(destination, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n parentAccount: string;\n parentGateway: string;\n name?: string;\n domain?: string;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n },\n): Promise<void> {\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.parentAccount}/${opts.parentGateway}`;\n\n if (opts.name) {\n config.account = opts.name;\n }\n if (opts.domain) {\n config.domain = opts.domain;\n }\n\n if (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.productionIntegrity;\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 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.productionIntegrity;\n }\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(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) => p !== \"host\" && !p.startsWith(\"packages/\"));\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: false,\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\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":";;;;;;;;;;;;;AAsBA,MAAMA,yFAAwC;AAQ9C,eAAsB,iBAAiB,MAIb;AACxB,KAAI,KAAK,QAAQ;EACf,MAAM,mCAAoB,KAAK,OAAO;AACtC,MAAI,6CAAiB,WAAW,kBAAkB,CAAC,CACjD,OAAM,IAAI,MAAM,iDAAiD,YAAY;AAK/E,SAAO;GAAE;GAAW,cAHC,KAAK,oDACN,WAAW,kBAAkB,EAAE,QAAQ,CAC1D;GACiC,SAAS,YAAY;GAAI;;CAG7D,MAAM,eAAe,MAAM,kBAAkB,KAAK,SAAS,KAAK,QAAQ;AAExE,KAAI,CAAC,aAAa,WAChB,OAAM,IAAI,MAAM,wEAAwE;CAG1F,MAAM,EAAE,KAAK,WAAW,YAAY,MAAM,gBAAgB,aAAa,WAAW;AAClF,QAAO;EAAE;EAAW;EAAc;EAAS;;AAG7C,eAAsB,kBAAkB,SAAiB,SAAqC;AAE5F,QAAOC,wCADQ,SAAS,QAAQ,GAAG,UACe;;AAGpD,eAAsB,gBACpB,SACwD;CACxD,MAAM,SAAS,eAAe,QAAQ;AACtC,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,gCAAgC,UAAU;CAG5D,MAAM,EAAE,OAAO,MAAM,WAAW;CAChC,MAAM,aAAa,gCAAgC,MAAM,GAAG,KAAK,WAAW;CAE5E,MAAM,SAAS,SAAS,oBAAoB;CAC5C,MAAM,kCAAmB,QAAQ,gBAAgB;CAEjD,MAAM,WAAW,MAAM,MAAM,YAAY;EACvC,SAAS,EAAE,cAAc,kBAAkB;EAC3C,UAAU;EACX,CAAC;AAEF,KAAI,CAAC,SAAS,IAAI;AAChB,sBAAO,QAAQ;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;AAChD,QAAM,IAAI,MAAM,mCAAmC,SAAS,OAAO,GAAG,SAAS,aAAa;;AAG9F,KAAI,CAAC,SAAS,MAAM;AAClB,sBAAO,QAAQ;GAAE,WAAW;GAAM,OAAO;GAAM,CAAC;AAChD,QAAM,IAAI,MAAM,8CAA8C;;CAGhE,MAAM,4CAA+B,YAAY;CACjD,MAAM,SAAS,SAAS;AACxB,0CAAe,QAAQ,WAAW;CAElC,MAAM,aAAa,SAAS,oBAAoB;AAChD,KAAI;AAIF,QAHYD,UAAQ,MAAM,CAGhB,QAAQ;GAAE,KAAK;GAAY,MAAM;GAAa,OAAO;GAAG,CAAC;SAC7D;AACN,QAAM,YAAY,OAAO;GAAC;GAAQ;GAAa;GAAwB;GAAM;GAAW,CAAC;;AAG3F,qBAAO,QAAQ;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC;AAEhD,QAAO;EACL,KAAK;EACL,SAAS,YAAY;AACnB,uBAAO,YAAY;IAAE,WAAW;IAAM,OAAO;IAAM,CAAC;;EAEvD;;AAGH,SAAS,eAAe,KAAqE;CAC3F,MAAM,aAAa,IAAI,MAAM,iEAAiE;AAC9F,KAAI,WACF,QAAO;EAAE,OAAO,WAAW;EAAI,MAAM,WAAW;EAAI,QAAQ;EAAQ;CAGtE,MAAM,WAAW,IAAI,MAAM,gDAAgD;AAC3E,KAAI,SACF,QAAO;EAAE,OAAO,SAAS;EAAI,MAAM,SAAS;EAAI,QAAQ;EAAQ;AAGlE,QAAO;;AAGT,eAAsB,iBAAiB,WAAsC;CAC3E,MAAM,+BAAgB,WAAW,gBAAgB;AACjD,KAAI,yBAAY,SAAS,CACvB,QAAO,EAAE;AAIX,kCAD6B,UAAU,QAAQ,CAE5C,MAAM,KAAK,CACX,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,KAAK,CAAC,KAAK,WAAW,IAAI,CAAC;;AAG/D,eAAsB,kBACpB,WACA,aACA,UACA,SACiB;AACjB,KAAI,SAAS,WAAW,EACtB,QAAO;CAGT,MAAM,oBAAoB,QAAQ,WAC9B,CAAC,GAAG,UAAU,UAAU,GACxB,SAAS,QAAQ,MAAM,CAAC,EAAE,WAAW,QAAQ,IAAI,MAAM,UAAU;CAErE,MAAM,2BAAW,IAAI,KAAa;AAClC,MAAK,MAAM,WAAW,mBAAmB;EACvC,MAAM,UAAU,qBAAW,SAAS;GAClC,KAAK;GACL,OAAO;GACP,KAAK;GACL,UAAU;GACX,CAAC;AACF,OAAK,MAAM,SAAS,QAClB,UAAS,IAAI,MAAM;;AAIvB,wBAAU,aAAa,EAAE,WAAW,MAAM,CAAC;CAE3C,IAAI,QAAQ;AACZ,MAAK,MAAM,YAAY,UAAU;EAC/B,MAAM,0BAAW,WAAW,SAAS;AAErC,MAAI,wBADmB,IAAI,CACjB,QAAQ,CAAE;EAEpB,MAAM,2BAAY,aAAa,SAAS;AACxC,gDAAkB,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAE7C,6BAAc,gCADe,IAAI,CACL;AAC5B;;AAGF,QAAO;;AAGT,eAAsB,kBACpB,aACA,MAOe;CACf,MAAM,iCAAkB,aAAa,kBAAkB;AACvD,6BAAe,WAAW,EAAE;EAC1B,MAAM,SAAS,KAAK,gCAAmB,YAAY,QAAQ,CAAC;AAE5D,SAAO,UAAU,SAAS,KAAK,cAAc,GAAG,KAAK;AAErD,MAAI,KAAK,KACP,QAAO,UAAU,KAAK;AAExB,MAAI,KAAK,OACP,QAAO,SAAS,KAAK;AAGvB,MAAI,OAAO,OAAO,OAAO,OAAO,QAAQ,UAAU;GAChD,MAAM,MAAM,OAAO;AACnB,QAAK,MAAM,YAAY,OAAO,KAAK,IAAI,EAAE;IACvC,MAAM,QAAQ,IAAI;AAClB,QAAI,SAAS,OAAO,UAAU,UAAU;KACtC,MAAM,IAAI;AACV,YAAO,EAAE;AACT,YAAO,EAAE;AACT,YAAO,EAAE;AACT,YAAO,EAAE;;;;AAKf,MAAI,OAAO,WAAW,OAAO,OAAO,YAAY,UAAU;GACxD,MAAM,UAAU,OAAO;AACvB,QAAK,MAAM,aAAa,OAAO,KAAK,QAAQ,EAAE;IAC5C,MAAM,SAAS,QAAQ;AACvB,QAAI,UAAU,OAAO,WAAW,UAAU;KACxC,MAAM,IAAI;AACV,YAAO,EAAE;AACT,YAAO,EAAE;;;;AAKf,6BAAc,YAAY,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,IAAI;;CAGnE,MAAM,8BAAe,aAAa,eAAe;AACjD,6BAAe,QAAQ,EAAE;EACvB,MAAM,MAAM,KAAK,gCAAmB,SAAS,QAAQ,CAAC;AAEtD,MAAI,IAAI,cAAc,OAAO,IAAI,eAAe,UAAU;GACxD,MAAM,KAAK,IAAI;AACf,OAAI,MAAM,QAAQ,GAAG,SAAS,CAC5B,IAAG,WAAW,GAAG,SAAS,QAAQ,MAAc,MAAM,UAAU,CAAC,EAAE,WAAW,YAAY,CAAC;;AAI/F,MAAI,IAAI,WAAW,OAAO,IAAI,YAAY,UAAU;GAClD,MAAM,UAAU,IAAI;GACpB,MAAM,WAAW,KAAa,MAAc,OAAe;AACzD,QAAI,QAAQ,MAAM,SAAS,KAAK,CAC9B,SAAQ,OAAO,QAAQ,KAAK,WAAW,MAAM,GAAG;;AAGpD,WAAQ,OAAO,kCAAkC,wBAAwB;AACzE,WAAQ,UAAU,kCAAkC,wBAAwB;AAC5E,WAAQ,WAAW,kCAAkC,wBAAwB;AAC7E,WAAQ,aAAa,kCAAkC,wBAAwB;AAC/E,WAAQ,SAAS,kCAAkC,wBAAwB;AAC3E,WAAQ,UAAU,kCAAkC,wBAAwB;AAC5E,WAAQ,WAAW,kCAAkC,wBAAwB;AAC7E,WAAQ,SAAS,kCAAkC,wBAAwB;AAE3E,OAAI,QAAQ,qBACV,QAAO,QAAQ;AAEjB,OAAI,QAAQ,YACV,QAAO,QAAQ;AAEjB,OAAI,QAAQ,WAAW,SAAS,oBAAoB,CAClD,SAAQ,YAAY,QAAQ,UAAU,QAAQ,iCAAiC,GAAG;;AAItF,MAAI,IAAI,mBAAmB,OAAO,IAAI,oBAAoB,UAAU;GAClE,MAAM,OAAO,IAAI;AACjB,UAAO,KAAK;AACZ,UAAO,KAAK;;AAGd,MAAI,CAAC,IAAI,aAAc,KAAI,eAAe,EAAE;EAC5C,MAAM,OAAO,IAAI;EACjB,MAAM,OAAO,KAAK,eAAe,YAC7BE,0DAA8B,KAAK,cAAc,UAAU,GAC3D;AACJ,MAAI,CAAC,KAAK,qBAAqB,KAC7B,MAAK,oBAAoB,KAAK,YAAY;AAC5C,MAAI,CAAC,KAAK,mBAAmB,KAAM,MAAK,kBAAkB,KAAK,YAAY;AAE3E,6BAAc,SAAS,GAAG,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC,IAAI;;AAG7D,OAAM,qBAAqB,aAAa,KAAK,cAAc;CAE3D,MAAM,sCAAuB,aAAa,MAAM,OAAO,sBAAsB;AAC7E,KAAI,yBAAY,gBAAgB,EAAE;AAChC,gDAAkB,gBAAgB,EAAE,EAAE,WAAW,MAAM,CAAC;AACxD,6BAAc,iBAAiB,qDAAqD;;;AAIxF,eAAsB,cAAc,aAAoC;AACtE,OAAM,YAAY,OAAO,CAAC,UAAU,EAAE,YAAY;;AAGpD,MAAM,wBAAgD;CACpD,kBAAkB;CAClB,gBAAgB;CACjB;AAED,eAAe,qBACb,aACA,SACe;AACf,OAAMC,4DAAgC;EACpC,eAAe,SAAS,aAAa;EACrC,WAAW;EACX,oBAAoB;EACpB,qBAAqB,CAAC,OAAO;EAC9B,CAAC;AAEF,KAAI,SAAS,kBAAkB,QAAQ,WAAW;EAChD,MAAM,kCAAmB,aAAa,eAAe;AACrD,8BAAe,YAAY,EAAE;GAC3B,MAAM,MAAM,KAAK,gCAAmB,aAAa,QAAQ,CAAC;AAC1D,OAAI,CAAC,IAAI,UAAW,KAAI,YAAY,EAAE;GACtC,MAAM,YAAY,IAAI;GAEtB,MAAM,kBAAmB,IAAI,YAAyC,YAAY,EAAE,EAAE,OACpF,QACD;AAED,QAAK,MAAM,CAAC,MAAM,YAAY,OAAO,QAAQ,sBAAsB,CACjE,KAAI,CAAC,eAAe,MAAM,OAAO,OAAO,WAAW,OAAO,WAAW,OAAO,EAE1E;oDADwB,QAAQ,WAAW,SAAS,eAAe,CACzC,EAAE;AAC1B,eAAU,QAAQ,QAAQ;AAC1B,oBAAe,KAAK,QAAQ;;;AAKlC,OAAI,eAAe,SAAS,GAAG;AAC7B,QAAI,CAAC,IAAI,WAAY,KAAI,aAAa,EAAE;AACxC,IAAC,IAAI,WAAwC,WAAW;;AAG1D,8BAAc,aAAa,GAAG,KAAK,UAAU,KAAK,MAAM,EAAE,CAAC,IAAI;;;;AAKrE,SAAS,SAAS,QAAwB;CACxC,MAAM,gDAAoB,EAAE,OAAO;CACnC,IAAI,UAAU;AACd,QAAO,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,GAAG,KAAK,KAAK,CAAC,GAAG;AACrC,MAAI;AACF,0BAAU,KAAK,EAAE,WAAW,MAAM,CAAC;AACnC,UAAO;UACD;AACN;AACA,OAAI,UAAU,GAAI,OAAM,IAAI,MAAM,kCAAkC;;;;AAK1E,SAAS,YAAY,SAAiB,MAAgB,KAA6B;AACjF,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,sCAAc,SAAS,MAAM;GACjC;GACA,OAAO;GACP,OAAO;GACR,CAAC;EACF,IAAI,SAAS;AACb,QAAM,QAAQ,GAAG,SAAS,SAAiB;AACzC,aAAU,KAAK,UAAU;IACzB;AACF,QAAM,GAAG,UAAU,SAAS;AAC1B,OAAI,SAAS,EAAG,UAAS;OAEvB,wBACE,IAAI,MACF,YAAY,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,0BAA0B,KAAK,IAAI,SAC1E,CACF;IACH;AACF,QAAM,GAAG,SAAS,OAAO;GACzB"}
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\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 },\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 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 allFiles.add(match);\n }\n }\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 dest = join(destination, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n extendsAccount: string;\n extendsGateway: string;\n account?: string;\n domain?: string;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n },\n): Promise<void> {\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 (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.productionIntegrity;\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 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.productionIntegrity;\n }\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(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) => p !== \"host\" && !p.startsWith(\"packages/\"));\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: false,\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 },\n): Promise<void> {\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\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 allFiles.add(match);\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 fileHashes[filePath] = 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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"}
@@ -7,11 +7,11 @@ interface SourceResult {
7
7
  cleanup: () => Promise<void>;
8
8
  }
9
9
  declare function resolveSourceDir(opts: {
10
- account: string;
11
- gateway: string;
10
+ extendsAccount: string;
11
+ extendsGateway: string;
12
12
  source?: string;
13
13
  }): Promise<SourceResult>;
14
- declare function fetchParentConfig(account: string, gateway: string): Promise<BosConfig>;
14
+ declare function fetchParentConfig(extendsAccount: string, extendsGateway: string): Promise<BosConfig>;
15
15
  declare function downloadTarball(repoUrl: string): Promise<{
16
16
  dir: string;
17
17
  cleanup: () => Promise<void>;
@@ -21,9 +21,9 @@ declare function copyFilteredFiles(sourceDir: string, destination: string, patte
21
21
  withHost: boolean;
22
22
  }): Promise<number>;
23
23
  declare function personalizeConfig(destination: string, opts: {
24
- parentAccount: string;
25
- parentGateway: string;
26
- name?: string;
24
+ extendsAccount: string;
25
+ extendsGateway: string;
26
+ account?: string;
27
27
  domain?: string;
28
28
  workspaceOpts?: {
29
29
  localOverrides?: boolean;
@@ -31,6 +31,9 @@ declare function personalizeConfig(destination: string, opts: {
31
31
  };
32
32
  }): Promise<void>;
33
33
  declare function runBunInstall(destination: string): Promise<void>;
34
+ declare function writeInitSnapshot(destination: string, extendsAccount: string, extendsGateway: string, sourceDir: string, patterns: string[], options: {
35
+ withHost: boolean;
36
+ }): Promise<void>;
34
37
  //#endregion
35
- export { copyFilteredFiles, downloadTarball, fetchParentConfig, personalizeConfig, readTemplatekeep, resolveSourceDir, runBunInstall };
38
+ export { copyFilteredFiles, downloadTarball, fetchParentConfig, personalizeConfig, readTemplatekeep, resolveSourceDir, runBunInstall, writeInitSnapshot };
36
39
  //# sourceMappingURL=init.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.cts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UAwBU,YAAA;EACR,SAAA;EACA,YAAA,EAAc,SAAA;EACd,OAAA,QAAe,OAAA;AAAA;AAAA,iBAGK,gBAAA,CAAiB,IAAA;EACrC,OAAA;EACA,OAAA;EACA,MAAA;AAAA,IACE,OAAA,CAAQ,YAAA;AAAA,iBAsBU,iBAAA,CAAkB,OAAA,UAAiB,OAAA,WAAkB,OAAA,CAAQ,SAAA;AAAA,iBAK7D,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;AAAA,IACV,OAAA;AAAA,iBAwCmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,aAAA;EACA,aAAA;EACA,IAAA;EACA,MAAA;EACA,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;AAAA,IAE7C,OAAA;AAAA,iBA4GmB,aAAA,CAAc,WAAA,WAAsB,OAAA"}
1
+ {"version":3,"file":"init.d.cts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UA0BU,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;AAAA,IACV,OAAA;AAAA,iBAwCmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,cAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;AAAA,IAE7C,OAAA;AAAA,iBA4GmB,aAAA,CAAc,WAAA,WAAsB,OAAA;AAAA,iBAmDpC,iBAAA,CACpB,WAAA,UACA,cAAA,UACA,cAAA,UACA,SAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;AAAA,IACV,OAAA"}
@@ -7,11 +7,11 @@ interface SourceResult {
7
7
  cleanup: () => Promise<void>;
8
8
  }
9
9
  declare function resolveSourceDir(opts: {
10
- account: string;
11
- gateway: string;
10
+ extendsAccount: string;
11
+ extendsGateway: string;
12
12
  source?: string;
13
13
  }): Promise<SourceResult>;
14
- declare function fetchParentConfig(account: string, gateway: string): Promise<BosConfig>;
14
+ declare function fetchParentConfig(extendsAccount: string, extendsGateway: string): Promise<BosConfig>;
15
15
  declare function downloadTarball(repoUrl: string): Promise<{
16
16
  dir: string;
17
17
  cleanup: () => Promise<void>;
@@ -21,9 +21,9 @@ declare function copyFilteredFiles(sourceDir: string, destination: string, patte
21
21
  withHost: boolean;
22
22
  }): Promise<number>;
23
23
  declare function personalizeConfig(destination: string, opts: {
24
- parentAccount: string;
25
- parentGateway: string;
26
- name?: string;
24
+ extendsAccount: string;
25
+ extendsGateway: string;
26
+ account?: string;
27
27
  domain?: string;
28
28
  workspaceOpts?: {
29
29
  localOverrides?: boolean;
@@ -31,6 +31,9 @@ declare function personalizeConfig(destination: string, opts: {
31
31
  };
32
32
  }): Promise<void>;
33
33
  declare function runBunInstall(destination: string): Promise<void>;
34
+ declare function writeInitSnapshot(destination: string, extendsAccount: string, extendsGateway: string, sourceDir: string, patterns: string[], options: {
35
+ withHost: boolean;
36
+ }): Promise<void>;
34
37
  //#endregion
35
- export { copyFilteredFiles, downloadTarball, fetchParentConfig, personalizeConfig, readTemplatekeep, resolveSourceDir, runBunInstall };
38
+ export { copyFilteredFiles, downloadTarball, fetchParentConfig, personalizeConfig, readTemplatekeep, resolveSourceDir, runBunInstall, writeInitSnapshot };
36
39
  //# sourceMappingURL=init.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.mts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UAwBU,YAAA;EACR,SAAA;EACA,YAAA,EAAc,SAAA;EACd,OAAA,QAAe,OAAA;AAAA;AAAA,iBAGK,gBAAA,CAAiB,IAAA;EACrC,OAAA;EACA,OAAA;EACA,MAAA;AAAA,IACE,OAAA,CAAQ,YAAA;AAAA,iBAsBU,iBAAA,CAAkB,OAAA,UAAiB,OAAA,WAAkB,OAAA,CAAQ,SAAA;AAAA,iBAK7D,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;AAAA,IACV,OAAA;AAAA,iBAwCmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,aAAA;EACA,aAAA;EACA,IAAA;EACA,MAAA;EACA,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;AAAA,IAE7C,OAAA;AAAA,iBA4GmB,aAAA,CAAc,WAAA,WAAsB,OAAA"}
1
+ {"version":3,"file":"init.d.mts","names":[],"sources":["../../src/cli/init.ts"],"mappings":";;;UA0BU,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;AAAA,IACV,OAAA;AAAA,iBAwCmB,iBAAA,CACpB,WAAA,UACA,IAAA;EACE,cAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,aAAA;IAAkB,cAAA;IAA0B,SAAA;EAAA;AAAA,IAE7C,OAAA;AAAA,iBA4GmB,aAAA,CAAc,WAAA,WAAsB,OAAA;AAAA,iBAmDpC,iBAAA,CACpB,WAAA,UACA,cAAA,UACA,cAAA,UACA,SAAA,UACA,QAAA,YACA,OAAA;EAAW,QAAA;AAAA,IACV,OAAA"}
package/dist/cli/init.mjs CHANGED
@@ -1,8 +1,10 @@
1
1
  import { fetchBosConfigFromFastKv } from "../fastkv.mjs";
2
2
  import { loadManifestNormalizationSpec, normalizePackageManifestsInTree } from "../internal/manifest-normalizer.mjs";
3
+ import { writeSnapshot } from "./snapshot.mjs";
3
4
  import { createRequire } from "node:module";
4
5
  import { createWriteStream, existsSync, lstatSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
5
6
  import { dirname, join, resolve } from "node:path";
7
+ import { createHash } from "node:crypto";
6
8
  import { spawn } from "node:child_process";
7
9
  import { tmpdir } from "node:os";
8
10
  import { pipeline } from "node:stream/promises";
@@ -20,7 +22,7 @@ async function resolveSourceDir(opts) {
20
22
  cleanup: async () => {}
21
23
  };
22
24
  }
23
- const parentConfig = await fetchParentConfig(opts.account, opts.gateway);
25
+ const parentConfig = await fetchParentConfig(opts.extendsAccount, opts.extendsGateway);
24
26
  if (!parentConfig.repository) throw new Error("Parent config has no repository field — cannot locate template source");
25
27
  const { dir: sourceDir, cleanup } = await downloadTarball(parentConfig.repository);
26
28
  return {
@@ -29,8 +31,8 @@ async function resolveSourceDir(opts) {
29
31
  cleanup
30
32
  };
31
33
  }
32
- async function fetchParentConfig(account, gateway) {
33
- return fetchBosConfigFromFastKv(`bos://${account}/${gateway}`);
34
+ async function fetchParentConfig(extendsAccount, extendsGateway) {
35
+ return fetchBosConfigFromFastKv(`bos://${extendsAccount}/${extendsGateway}`);
34
36
  }
35
37
  async function downloadTarball(repoUrl) {
36
38
  const parsed = parseGitHubUrl(repoUrl);
@@ -139,8 +141,8 @@ async function personalizeConfig(destination, opts) {
139
141
  const configPath = join(destination, "bos.config.json");
140
142
  if (existsSync(configPath)) {
141
143
  const config = JSON.parse(readFileSync(configPath, "utf-8"));
142
- config.extends = `bos://${opts.parentAccount}/${opts.parentGateway}`;
143
- if (opts.name) config.account = opts.name;
144
+ config.extends = `bos://${opts.extendsAccount}/${opts.extendsGateway}`;
145
+ if (opts.account) config.account = opts.account;
144
146
  if (opts.domain) config.domain = opts.domain;
145
147
  if (config.app && typeof config.app === "object") {
146
148
  const app = config.app;
@@ -246,6 +248,32 @@ async function resolveWorkspaceRefs(destination, options) {
246
248
  }
247
249
  }
248
250
  }
251
+ async function writeInitSnapshot(destination, extendsAccount, extendsGateway, sourceDir, patterns, options) {
252
+ const effectivePatterns = options.withHost ? [...patterns, "host/**"] : patterns.filter((p) => !p.startsWith("host/") && p !== "host/**");
253
+ const allFiles = /* @__PURE__ */ new Set();
254
+ for (const pattern of effectivePatterns) {
255
+ const matches = await glob(pattern, {
256
+ cwd: sourceDir,
257
+ nodir: true,
258
+ dot: true,
259
+ absolute: false
260
+ });
261
+ for (const match of matches) allFiles.add(match);
262
+ }
263
+ const fileHashes = {};
264
+ for (const filePath of allFiles) {
265
+ const src = join(sourceDir, filePath);
266
+ if (!lstatSync(src).isFile()) continue;
267
+ fileHashes[filePath] = computeHash(readFileSync(src));
268
+ }
269
+ await writeSnapshot(destination, {
270
+ parentRef: `bos://${extendsAccount}/${extendsGateway}`,
271
+ files: fileHashes
272
+ });
273
+ }
274
+ function computeHash(data) {
275
+ return createHash("sha256").update(data).digest("hex").substring(0, 16);
276
+ }
249
277
  function mkTmpDir(prefix) {
250
278
  const base = join(tmpdir(), prefix);
251
279
  let attempt = 0;
@@ -280,5 +308,5 @@ function execCommand(command, args, cwd) {
280
308
  }
281
309
 
282
310
  //#endregion
283
- export { copyFilteredFiles, downloadTarball, fetchParentConfig, personalizeConfig, readTemplatekeep, resolveSourceDir, runBunInstall };
311
+ export { copyFilteredFiles, downloadTarball, fetchParentConfig, personalizeConfig, readTemplatekeep, resolveSourceDir, runBunInstall, writeInitSnapshot };
284
312
  //# sourceMappingURL=init.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.mjs","names":[],"sources":["../../src/cli/init.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\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\";\n\nconst require = createRequire(import.meta.url);\n\ninterface SourceResult {\n sourceDir: string;\n parentConfig: BosConfig;\n cleanup: () => Promise<void>;\n}\n\nexport async function resolveSourceDir(opts: {\n account: string;\n gateway: 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.account, opts.gateway);\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(account: string, gateway: string): Promise<BosConfig> {\n const bosUrl = `bos://${account}/${gateway}`;\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 },\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 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 allFiles.add(match);\n }\n }\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 dest = join(destination, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n parentAccount: string;\n parentGateway: string;\n name?: string;\n domain?: string;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n },\n): Promise<void> {\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.parentAccount}/${opts.parentGateway}`;\n\n if (opts.name) {\n config.account = opts.name;\n }\n if (opts.domain) {\n config.domain = opts.domain;\n }\n\n if (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.productionIntegrity;\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 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.productionIntegrity;\n }\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(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) => p !== \"host\" && !p.startsWith(\"packages/\"));\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: false,\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\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\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 },\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 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 allFiles.add(match);\n }\n }\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 dest = join(destination, filePath);\n mkdirSync(dirname(dest), { recursive: true });\n const content = readFileSync(src);\n writeFileSync(dest, content);\n count++;\n }\n\n return count;\n}\n\nexport async function personalizeConfig(\n destination: string,\n opts: {\n extendsAccount: string;\n extendsGateway: string;\n account?: string;\n domain?: string;\n workspaceOpts?: { localOverrides?: boolean; sourceDir?: string };\n },\n): Promise<void> {\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 (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.productionIntegrity;\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 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.productionIntegrity;\n }\n }\n }\n\n writeFileSync(configPath, `${JSON.stringify(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) => p !== \"host\" && !p.startsWith(\"packages/\"));\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: false,\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 },\n): Promise<void> {\n const effectivePatterns = options.withHost\n ? [...patterns, \"host/**\"]\n : patterns.filter((p) => !p.startsWith(\"host/\") && p !== \"host/**\");\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 allFiles.add(match);\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 fileHashes[filePath] = 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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"}
@@ -20,18 +20,28 @@ async function promptYesNo(question, defaultVal = false) {
20
20
  if (!answer) return defaultVal;
21
21
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
22
22
  }
23
+ function deriveDirectoryFromDomain(domain) {
24
+ return domain.split(".")[0] || domain;
25
+ }
26
+ function deriveAccountFromDomain(domain, extendsAccount) {
27
+ const firstSegment = domain.split(".")[0];
28
+ if (!firstSegment) return "";
29
+ return `${firstSegment}.${extendsAccount.includes(".") ? extendsAccount.substring(extendsAccount.indexOf(".") + 1) : extendsAccount}`;
30
+ }
23
31
  async function promptInitOptions(input) {
24
- const account = input.account || await prompt("NEAR account", "dev.everything.near");
25
- const gateway = input.gateway || await prompt("Gateway ID", "everything.dev");
26
- const destination = input.destination || await prompt("Project directory", gateway);
27
- const name = input.name || await prompt("New project NEAR account (optional)", "");
28
- const domain = input.domain || await prompt("New project domain (optional)", "");
32
+ const extendsAccount = input.extendsAccount || await prompt("Extends account", "dev.everything.near");
33
+ const extendsGateway = input.extendsGateway || await prompt("Extends gateway", "everything.dev");
34
+ const domain = input.domain || await prompt("Project domain");
35
+ const accountDefault = domain ? deriveAccountFromDomain(domain, extendsAccount) : "";
36
+ const account = input.account || await prompt("Project NEAR account", accountDefault);
37
+ const directoryDefault = domain ? deriveDirectoryFromDomain(domain) : extendsGateway;
38
+ const directory = input.directory || await prompt("Project directory", directoryDefault);
29
39
  const withHost = input.withHost !== void 0 ? input.withHost : await promptYesNo("Include host?", false);
30
40
  return {
31
- account,
32
- gateway,
33
- destination,
34
- name: name || void 0,
41
+ extendsAccount,
42
+ extendsGateway,
43
+ directory,
44
+ account: account || void 0,
35
45
  domain: domain || void 0,
36
46
  withHost
37
47
  };
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.cjs","names":[],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import { createInterface } from \"node:readline\";\n\nexport async function prompt(question: string, defaultValue?: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const suffix = defaultValue ? ` [${defaultValue}]` : \"\";\n const fullQuestion = `${question}${suffix}: `;\n\n return new Promise<string>((resolve) => {\n rl.question(fullQuestion, (answer) => {\n rl.close();\n const trimmed = answer.trim();\n resolve(trimmed || defaultValue || \"\");\n });\n });\n}\n\nexport async function promptYesNo(question: string, defaultVal = false): Promise<boolean> {\n const hint = defaultVal ? \"Y/n\" : \"y/N\";\n const answer = await prompt(`${question} (${hint})`);\n if (!answer) return defaultVal;\n return answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n}\n\nexport async function promptInitOptions(input: {\n account?: string;\n gateway?: string;\n destination?: string;\n name?: string;\n domain?: string;\n withHost?: boolean;\n}): Promise<{\n account: string;\n gateway: string;\n destination: string;\n name?: string;\n domain?: string;\n withHost: boolean;\n}> {\n const account = input.account || (await prompt(\"NEAR account\", \"dev.everything.near\"));\n\n const gateway = input.gateway || (await prompt(\"Gateway ID\", \"everything.dev\"));\n\n const destination = input.destination || (await prompt(\"Project directory\", gateway));\n\n const name = input.name || (await prompt(\"New project NEAR account (optional)\", \"\"));\n\n const domain = input.domain || (await prompt(\"New project domain (optional)\", \"\"));\n\n const withHost =\n input.withHost !== undefined ? input.withHost : await promptYesNo(\"Include host?\", false);\n\n return {\n account,\n gateway,\n destination,\n name: name || undefined,\n domain: domain || undefined,\n withHost,\n };\n}\n"],"mappings":";;;;AAEA,eAAsB,OAAO,UAAkB,cAAwC;CACrF,MAAM,wCAAqB;EACzB,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;CAGF,MAAM,eAAe,GAAG,WADT,eAAe,KAAK,aAAa,KAAK,GACX;AAE1C,QAAO,IAAI,SAAiB,YAAY;AACtC,KAAG,SAAS,eAAe,WAAW;AACpC,MAAG,OAAO;AAEV,WADgB,OAAO,MAAM,IACV,gBAAgB,GAAG;IACtC;GACF;;AAGJ,eAAsB,YAAY,UAAkB,aAAa,OAAyB;CAExF,MAAM,SAAS,MAAM,OAAO,GAAG,SAAS,IAD3B,aAAa,QAAQ,MACe,GAAG;AACpD,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,aAAa,KAAK,OAAO,OAAO,aAAa,KAAK;;AAGlE,eAAsB,kBAAkB,OAcrC;CACD,MAAM,UAAU,MAAM,WAAY,MAAM,OAAO,gBAAgB,sBAAsB;CAErF,MAAM,UAAU,MAAM,WAAY,MAAM,OAAO,cAAc,iBAAiB;CAE9E,MAAM,cAAc,MAAM,eAAgB,MAAM,OAAO,qBAAqB,QAAQ;CAEpF,MAAM,OAAO,MAAM,QAAS,MAAM,OAAO,uCAAuC,GAAG;CAEnF,MAAM,SAAS,MAAM,UAAW,MAAM,OAAO,iCAAiC,GAAG;CAEjF,MAAM,WACJ,MAAM,aAAa,SAAY,MAAM,WAAW,MAAM,YAAY,iBAAiB,MAAM;AAE3F,QAAO;EACL;EACA;EACA;EACA,MAAM,QAAQ;EACd,QAAQ,UAAU;EAClB;EACD"}
1
+ {"version":3,"file":"prompts.cjs","names":[],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import { createInterface } from \"node:readline\";\n\nexport async function prompt(question: string, defaultValue?: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const suffix = defaultValue ? ` [${defaultValue}]` : \"\";\n const fullQuestion = `${question}${suffix}: `;\n\n return new Promise<string>((resolve) => {\n rl.question(fullQuestion, (answer) => {\n rl.close();\n const trimmed = answer.trim();\n resolve(trimmed || defaultValue || \"\");\n });\n });\n}\n\nexport async function promptYesNo(question: string, defaultVal = false): Promise<boolean> {\n const hint = defaultVal ? \"Y/n\" : \"y/N\";\n const answer = await prompt(`${question} (${hint})`);\n if (!answer) return defaultVal;\n return answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n}\n\nfunction deriveDirectoryFromDomain(domain: string): string {\n const firstSegment = domain.split(\".\")[0];\n return firstSegment || domain;\n}\n\nfunction deriveAccountFromDomain(domain: string, extendsAccount: string): string {\n const firstSegment = domain.split(\".\")[0];\n if (!firstSegment) return \"\";\n const suffix = extendsAccount.includes(\".\")\n ? extendsAccount.substring(extendsAccount.indexOf(\".\") + 1)\n : extendsAccount;\n return `${firstSegment}.${suffix}`;\n}\n\nexport async function promptInitOptions(input: {\n extendsAccount?: string;\n extendsGateway?: string;\n directory?: string;\n account?: string;\n domain?: string;\n withHost?: boolean;\n}): Promise<{\n extendsAccount: string;\n extendsGateway: string;\n directory: string;\n account?: string;\n domain?: string;\n withHost: boolean;\n}> {\n const extendsAccount =\n input.extendsAccount || (await prompt(\"Extends account\", \"dev.everything.near\"));\n\n const extendsGateway =\n input.extendsGateway || (await prompt(\"Extends gateway\", \"everything.dev\"));\n\n const domain = input.domain || (await prompt(\"Project domain\"));\n\n const accountDefault = domain ? deriveAccountFromDomain(domain, extendsAccount) : \"\";\n const account = input.account || (await prompt(\"Project NEAR account\", accountDefault));\n\n const directoryDefault = domain ? deriveDirectoryFromDomain(domain) : extendsGateway;\n const directory = input.directory || (await prompt(\"Project directory\", directoryDefault));\n\n const withHost =\n input.withHost !== undefined ? input.withHost : await promptYesNo(\"Include host?\", false);\n\n return {\n extendsAccount,\n extendsGateway,\n directory,\n account: account || undefined,\n domain: domain || undefined,\n withHost,\n };\n}\n"],"mappings":";;;;AAEA,eAAsB,OAAO,UAAkB,cAAwC;CACrF,MAAM,wCAAqB;EACzB,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;CAGF,MAAM,eAAe,GAAG,WADT,eAAe,KAAK,aAAa,KAAK,GACX;AAE1C,QAAO,IAAI,SAAiB,YAAY;AACtC,KAAG,SAAS,eAAe,WAAW;AACpC,MAAG,OAAO;AAEV,WADgB,OAAO,MAAM,IACV,gBAAgB,GAAG;IACtC;GACF;;AAGJ,eAAsB,YAAY,UAAkB,aAAa,OAAyB;CAExF,MAAM,SAAS,MAAM,OAAO,GAAG,SAAS,IAD3B,aAAa,QAAQ,MACe,GAAG;AACpD,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,aAAa,KAAK,OAAO,OAAO,aAAa,KAAK;;AAGlE,SAAS,0BAA0B,QAAwB;AAEzD,QADqB,OAAO,MAAM,IAAI,CAAC,MAChB;;AAGzB,SAAS,wBAAwB,QAAgB,gBAAgC;CAC/E,MAAM,eAAe,OAAO,MAAM,IAAI,CAAC;AACvC,KAAI,CAAC,aAAc,QAAO;AAI1B,QAAO,GAAG,aAAa,GAHR,eAAe,SAAS,IAAI,GACvC,eAAe,UAAU,eAAe,QAAQ,IAAI,GAAG,EAAE,GACzD;;AAIN,eAAsB,kBAAkB,OAcrC;CACD,MAAM,iBACJ,MAAM,kBAAmB,MAAM,OAAO,mBAAmB,sBAAsB;CAEjF,MAAM,iBACJ,MAAM,kBAAmB,MAAM,OAAO,mBAAmB,iBAAiB;CAE5E,MAAM,SAAS,MAAM,UAAW,MAAM,OAAO,iBAAiB;CAE9D,MAAM,iBAAiB,SAAS,wBAAwB,QAAQ,eAAe,GAAG;CAClF,MAAM,UAAU,MAAM,WAAY,MAAM,OAAO,wBAAwB,eAAe;CAEtF,MAAM,mBAAmB,SAAS,0BAA0B,OAAO,GAAG;CACtE,MAAM,YAAY,MAAM,aAAc,MAAM,OAAO,qBAAqB,iBAAiB;CAEzF,MAAM,WACJ,MAAM,aAAa,SAAY,MAAM,WAAW,MAAM,YAAY,iBAAiB,MAAM;AAE3F,QAAO;EACL;EACA;EACA;EACA,SAAS,WAAW;EACpB,QAAQ,UAAU;EAClB;EACD"}
@@ -19,18 +19,28 @@ async function promptYesNo(question, defaultVal = false) {
19
19
  if (!answer) return defaultVal;
20
20
  return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
21
21
  }
22
+ function deriveDirectoryFromDomain(domain) {
23
+ return domain.split(".")[0] || domain;
24
+ }
25
+ function deriveAccountFromDomain(domain, extendsAccount) {
26
+ const firstSegment = domain.split(".")[0];
27
+ if (!firstSegment) return "";
28
+ return `${firstSegment}.${extendsAccount.includes(".") ? extendsAccount.substring(extendsAccount.indexOf(".") + 1) : extendsAccount}`;
29
+ }
22
30
  async function promptInitOptions(input) {
23
- const account = input.account || await prompt("NEAR account", "dev.everything.near");
24
- const gateway = input.gateway || await prompt("Gateway ID", "everything.dev");
25
- const destination = input.destination || await prompt("Project directory", gateway);
26
- const name = input.name || await prompt("New project NEAR account (optional)", "");
27
- const domain = input.domain || await prompt("New project domain (optional)", "");
31
+ const extendsAccount = input.extendsAccount || await prompt("Extends account", "dev.everything.near");
32
+ const extendsGateway = input.extendsGateway || await prompt("Extends gateway", "everything.dev");
33
+ const domain = input.domain || await prompt("Project domain");
34
+ const accountDefault = domain ? deriveAccountFromDomain(domain, extendsAccount) : "";
35
+ const account = input.account || await prompt("Project NEAR account", accountDefault);
36
+ const directoryDefault = domain ? deriveDirectoryFromDomain(domain) : extendsGateway;
37
+ const directory = input.directory || await prompt("Project directory", directoryDefault);
28
38
  const withHost = input.withHost !== void 0 ? input.withHost : await promptYesNo("Include host?", false);
29
39
  return {
30
- account,
31
- gateway,
32
- destination,
33
- name: name || void 0,
40
+ extendsAccount,
41
+ extendsGateway,
42
+ directory,
43
+ account: account || void 0,
34
44
  domain: domain || void 0,
35
45
  withHost
36
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.mjs","names":[],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import { createInterface } from \"node:readline\";\n\nexport async function prompt(question: string, defaultValue?: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const suffix = defaultValue ? ` [${defaultValue}]` : \"\";\n const fullQuestion = `${question}${suffix}: `;\n\n return new Promise<string>((resolve) => {\n rl.question(fullQuestion, (answer) => {\n rl.close();\n const trimmed = answer.trim();\n resolve(trimmed || defaultValue || \"\");\n });\n });\n}\n\nexport async function promptYesNo(question: string, defaultVal = false): Promise<boolean> {\n const hint = defaultVal ? \"Y/n\" : \"y/N\";\n const answer = await prompt(`${question} (${hint})`);\n if (!answer) return defaultVal;\n return answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n}\n\nexport async function promptInitOptions(input: {\n account?: string;\n gateway?: string;\n destination?: string;\n name?: string;\n domain?: string;\n withHost?: boolean;\n}): Promise<{\n account: string;\n gateway: string;\n destination: string;\n name?: string;\n domain?: string;\n withHost: boolean;\n}> {\n const account = input.account || (await prompt(\"NEAR account\", \"dev.everything.near\"));\n\n const gateway = input.gateway || (await prompt(\"Gateway ID\", \"everything.dev\"));\n\n const destination = input.destination || (await prompt(\"Project directory\", gateway));\n\n const name = input.name || (await prompt(\"New project NEAR account (optional)\", \"\"));\n\n const domain = input.domain || (await prompt(\"New project domain (optional)\", \"\"));\n\n const withHost =\n input.withHost !== undefined ? input.withHost : await promptYesNo(\"Include host?\", false);\n\n return {\n account,\n gateway,\n destination,\n name: name || undefined,\n domain: domain || undefined,\n withHost,\n };\n}\n"],"mappings":";;;AAEA,eAAsB,OAAO,UAAkB,cAAwC;CACrF,MAAM,KAAK,gBAAgB;EACzB,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;CAGF,MAAM,eAAe,GAAG,WADT,eAAe,KAAK,aAAa,KAAK,GACX;AAE1C,QAAO,IAAI,SAAiB,YAAY;AACtC,KAAG,SAAS,eAAe,WAAW;AACpC,MAAG,OAAO;AAEV,WADgB,OAAO,MAAM,IACV,gBAAgB,GAAG;IACtC;GACF;;AAGJ,eAAsB,YAAY,UAAkB,aAAa,OAAyB;CAExF,MAAM,SAAS,MAAM,OAAO,GAAG,SAAS,IAD3B,aAAa,QAAQ,MACe,GAAG;AACpD,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,aAAa,KAAK,OAAO,OAAO,aAAa,KAAK;;AAGlE,eAAsB,kBAAkB,OAcrC;CACD,MAAM,UAAU,MAAM,WAAY,MAAM,OAAO,gBAAgB,sBAAsB;CAErF,MAAM,UAAU,MAAM,WAAY,MAAM,OAAO,cAAc,iBAAiB;CAE9E,MAAM,cAAc,MAAM,eAAgB,MAAM,OAAO,qBAAqB,QAAQ;CAEpF,MAAM,OAAO,MAAM,QAAS,MAAM,OAAO,uCAAuC,GAAG;CAEnF,MAAM,SAAS,MAAM,UAAW,MAAM,OAAO,iCAAiC,GAAG;CAEjF,MAAM,WACJ,MAAM,aAAa,SAAY,MAAM,WAAW,MAAM,YAAY,iBAAiB,MAAM;AAE3F,QAAO;EACL;EACA;EACA;EACA,MAAM,QAAQ;EACd,QAAQ,UAAU;EAClB;EACD"}
1
+ {"version":3,"file":"prompts.mjs","names":[],"sources":["../../src/cli/prompts.ts"],"sourcesContent":["import { createInterface } from \"node:readline\";\n\nexport async function prompt(question: string, defaultValue?: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const suffix = defaultValue ? ` [${defaultValue}]` : \"\";\n const fullQuestion = `${question}${suffix}: `;\n\n return new Promise<string>((resolve) => {\n rl.question(fullQuestion, (answer) => {\n rl.close();\n const trimmed = answer.trim();\n resolve(trimmed || defaultValue || \"\");\n });\n });\n}\n\nexport async function promptYesNo(question: string, defaultVal = false): Promise<boolean> {\n const hint = defaultVal ? \"Y/n\" : \"y/N\";\n const answer = await prompt(`${question} (${hint})`);\n if (!answer) return defaultVal;\n return answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n}\n\nfunction deriveDirectoryFromDomain(domain: string): string {\n const firstSegment = domain.split(\".\")[0];\n return firstSegment || domain;\n}\n\nfunction deriveAccountFromDomain(domain: string, extendsAccount: string): string {\n const firstSegment = domain.split(\".\")[0];\n if (!firstSegment) return \"\";\n const suffix = extendsAccount.includes(\".\")\n ? extendsAccount.substring(extendsAccount.indexOf(\".\") + 1)\n : extendsAccount;\n return `${firstSegment}.${suffix}`;\n}\n\nexport async function promptInitOptions(input: {\n extendsAccount?: string;\n extendsGateway?: string;\n directory?: string;\n account?: string;\n domain?: string;\n withHost?: boolean;\n}): Promise<{\n extendsAccount: string;\n extendsGateway: string;\n directory: string;\n account?: string;\n domain?: string;\n withHost: boolean;\n}> {\n const extendsAccount =\n input.extendsAccount || (await prompt(\"Extends account\", \"dev.everything.near\"));\n\n const extendsGateway =\n input.extendsGateway || (await prompt(\"Extends gateway\", \"everything.dev\"));\n\n const domain = input.domain || (await prompt(\"Project domain\"));\n\n const accountDefault = domain ? deriveAccountFromDomain(domain, extendsAccount) : \"\";\n const account = input.account || (await prompt(\"Project NEAR account\", accountDefault));\n\n const directoryDefault = domain ? deriveDirectoryFromDomain(domain) : extendsGateway;\n const directory = input.directory || (await prompt(\"Project directory\", directoryDefault));\n\n const withHost =\n input.withHost !== undefined ? input.withHost : await promptYesNo(\"Include host?\", false);\n\n return {\n extendsAccount,\n extendsGateway,\n directory,\n account: account || undefined,\n domain: domain || undefined,\n withHost,\n };\n}\n"],"mappings":";;;AAEA,eAAsB,OAAO,UAAkB,cAAwC;CACrF,MAAM,KAAK,gBAAgB;EACzB,OAAO,QAAQ;EACf,QAAQ,QAAQ;EACjB,CAAC;CAGF,MAAM,eAAe,GAAG,WADT,eAAe,KAAK,aAAa,KAAK,GACX;AAE1C,QAAO,IAAI,SAAiB,YAAY;AACtC,KAAG,SAAS,eAAe,WAAW;AACpC,MAAG,OAAO;AAEV,WADgB,OAAO,MAAM,IACV,gBAAgB,GAAG;IACtC;GACF;;AAGJ,eAAsB,YAAY,UAAkB,aAAa,OAAyB;CAExF,MAAM,SAAS,MAAM,OAAO,GAAG,SAAS,IAD3B,aAAa,QAAQ,MACe,GAAG;AACpD,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,OAAO,aAAa,KAAK,OAAO,OAAO,aAAa,KAAK;;AAGlE,SAAS,0BAA0B,QAAwB;AAEzD,QADqB,OAAO,MAAM,IAAI,CAAC,MAChB;;AAGzB,SAAS,wBAAwB,QAAgB,gBAAgC;CAC/E,MAAM,eAAe,OAAO,MAAM,IAAI,CAAC;AACvC,KAAI,CAAC,aAAc,QAAO;AAI1B,QAAO,GAAG,aAAa,GAHR,eAAe,SAAS,IAAI,GACvC,eAAe,UAAU,eAAe,QAAQ,IAAI,GAAG,EAAE,GACzD;;AAIN,eAAsB,kBAAkB,OAcrC;CACD,MAAM,iBACJ,MAAM,kBAAmB,MAAM,OAAO,mBAAmB,sBAAsB;CAEjF,MAAM,iBACJ,MAAM,kBAAmB,MAAM,OAAO,mBAAmB,iBAAiB;CAE5E,MAAM,SAAS,MAAM,UAAW,MAAM,OAAO,iBAAiB;CAE9D,MAAM,iBAAiB,SAAS,wBAAwB,QAAQ,eAAe,GAAG;CAClF,MAAM,UAAU,MAAM,WAAY,MAAM,OAAO,wBAAwB,eAAe;CAEtF,MAAM,mBAAmB,SAAS,0BAA0B,OAAO,GAAG;CACtE,MAAM,YAAY,MAAM,aAAc,MAAM,OAAO,qBAAqB,iBAAiB;CAEzF,MAAM,WACJ,MAAM,aAAa,SAAY,MAAM,WAAW,MAAM,YAAY,iBAAiB,MAAM;AAE3F,QAAO;EACL;EACA;EACA;EACA,SAAS,WAAW;EACpB,QAAQ,UAAU;EAClB;EACD"}