@rebasepro/cli 0.25.1 → 0.26.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 (151) hide show
  1. package/README.md +2 -1
  2. package/bin/rebase.js +143 -4
  3. package/dist/{agent-setup-BYb2Tbdz.js → agent-setup-D9mHRZ5R.js} +125 -3
  4. package/dist/agent-setup-D9mHRZ5R.js.map +1 -0
  5. package/dist/{api-keys-CSMbsmAn.js → api-keys-CyJ26KEJ.js} +41 -9
  6. package/dist/api-keys-CyJ26KEJ.js.map +1 -0
  7. package/dist/{apps-iBXNZhVN.js → apps-CnLDV5b6.js} +6 -6
  8. package/dist/{apps-iBXNZhVN.js.map → apps-CnLDV5b6.js.map} +1 -1
  9. package/dist/{atlas-dev-database-BusbHP6n.js → atlas-dev-database-BODqdCWt.js} +2 -2
  10. package/dist/{atlas-dev-database-BusbHP6n.js.map → atlas-dev-database-BODqdCWt.js.map} +1 -1
  11. package/dist/{auth-DRsTWPky.js → auth-dII2jCO1.js} +10 -7
  12. package/dist/auth-dII2jCO1.js.map +1 -0
  13. package/dist/{branch-pointer-Bn_FjNld.js → branch-pointer-BQUF6lYa.js} +1 -1
  14. package/dist/{build-et7Rccxi.js → build-Cza7ZQrp.js} +6 -6
  15. package/dist/{build-et7Rccxi.js.map → build-Cza7ZQrp.js.map} +1 -1
  16. package/dist/{bundle-DlqkDYSe.js → bundle-C6yEtMJ-.js} +53 -5
  17. package/dist/bundle-C6yEtMJ-.js.map +1 -0
  18. package/dist/bundle.d.ts +14 -0
  19. package/dist/{cloud-B-ZIjHrA.js → cloud-BdnmqQaZ.js} +8527 -4340
  20. package/dist/cloud-BdnmqQaZ.js.map +1 -0
  21. package/dist/collections-dir-DlvDhime.js +69 -0
  22. package/dist/collections-dir-DlvDhime.js.map +1 -0
  23. package/dist/commands/agent-setup.d.ts +58 -0
  24. package/dist/commands/api-keys.d.ts +13 -0
  25. package/dist/commands/cloud/activity.d.ts +25 -0
  26. package/dist/commands/cloud/app-key.d.ts +18 -0
  27. package/dist/commands/cloud/auth.d.ts +1 -0
  28. package/dist/commands/cloud/billing-invoices.d.ts +39 -0
  29. package/dist/commands/cloud/claim.d.ts +7 -0
  30. package/dist/commands/cloud/context.d.ts +115 -6
  31. package/dist/commands/cloud/deploy-summary.d.ts +162 -0
  32. package/dist/commands/cloud/deploy.d.ts +64 -0
  33. package/dist/commands/cloud/env.d.ts +24 -0
  34. package/dist/commands/cloud/index.d.ts +13 -1
  35. package/dist/commands/cloud/init.d.ts +143 -0
  36. package/dist/commands/cloud/login-flow.d.ts +51 -0
  37. package/dist/commands/cloud/notifications.d.ts +28 -0
  38. package/dist/commands/cloud/orgs.d.ts +13 -0
  39. package/dist/commands/cloud/previews.d.ts +123 -0
  40. package/dist/commands/cloud/resources.d.ts +68 -14
  41. package/dist/commands/cloud/runtime-logs.d.ts +176 -0
  42. package/dist/commands/cloud/service-key.d.ts +15 -0
  43. package/dist/commands/cloud/token-capabilities.d.ts +61 -8
  44. package/dist/commands/cloud/tokens.d.ts +18 -3
  45. package/dist/commands/cloud/usage.d.ts +63 -0
  46. package/dist/commands/dev.d.ts +10 -0
  47. package/dist/commands/doctor.d.ts +1 -1
  48. package/dist/commands/generate-view.d.ts +94 -0
  49. package/dist/commands/generate_sdk.d.ts +15 -0
  50. package/dist/commands/skills.d.ts +4 -3
  51. package/dist/commands/storage.d.ts +4 -0
  52. package/dist/commands/verify.d.ts +96 -0
  53. package/dist/{consent-BaB-eQKG.js → consent-BD7F29T3.js} +2 -2
  54. package/dist/{consent-BaB-eQKG.js.map → consent-BD7F29T3.js.map} +1 -1
  55. package/dist/{console-BlD9kjFW.js → console-BXB6-8GT.js} +12 -6
  56. package/dist/console-BXB6-8GT.js.map +1 -0
  57. package/dist/{context-DHiiiJ5C.js → context-GUxkZm-S.js} +481 -24
  58. package/dist/context-GUxkZm-S.js.map +1 -0
  59. package/dist/{daemon-DDMRbz4T.js → daemon-Cp7oNXth.js} +2 -2
  60. package/dist/{daemon-DDMRbz4T.js.map → daemon-Cp7oNXth.js.map} +1 -1
  61. package/dist/{db-9P6MnmdC.js → db-KzlqddGD.js} +37 -30
  62. package/dist/db-KzlqddGD.js.map +1 -0
  63. package/dist/{derive-MTdClnkc.js → derive-ae9UOoOB.js} +2 -2
  64. package/dist/{derive-MTdClnkc.js.map → derive-ae9UOoOB.js.map} +1 -1
  65. package/dist/{dev-BDN_OKXA.js → dev-DTqVMgB3.js} +59 -32
  66. package/dist/dev-DTqVMgB3.js.map +1 -0
  67. package/dist/{dev-preflight-FT9GbJVj.js → dev-preflight-Cxv3TiD1.js} +2 -2
  68. package/dist/{dev-preflight-FT9GbJVj.js.map → dev-preflight-Cxv3TiD1.js.map} +1 -1
  69. package/dist/{dev-server-CIZwAfZa.js → dev-server-OJsUGZEB.js} +2 -2
  70. package/dist/{dev-server-CIZwAfZa.js.map → dev-server-OJsUGZEB.js.map} +1 -1
  71. package/dist/{doctor-D8YXz7df.js → doctor-BRWOlqeG.js} +13 -11
  72. package/dist/doctor-BRWOlqeG.js.map +1 -0
  73. package/dist/{eject-izG2KjMo.js → eject-DABcDnPN.js} +3 -3
  74. package/dist/{eject-izG2KjMo.js.map → eject-DABcDnPN.js.map} +1 -1
  75. package/dist/{fold-static-CybSay_W.js → fold-static-BnAK-anQ.js} +3 -3
  76. package/dist/{fold-static-CybSay_W.js.map → fold-static-BnAK-anQ.js.map} +1 -1
  77. package/dist/generate-view-IFwCADvb.js +662 -0
  78. package/dist/generate-view-IFwCADvb.js.map +1 -0
  79. package/dist/{generate_sdk-B4R65oUV.js → generate_sdk-BvcWvoUh.js} +33 -7
  80. package/dist/generate_sdk-BvcWvoUh.js.map +1 -0
  81. package/dist/index.es.js +57 -38
  82. package/dist/index.es.js.map +1 -1
  83. package/dist/{init-DYaeppEN.js → init-CaU6GhwI.js} +8 -8
  84. package/dist/{init-DYaeppEN.js.map → init-CaU6GhwI.js.map} +1 -1
  85. package/dist/last-dev-database-DpW5dfoX.js +2 -0
  86. package/dist/{manifest-nvPdLlJY.js → manifest-BtzDy7KQ.js} +36 -3
  87. package/dist/{manifest-nvPdLlJY.js.map → manifest-BtzDy7KQ.js.map} +1 -1
  88. package/dist/{normalize-imports-BYw8ad87.js → normalize-imports-D0zXlM6g.js} +3 -3
  89. package/dist/{normalize-imports-BYw8ad87.js.map → normalize-imports-D0zXlM6g.js.map} +1 -1
  90. package/dist/{path-flags-BFgG9V6y.js → path-flags-DNvtEi2-.js} +5 -4
  91. package/dist/path-flags-DNvtEi2-.js.map +1 -0
  92. package/dist/{prepare-1rVNd2PF.js → prepare-CTw9NEkh.js} +4 -4
  93. package/dist/{prepare-1rVNd2PF.js.map → prepare-CTw9NEkh.js.map} +1 -1
  94. package/dist/{project-g4K6kV1t.js → project-CasK56vN.js} +2 -2
  95. package/dist/{project-g4K6kV1t.js.map → project-CasK56vN.js.map} +1 -1
  96. package/dist/resolve-D647F1LA.js +2 -0
  97. package/dist/{resources-CovP8AZ-.js → resources-CPSC5Kcu.js} +4 -4
  98. package/dist/{resources-CovP8AZ-.js.map → resources-CPSC5Kcu.js.map} +1 -1
  99. package/dist/{schema-nuxvvc50.js → schema-BSXwZSiI.js} +9 -7
  100. package/dist/schema-BSXwZSiI.js.map +1 -0
  101. package/dist/{skills-DeUIsZcT.js → skills-BU2flMOy.js} +52 -7
  102. package/dist/skills-BU2flMOy.js.map +1 -0
  103. package/dist/{start-RzZqDroW.js → start-mVb6upwY.js} +5 -5
  104. package/dist/{start-RzZqDroW.js.map → start-mVb6upwY.js.map} +1 -1
  105. package/dist/static-syntax-check.d.ts +64 -0
  106. package/dist/{status-D9Zm88NZ.js → status-BREvtzJm.js} +7 -7
  107. package/dist/{status-D9Zm88NZ.js.map → status-BREvtzJm.js.map} +1 -1
  108. package/dist/{storage-BB3umRfw.js → storage-DtOXGflp.js} +159 -15
  109. package/dist/storage-DtOXGflp.js.map +1 -0
  110. package/dist/{telemetry-HfU5uAh1.js → telemetry-CgwJPVMO.js} +2 -2
  111. package/dist/{telemetry-HfU5uAh1.js.map → telemetry-CgwJPVMO.js.map} +1 -1
  112. package/dist/{telemetry-TseNLk6X.js → telemetry-DwK5RQJl.js} +4 -4
  113. package/dist/{telemetry-TseNLk6X.js.map → telemetry-DwK5RQJl.js.map} +1 -1
  114. package/dist/{upgrade-apiPKKE_.js → upgrade-B7sVwL8S.js} +4 -4
  115. package/dist/{upgrade-apiPKKE_.js.map → upgrade-B7sVwL8S.js.map} +1 -1
  116. package/dist/utils/collections-dir.d.ts +14 -0
  117. package/dist/utils/path-flags.d.ts +2 -1
  118. package/dist/utils/tool-stdio.d.ts +1 -1
  119. package/dist/verify-D7UsV_qe.js +730 -0
  120. package/dist/verify-D7UsV_qe.js.map +1 -0
  121. package/package.json +9 -7
  122. package/templates/eject/backend/src/index.ts +9 -1
  123. package/templates/generated-schemas/ecommerce.ts +3 -0
  124. package/templates/overlays/baas/ai-instructions.md +13 -0
  125. package/templates/template/.claude/hooks/post-edit-collection.sh +99 -0
  126. package/templates/template/.claude/settings.json +17 -0
  127. package/templates/template/.env.example +10 -1
  128. package/templates/template/ai-instructions.md +21 -1
  129. package/templates/template/config/collections/presets/ecommerce/index.ts +23 -0
  130. package/templates/template/docker-compose.yml +4 -1
  131. package/templates/template/frontend/package.json +1 -0
  132. package/templates/views/AppView.tsx.tmpl +138 -0
  133. package/templates/views/EntityView.tsx.tmpl +64 -0
  134. package/templates/views/index.ts.tmpl +8 -0
  135. package/dist/agent-setup-BYb2Tbdz.js.map +0 -1
  136. package/dist/api-keys-CSMbsmAn.js.map +0 -1
  137. package/dist/auth-DRsTWPky.js.map +0 -1
  138. package/dist/bundle-DlqkDYSe.js.map +0 -1
  139. package/dist/cloud-B-ZIjHrA.js.map +0 -1
  140. package/dist/console-BlD9kjFW.js.map +0 -1
  141. package/dist/context-DHiiiJ5C.js.map +0 -1
  142. package/dist/db-9P6MnmdC.js.map +0 -1
  143. package/dist/dev-BDN_OKXA.js.map +0 -1
  144. package/dist/doctor-D8YXz7df.js.map +0 -1
  145. package/dist/generate_sdk-B4R65oUV.js.map +0 -1
  146. package/dist/last-dev-database-B_75fxZC.js +0 -2
  147. package/dist/path-flags-BFgG9V6y.js.map +0 -1
  148. package/dist/resolve-BQUAC3Wi.js +0 -2
  149. package/dist/schema-nuxvvc50.js.map +0 -1
  150. package/dist/skills-DeUIsZcT.js.map +0 -1
  151. package/dist/storage-BB3umRfw.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"apps-iBXNZhVN.js","names":[],"sources":["../src/commands/apps.ts"],"sourcesContent":["/**\n * CLI command: rebase apps\n *\n * Inspect the apps this repository contributes to a project, adopt a\n * `rebase.json` for a project that predates it, and print the client bootstrap\n * an app needs to reach its backend.\n *\n * The distinction that runs through all of this: a *repository* declares apps,\n * a *project* owns them. Two repositories can contribute to the same project and\n * never know about each other, which is what makes a separate frontend repo — or\n * a mobile app with no repo relationship at all — an ordinary thing rather than\n * a special case.\n */\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport type { RebaseAppConfig, RebaseProjectManifest } from \"@rebasepro/types\";\nimport { failAsJson, requireProjectRoot } from \"../utils/project\";\nimport { devServerUrl, runningBackendUrl } from \"../utils/dev-server\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport {\n assessManagedCompatibility,\n findBackendApp,\n formatAppAddress,\n loadManifest,\n ManifestError,\n manifestExists,\n staticAppAddress,\n synthesizeManifest,\n writeManifest\n} from \"../manifest\";\nimport { readLink } from \"./cloud/context\";\nimport { unknownCommand } from \"../utils/unknown-command\";\nimport { foldableApps } from \"../fold-static\";\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase apps\")} — the apps this repository contributes\n\n${chalk.bold(\"Usage\")}\n rebase apps list List declared apps and their build outputs\n rebase apps init Write a rebase.json inferred from this project\n rebase apps config <app> Print the client configuration for an app\n\n${chalk.bold(\"Options\")}\n --json Machine-readable output\n --force Replace an existing rebase.json (apps init), keeping\n each app's name, path and cms\n -h, --help Show this help\n`.trim());\n}\n\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const APPS_SUBCOMMANDS = [\"list\", \"init\", \"config\"] as const;\n\nexport async function appsCommand(subcommand: string | undefined, rawArgs: string[] = []): Promise<void> {\n // Help is answered before parsing, so `rebase apps config --help` prints the\n // page rather than being rejected for naming no app.\n if (!subcommand || subcommand === \"--help\" || wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n // Only `apps` is a command word here: this one parser serves every\n // subcommand, so the subcommand stays in the positionals and the app name\n // `apps config` takes follows it.\n const { flags: args, positionals } = parseCommandArgs({\n spec: {\n \"--json\": Boolean,\n \"--force\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"apps\",\n maxPositionals: 2\n });\n\n switch (subcommand) {\n case \"list\":\n await listApps(Boolean(args[\"--json\"]));\n break;\n case \"init\":\n if (positionals[1] !== undefined) {\n // It never registered one app: the name was ignored and the\n // whole manifest inferred, which is not what the reader asked for.\n console.error(chalk.red(`✗ rebase apps init takes no app name (got \"${positionals[1]}\").`));\n console.error(chalk.dim(\" It infers every app from this project and writes the whole rebase.json.\"));\n console.error(chalk.dim(\" To add one app, declare it under \\\"apps\\\" in rebase.json.\"));\n process.exit(1);\n }\n await initManifest(Boolean(args[\"--force\"]));\n break;\n case \"config\":\n await printAppConfig(positionals[1], Boolean(args[\"--json\"]));\n break;\n default:\n unknownCommand(subcommand, APPS_SUBCOMMANDS, \"apps\");\n }\n}\n\n/**\n * One app's line in `rebase apps list`.\n *\n * A static app shows its full address — the https URL when its `path` gives it\n * a hostname — and the CMS as the address a browser would open. `CMS at /` on\n * an app that lives on `admin.example.com` reads as the project's own root,\n * which is the one place that CMS is not.\n */\nexport function describeApp(name: string, app: RebaseAppConfig): string {\n switch (app.type) {\n case \"backend\":\n return app.runtime === \"custom\"\n // The context is named only when it is not the project, which is\n // the case where it changes what you would type. A workspace app\n // builds from the workspace root, and a listing that showed only\n // the Dockerfile implied a `docker build .` beside it that fails.\n ? `custom runtime — ${app.dockerfile ?? \"Dockerfile\"}`\n + (app.context && app.context !== \".\" ? ` (context: ${app.context})` : \"\")\n : `managed runtime, config: ${app.config ?? \"config\"}`;\n case \"static\": {\n const address = staticAppAddress(name, app);\n return `${app.root} → ${app.output} @ ${formatAppAddress(address)}`\n + (app.cms ? ` ${chalk.magenta(`CMS at ${formatAppAddress({ ...address, path: app.cms })}`)}` : \"\");\n }\n default:\n return \"\";\n }\n}\n\nasync function listApps(asJson: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n const loaded = loadManifestOrExit(projectRoot, asJson);\n const compatibility = assessManagedCompatibility(loaded.manifest);\n\n if (asJson) {\n console.log(JSON.stringify(\n {\n source: loaded.source,\n rebase: loaded.manifest.rebase,\n apps: loaded.manifest.apps,\n managed: compatibility\n },\n null,\n 2\n ));\n return;\n }\n\n if (loaded.source === \"synthesized\") {\n console.log(chalk.dim(\"No rebase.json — showing the layout inferred from this project.\"));\n console.log(chalk.dim(`Run ${chalk.cyan(\"rebase apps init\")} to write it down.\\n`));\n }\n\n console.log(chalk.bold(`Rebase ${loaded.manifest.rebase}`));\n console.log(\"\");\n\n const entries = Object.entries(loaded.manifest.apps);\n if (entries.length === 0) {\n console.log(chalk.yellow(\"No apps declared.\"));\n return;\n }\n\n const width = Math.max(...entries.map(([name]) => name.length));\n for (const [name, app] of entries) {\n console.log(\n ` ${chalk.cyan(name.padEnd(width))} ${chalk.dim(app.type.padEnd(8))} ${describeApp(name, app)}`\n );\n }\n\n console.log(\"\");\n if (compatibility.eligible) {\n console.log(chalk.green(\"✓ Eligible for the managed runtime.\"));\n } else {\n console.log(chalk.yellow(\"• Uses the custom runtime:\"));\n for (const reason of compatibility.reasons) {\n console.log(chalk.dim(` ${reason}`));\n }\n }\n}\n\n/** A static app's `root`, compared as a directory: `./frontend/` is `frontend`. */\nfunction sameRoot(a: string, b: string): boolean {\n const normal = (root: string): string => path.posix.normalize(root.replace(/\\\\/g, \"/\")).replace(/\\/+$/, \"\");\n return normal(a) === normal(b);\n}\n\n/**\n * Re-infer over a manifest the project already declares, keeping what only the\n * declaration knows.\n *\n * An inferred app takes the name the file gives the app it matches — the\n * backend, or the static app with the same `root` — and that app's `path` and\n * `cms`. The name is the app's identity on a deployed project, so renaming it\n * would deploy a second app beside the first. `path` can carry the hostname the\n * app is registered on. `cms` is a client-side route that nothing in the project\n * shows. Everything else is inferred again, which is what `--force` asks for.\n *\n * A declared app the inference does not find is returned in `removed`, so the\n * command can say so rather than drop it in silence.\n */\nfunction keepDeclaredIdentity(\n inferred: RebaseProjectManifest,\n declared: RebaseProjectManifest\n): { manifest: RebaseProjectManifest; removed: Array<{ name: string; app: RebaseAppConfig }> } {\n const apps: Record<string, RebaseAppConfig> = {};\n const matched = new Set<string>();\n\n for (const [name, app] of Object.entries(inferred.apps)) {\n if (app.type === \"backend\") {\n const backend = findBackendApp(declared);\n const keptName = backend && !matched.has(backend.name) ? backend.name : name;\n matched.add(keptName);\n apps[keptName] = app;\n continue;\n }\n const match = Object.entries(declared.apps).find(([declaredName, candidate]) =>\n !matched.has(declaredName) && candidate.type === \"static\" && sameRoot(candidate.root, app.root));\n const declaredApp = match?.[1];\n if (!match || declaredApp?.type !== \"static\") {\n apps[name] = app;\n continue;\n }\n const keptName = match[0];\n matched.add(keptName);\n const address = declaredApp.path ?? app.path;\n apps[keptName] = {\n ...app,\n ...(address !== undefined ? { path: address } : {}),\n ...(declaredApp.cms !== undefined ? { cms: declaredApp.cms } : {})\n };\n }\n\n const removed = Object.entries(declared.apps)\n .filter(([name]) => !matched.has(name))\n .map(([name, app]) => ({ name, app }));\n return { manifest: { ...inferred, apps }, removed };\n}\n\nasync function initManifest(force: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n\n let declared: RebaseProjectManifest | undefined;\n if (manifestExists(projectRoot)) {\n if (!force) {\n console.error(chalk.red(\"✗ rebase.json already exists.\"));\n console.error(chalk.dim(\" Pass --force to replace it with an inferred one, keeping each app's name, path and cms.\"));\n process.exit(1);\n }\n try {\n declared = loadManifest(projectRoot).manifest;\n } catch (err) {\n if (!(err instanceof ManifestError)) throw err;\n const issues = err.issues.map(issue => `${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`);\n console.log(chalk.yellow(\"• The existing rebase.json is invalid, so no app name, path or cms in it is kept:\"));\n for (const issue of issues.length > 0 ? issues : [err.message]) console.log(chalk.dim(` ${issue}`));\n }\n }\n\n const inferred = synthesizeManifest(projectRoot);\n const { manifest, removed } = declared\n ? keepDeclaredIdentity(inferred, declared)\n : { manifest: inferred, removed: [] };\n const filePath = writeManifest(projectRoot, manifest);\n\n console.log(chalk.green(`✓ Wrote ${path.relative(projectRoot, filePath)}`));\n console.log(\"\");\n for (const [name, app] of Object.entries(manifest.apps)) {\n console.log(` ${chalk.cyan(name)} ${chalk.dim(`(${app.type})`)}`);\n }\n for (const { name, app } of removed) {\n const where = app.type === \"static\" ? `, root ${app.root}` : \"\";\n console.log(` ${chalk.yellow(name)} ${chalk.dim(`(${app.type}${where})`)} ${chalk.yellow(\"— not found in this project, removed\")}`);\n }\n\n const compatibility = assessManagedCompatibility(manifest);\n if (!compatibility.eligible) {\n console.log(\"\");\n console.log(chalk.yellow(\"This project will use the custom runtime:\"));\n for (const reason of compatibility.reasons) {\n console.log(chalk.dim(` ${reason}`));\n }\n }\n}\n\n/**\n * Print what a client needs to reach this project.\n *\n * Never prints a secret. The API URL and an app's publishable identity are meant\n * to ship inside a client bundle; anything that is not safe there does not belong\n * in output that will inevitably be pasted into a `.env` that gets committed.\n */\nasync function printAppConfig(appName: string | undefined, asJson: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n const loaded = loadManifestOrExit(projectRoot, asJson);\n\n if (!appName) {\n if (asJson) {\n failAsJson(\"Which app? Usage: rebase apps config <app>\", \"app_not_named\",\n `Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`);\n }\n console.error(chalk.red(\"✗ Which app? Usage: rebase apps config <app>\"));\n process.exit(1);\n }\n\n const app = loaded.manifest.apps[appName];\n if (!app) {\n if (asJson) {\n failAsJson(`No app named \"${appName}\" in rebase.json.`, \"app_not_found\",\n `Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`);\n }\n console.error(chalk.red(`✗ No app named \"${appName}\" in rebase.json.`));\n console.error(chalk.dim(` Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`));\n process.exit(1);\n }\n\n const link = readLink(projectRoot);\n // An app the backend bundle serves calls the API on its own origin, so the\n // right value is empty — wherever the project is linked, and whatever a\n // dev server once wrote down. A URL here is baked into the build and\n // follows the bundle into production.\n const sameOrigin = servedByBackend(loaded.manifest, appName);\n const apiUrl = sameOrigin ? \"\" : resolveApiUrl(projectRoot, link);\n\n const config = {\n app: appName,\n type: app.type,\n apiUrl: apiUrl ?? null,\n sameOrigin,\n project: link?.projectId ?? link?.slug ?? null\n };\n\n if (asJson) {\n console.log(JSON.stringify(config, null, 2));\n return;\n }\n\n if (sameOrigin) {\n console.log(chalk.bold(`# ${appName}`));\n console.log(\"\");\n console.log(\"VITE_API_URL=\");\n console.log(\"\");\n console.log(chalk.dim(`Empty on purpose: \\`rebase build\\` folds ${appName} into the backend bundle, so it`));\n console.log(chalk.dim(\"calls the API on the same origin it is served from, locally and deployed alike.\"));\n console.log(chalk.dim(\"(`rebase dev` points it at the dev backend by itself.)\"));\n return;\n }\n\n // Whether the checkout is linked is a fact about the link, not about\n // whether `rebase dev` happens to be running: a running dev's address\n // used to fill the same slot, and the notice disappeared with it.\n if (!link?.apiUrl) {\n console.log(chalk.yellow(\"This checkout is not linked to a project yet.\"));\n // `rebase cloud link`, not `rebase link`. There has never been a\n // top-level `link` command — `cli.ts` dispatches `cloud`, and the link\n // lives inside that family — so this hint named something that exits 1\n // on the very screen that exists to tell you what to run next.\n console.log(chalk.dim(` Run ${chalk.cyan(\"rebase cloud link\")} (cloud) or ${chalk.cyan(\"rebase cloud link <url>\")} (self-hosted).`));\n console.log(chalk.dim(` Until then, this is the address ${chalk.cyan(\"rebase dev\")} serves this project on.`));\n console.log(\"\");\n }\n\n console.log(chalk.bold(`# ${appName}`));\n console.log(\"\");\n // Unlinked: the dev backend this project runs on, not a fixed 3001 — `rebase dev`\n // derives a port per project.\n console.log(`VITE_API_URL=${apiUrl ?? devServerUrl(projectRoot).url}`);\n console.log(\"\");\n console.log(chalk.dim(\"Then, in the app:\"));\n console.log(chalk.dim(\" const rebase = createRebaseClient({ baseUrl: import.meta.env.VITE_API_URL });\"));\n}\n\n/**\n * Work out the API base URL for this checkout.\n *\n * Prefers an explicit link, then the dev server's own record of where it bound.\n * The dev port is chosen dynamically, so a hardcoded default would be wrong on\n * any machine running more than one project.\n */\nfunction resolveApiUrl(projectRoot: string, link: ReturnType<typeof readLink>): string | undefined {\n if (link?.apiUrl) return link.apiUrl;\n // Only a dev server that is still running: the state file outlives the\n // process, and a port nothing listens on is not an address.\n return runningBackendUrl(projectRoot) ?? undefined;\n}\n\n/**\n * Whether `rebase build` folds this static app into the backend bundle, which\n * then serves it on the API's own origin: a managed backend, and an app with\n * built output to fold. The same predicate the build folds by.\n */\nexport function servedByBackend(manifest: ReturnType<typeof loadManifest>[\"manifest\"], appName: string): boolean {\n const backend = findBackendApp(manifest);\n if (!backend || backend.app.type !== \"backend\" || backend.app.runtime === \"custom\") return false;\n return foldableApps(manifest).apps.some(app => app.name === appName);\n}\n\nfunction loadManifestOrExit(projectRoot: string, asJson = false): ReturnType<typeof loadManifest> {\n try {\n return loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n // A caller that asked for JSON gets one on this exit too. It used\n // to get the human bullet list on stderr and an empty stdout —\n // `apps list --json` against the one manifest a caller most needs\n // to be told about.\n if (asJson) {\n failAsJson(err.message, \"manifest_invalid\", \"Fix rebase.json, then run this again.\",\n err.issues.map(issue => ({ path: issue.path, message: issue.message })));\n }\n console.error(chalk.red(`✗ ${err.message}`));\n for (const issue of err.issues) {\n console.error(chalk.red(` ${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`));\n }\n process.exit(1);\n }\n throw err;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"apps-CnLDV5b6.js","names":[],"sources":["../src/commands/apps.ts"],"sourcesContent":["/**\n * CLI command: rebase apps\n *\n * Inspect the apps this repository contributes to a project, adopt a\n * `rebase.json` for a project that predates it, and print the client bootstrap\n * an app needs to reach its backend.\n *\n * The distinction that runs through all of this: a *repository* declares apps,\n * a *project* owns them. Two repositories can contribute to the same project and\n * never know about each other, which is what makes a separate frontend repo — or\n * a mobile app with no repo relationship at all — an ordinary thing rather than\n * a special case.\n */\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport type { RebaseAppConfig, RebaseProjectManifest } from \"@rebasepro/types\";\nimport { failAsJson, requireProjectRoot } from \"../utils/project\";\nimport { devServerUrl, runningBackendUrl } from \"../utils/dev-server\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport {\n assessManagedCompatibility,\n findBackendApp,\n formatAppAddress,\n loadManifest,\n ManifestError,\n manifestExists,\n staticAppAddress,\n synthesizeManifest,\n writeManifest\n} from \"../manifest\";\nimport { readLink } from \"./cloud/context\";\nimport { unknownCommand } from \"../utils/unknown-command\";\nimport { foldableApps } from \"../fold-static\";\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase apps\")} — the apps this repository contributes\n\n${chalk.bold(\"Usage\")}\n rebase apps list List declared apps and their build outputs\n rebase apps init Write a rebase.json inferred from this project\n rebase apps config <app> Print the client configuration for an app\n\n${chalk.bold(\"Options\")}\n --json Machine-readable output\n --force Replace an existing rebase.json (apps init), keeping\n each app's name, path and cms\n -h, --help Show this help\n`.trim());\n}\n\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const APPS_SUBCOMMANDS = [\"list\", \"init\", \"config\"] as const;\n\nexport async function appsCommand(subcommand: string | undefined, rawArgs: string[] = []): Promise<void> {\n // Help is answered before parsing, so `rebase apps config --help` prints the\n // page rather than being rejected for naming no app.\n if (!subcommand || subcommand === \"--help\" || wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n // Only `apps` is a command word here: this one parser serves every\n // subcommand, so the subcommand stays in the positionals and the app name\n // `apps config` takes follows it.\n const { flags: args, positionals } = parseCommandArgs({\n spec: {\n \"--json\": Boolean,\n \"--force\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"apps\",\n maxPositionals: 2\n });\n\n switch (subcommand) {\n case \"list\":\n await listApps(Boolean(args[\"--json\"]));\n break;\n case \"init\":\n if (positionals[1] !== undefined) {\n // It never registered one app: the name was ignored and the\n // whole manifest inferred, which is not what the reader asked for.\n console.error(chalk.red(`✗ rebase apps init takes no app name (got \"${positionals[1]}\").`));\n console.error(chalk.dim(\" It infers every app from this project and writes the whole rebase.json.\"));\n console.error(chalk.dim(\" To add one app, declare it under \\\"apps\\\" in rebase.json.\"));\n process.exit(1);\n }\n await initManifest(Boolean(args[\"--force\"]));\n break;\n case \"config\":\n await printAppConfig(positionals[1], Boolean(args[\"--json\"]));\n break;\n default:\n unknownCommand(subcommand, APPS_SUBCOMMANDS, \"apps\");\n }\n}\n\n/**\n * One app's line in `rebase apps list`.\n *\n * A static app shows its full address — the https URL when its `path` gives it\n * a hostname — and the CMS as the address a browser would open. `CMS at /` on\n * an app that lives on `admin.example.com` reads as the project's own root,\n * which is the one place that CMS is not.\n */\nexport function describeApp(name: string, app: RebaseAppConfig): string {\n switch (app.type) {\n case \"backend\":\n return app.runtime === \"custom\"\n // The context is named only when it is not the project, which is\n // the case where it changes what you would type. A workspace app\n // builds from the workspace root, and a listing that showed only\n // the Dockerfile implied a `docker build .` beside it that fails.\n ? `custom runtime — ${app.dockerfile ?? \"Dockerfile\"}`\n + (app.context && app.context !== \".\" ? ` (context: ${app.context})` : \"\")\n : `managed runtime, config: ${app.config ?? \"config\"}`;\n case \"static\": {\n const address = staticAppAddress(name, app);\n return `${app.root} → ${app.output} @ ${formatAppAddress(address)}`\n + (app.cms ? ` ${chalk.magenta(`CMS at ${formatAppAddress({ ...address, path: app.cms })}`)}` : \"\");\n }\n default:\n return \"\";\n }\n}\n\nasync function listApps(asJson: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n const loaded = loadManifestOrExit(projectRoot, asJson);\n const compatibility = assessManagedCompatibility(loaded.manifest);\n\n if (asJson) {\n console.log(JSON.stringify(\n {\n source: loaded.source,\n rebase: loaded.manifest.rebase,\n apps: loaded.manifest.apps,\n managed: compatibility\n },\n null,\n 2\n ));\n return;\n }\n\n if (loaded.source === \"synthesized\") {\n console.log(chalk.dim(\"No rebase.json — showing the layout inferred from this project.\"));\n console.log(chalk.dim(`Run ${chalk.cyan(\"rebase apps init\")} to write it down.\\n`));\n }\n\n console.log(chalk.bold(`Rebase ${loaded.manifest.rebase}`));\n console.log(\"\");\n\n const entries = Object.entries(loaded.manifest.apps);\n if (entries.length === 0) {\n console.log(chalk.yellow(\"No apps declared.\"));\n return;\n }\n\n const width = Math.max(...entries.map(([name]) => name.length));\n for (const [name, app] of entries) {\n console.log(\n ` ${chalk.cyan(name.padEnd(width))} ${chalk.dim(app.type.padEnd(8))} ${describeApp(name, app)}`\n );\n }\n\n console.log(\"\");\n if (compatibility.eligible) {\n console.log(chalk.green(\"✓ Eligible for the managed runtime.\"));\n } else {\n console.log(chalk.yellow(\"• Uses the custom runtime:\"));\n for (const reason of compatibility.reasons) {\n console.log(chalk.dim(` ${reason}`));\n }\n }\n}\n\n/** A static app's `root`, compared as a directory: `./frontend/` is `frontend`. */\nfunction sameRoot(a: string, b: string): boolean {\n const normal = (root: string): string => path.posix.normalize(root.replace(/\\\\/g, \"/\")).replace(/\\/+$/, \"\");\n return normal(a) === normal(b);\n}\n\n/**\n * Re-infer over a manifest the project already declares, keeping what only the\n * declaration knows.\n *\n * An inferred app takes the name the file gives the app it matches — the\n * backend, or the static app with the same `root` — and that app's `path` and\n * `cms`. The name is the app's identity on a deployed project, so renaming it\n * would deploy a second app beside the first. `path` can carry the hostname the\n * app is registered on. `cms` is a client-side route that nothing in the project\n * shows. Everything else is inferred again, which is what `--force` asks for.\n *\n * A declared app the inference does not find is returned in `removed`, so the\n * command can say so rather than drop it in silence.\n */\nfunction keepDeclaredIdentity(\n inferred: RebaseProjectManifest,\n declared: RebaseProjectManifest\n): { manifest: RebaseProjectManifest; removed: Array<{ name: string; app: RebaseAppConfig }> } {\n const apps: Record<string, RebaseAppConfig> = {};\n const matched = new Set<string>();\n\n for (const [name, app] of Object.entries(inferred.apps)) {\n if (app.type === \"backend\") {\n const backend = findBackendApp(declared);\n const keptName = backend && !matched.has(backend.name) ? backend.name : name;\n matched.add(keptName);\n apps[keptName] = app;\n continue;\n }\n const match = Object.entries(declared.apps).find(([declaredName, candidate]) =>\n !matched.has(declaredName) && candidate.type === \"static\" && sameRoot(candidate.root, app.root));\n const declaredApp = match?.[1];\n if (!match || declaredApp?.type !== \"static\") {\n apps[name] = app;\n continue;\n }\n const keptName = match[0];\n matched.add(keptName);\n const address = declaredApp.path ?? app.path;\n apps[keptName] = {\n ...app,\n ...(address !== undefined ? { path: address } : {}),\n ...(declaredApp.cms !== undefined ? { cms: declaredApp.cms } : {})\n };\n }\n\n const removed = Object.entries(declared.apps)\n .filter(([name]) => !matched.has(name))\n .map(([name, app]) => ({ name, app }));\n return { manifest: { ...inferred, apps }, removed };\n}\n\nasync function initManifest(force: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n\n let declared: RebaseProjectManifest | undefined;\n if (manifestExists(projectRoot)) {\n if (!force) {\n console.error(chalk.red(\"✗ rebase.json already exists.\"));\n console.error(chalk.dim(\" Pass --force to replace it with an inferred one, keeping each app's name, path and cms.\"));\n process.exit(1);\n }\n try {\n declared = loadManifest(projectRoot).manifest;\n } catch (err) {\n if (!(err instanceof ManifestError)) throw err;\n const issues = err.issues.map(issue => `${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`);\n console.log(chalk.yellow(\"• The existing rebase.json is invalid, so no app name, path or cms in it is kept:\"));\n for (const issue of issues.length > 0 ? issues : [err.message]) console.log(chalk.dim(` ${issue}`));\n }\n }\n\n const inferred = synthesizeManifest(projectRoot);\n const { manifest, removed } = declared\n ? keepDeclaredIdentity(inferred, declared)\n : { manifest: inferred, removed: [] };\n const filePath = writeManifest(projectRoot, manifest);\n\n console.log(chalk.green(`✓ Wrote ${path.relative(projectRoot, filePath)}`));\n console.log(\"\");\n for (const [name, app] of Object.entries(manifest.apps)) {\n console.log(` ${chalk.cyan(name)} ${chalk.dim(`(${app.type})`)}`);\n }\n for (const { name, app } of removed) {\n const where = app.type === \"static\" ? `, root ${app.root}` : \"\";\n console.log(` ${chalk.yellow(name)} ${chalk.dim(`(${app.type}${where})`)} ${chalk.yellow(\"— not found in this project, removed\")}`);\n }\n\n const compatibility = assessManagedCompatibility(manifest);\n if (!compatibility.eligible) {\n console.log(\"\");\n console.log(chalk.yellow(\"This project will use the custom runtime:\"));\n for (const reason of compatibility.reasons) {\n console.log(chalk.dim(` ${reason}`));\n }\n }\n}\n\n/**\n * Print what a client needs to reach this project.\n *\n * Never prints a secret. The API URL and an app's publishable identity are meant\n * to ship inside a client bundle; anything that is not safe there does not belong\n * in output that will inevitably be pasted into a `.env` that gets committed.\n */\nasync function printAppConfig(appName: string | undefined, asJson: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n const loaded = loadManifestOrExit(projectRoot, asJson);\n\n if (!appName) {\n if (asJson) {\n failAsJson(\"Which app? Usage: rebase apps config <app>\", \"app_not_named\",\n `Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`);\n }\n console.error(chalk.red(\"✗ Which app? Usage: rebase apps config <app>\"));\n process.exit(1);\n }\n\n const app = loaded.manifest.apps[appName];\n if (!app) {\n if (asJson) {\n failAsJson(`No app named \"${appName}\" in rebase.json.`, \"app_not_found\",\n `Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`);\n }\n console.error(chalk.red(`✗ No app named \"${appName}\" in rebase.json.`));\n console.error(chalk.dim(` Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`));\n process.exit(1);\n }\n\n const link = readLink(projectRoot);\n // An app the backend bundle serves calls the API on its own origin, so the\n // right value is empty — wherever the project is linked, and whatever a\n // dev server once wrote down. A URL here is baked into the build and\n // follows the bundle into production.\n const sameOrigin = servedByBackend(loaded.manifest, appName);\n const apiUrl = sameOrigin ? \"\" : resolveApiUrl(projectRoot, link);\n\n const config = {\n app: appName,\n type: app.type,\n apiUrl: apiUrl ?? null,\n sameOrigin,\n project: link?.projectId ?? link?.slug ?? null\n };\n\n if (asJson) {\n console.log(JSON.stringify(config, null, 2));\n return;\n }\n\n if (sameOrigin) {\n console.log(chalk.bold(`# ${appName}`));\n console.log(\"\");\n console.log(\"VITE_API_URL=\");\n console.log(\"\");\n console.log(chalk.dim(`Empty on purpose: \\`rebase build\\` folds ${appName} into the backend bundle, so it`));\n console.log(chalk.dim(\"calls the API on the same origin it is served from, locally and deployed alike.\"));\n console.log(chalk.dim(\"(`rebase dev` points it at the dev backend by itself.)\"));\n return;\n }\n\n // Whether the checkout is linked is a fact about the link, not about\n // whether `rebase dev` happens to be running: a running dev's address\n // used to fill the same slot, and the notice disappeared with it.\n if (!link?.apiUrl) {\n console.log(chalk.yellow(\"This checkout is not linked to a project yet.\"));\n // `rebase cloud link`, not `rebase link`. There has never been a\n // top-level `link` command — `cli.ts` dispatches `cloud`, and the link\n // lives inside that family — so this hint named something that exits 1\n // on the very screen that exists to tell you what to run next.\n console.log(chalk.dim(` Run ${chalk.cyan(\"rebase cloud link\")} (cloud) or ${chalk.cyan(\"rebase cloud link <url>\")} (self-hosted).`));\n console.log(chalk.dim(` Until then, this is the address ${chalk.cyan(\"rebase dev\")} serves this project on.`));\n console.log(\"\");\n }\n\n console.log(chalk.bold(`# ${appName}`));\n console.log(\"\");\n // Unlinked: the dev backend this project runs on, not a fixed 3001 — `rebase dev`\n // derives a port per project.\n console.log(`VITE_API_URL=${apiUrl ?? devServerUrl(projectRoot).url}`);\n console.log(\"\");\n console.log(chalk.dim(\"Then, in the app:\"));\n console.log(chalk.dim(\" const rebase = createRebaseClient({ baseUrl: import.meta.env.VITE_API_URL });\"));\n}\n\n/**\n * Work out the API base URL for this checkout.\n *\n * Prefers an explicit link, then the dev server's own record of where it bound.\n * The dev port is chosen dynamically, so a hardcoded default would be wrong on\n * any machine running more than one project.\n */\nfunction resolveApiUrl(projectRoot: string, link: ReturnType<typeof readLink>): string | undefined {\n if (link?.apiUrl) return link.apiUrl;\n // Only a dev server that is still running: the state file outlives the\n // process, and a port nothing listens on is not an address.\n return runningBackendUrl(projectRoot) ?? undefined;\n}\n\n/**\n * Whether `rebase build` folds this static app into the backend bundle, which\n * then serves it on the API's own origin: a managed backend, and an app with\n * built output to fold. The same predicate the build folds by.\n */\nexport function servedByBackend(manifest: ReturnType<typeof loadManifest>[\"manifest\"], appName: string): boolean {\n const backend = findBackendApp(manifest);\n if (!backend || backend.app.type !== \"backend\" || backend.app.runtime === \"custom\") return false;\n return foldableApps(manifest).apps.some(app => app.name === appName);\n}\n\nfunction loadManifestOrExit(projectRoot: string, asJson = false): ReturnType<typeof loadManifest> {\n try {\n return loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n // A caller that asked for JSON gets one on this exit too. It used\n // to get the human bullet list on stderr and an empty stdout —\n // `apps list --json` against the one manifest a caller most needs\n // to be told about.\n if (asJson) {\n failAsJson(err.message, \"manifest_invalid\", \"Fix rebase.json, then run this again.\",\n err.issues.map(issue => ({ path: issue.path, message: issue.message })));\n }\n console.error(chalk.red(`✗ ${err.message}`));\n for (const issue of err.issues) {\n console.error(chalk.red(` ${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`));\n }\n process.exit(1);\n }\n throw err;\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { s as findFreePort } from "./state-CYdBvnwA.js";
2
- import { i as managedUrl } from "./daemon-DDMRbz4T.js";
2
+ import { i as managedUrl } from "./daemon-Cp7oNXth.js";
3
3
  import { loadExtensions } from "./daemon-entry-zOC1revO.js";
4
4
  //#region src/dev-db/atlas-dev-database.ts
5
5
  /**
@@ -59,4 +59,4 @@ async function startAtlasDevDatabase() {
59
59
  //#endregion
60
60
  export { startAtlasDevDatabase };
61
61
 
62
- //# sourceMappingURL=atlas-dev-database-BusbHP6n.js.map
62
+ //# sourceMappingURL=atlas-dev-database-BODqdCWt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"atlas-dev-database-BusbHP6n.js","names":[],"sources":["../src/dev-db/atlas-dev-database.ts"],"sourcesContent":["/**\n * A second, throwaway PGlite for Atlas to plan against.\n *\n * Atlas computes a schema change by replaying the desired schema into an\n * **empty** database and diffing. On a real server the driver makes one as\n * `<db>_dev_diff`; PGlite serves exactly one database, so that `CREATE\n * DATABASE` succeeds and creates nothing, and `rebase db push`, `generate` and\n * `migrate` were refused on the managed database outright — which left it with\n * no way to drop, rename or narrow a column: boot only ever adds.\n *\n * So the command that needs one starts one: in memory, in this process, for\n * as long as the command runs. It shares nothing with the managed database's\n * daemon (a separate instance, no data directory, a port of its own), so the\n * project's data is never the thing Atlas fills and clears, and nothing is\n * left behind — not a directory, not a process.\n *\n * Measured with Atlas 1.2.3 against PGlite 0.5.6: `schema apply` with this as\n * `--dev-url` plans and applies a DROP COLUMN and a `varchar(200)` →\n * `varchar(50)` narrowing on a PGlite target, and the dev database is empty\n * again afterwards, so one instance serves every Atlas call of a command.\n *\n * It runs on this process's event loop. The driver runs as a child process,\n * which is what keeps the loop free to serve it; a synchronous wait on that\n * child would hang Atlas.\n */\n\nimport { loadExtensions } from \"./daemon-entry\";\nimport { MANAGED_SERVER_MAX_CONNECTIONS } from \"./constraints\";\nimport { managedUrl } from \"./daemon\";\nimport { findFreePort } from \"./state\";\n\nexport interface AtlasDevDatabase {\n /** Connection string for Atlas's `--dev-url`. */\n url: string;\n /** Stop serving and drop the instance. Safe to call twice. */\n stop(): Promise<void>;\n}\n\nexport async function startAtlasDevDatabase(): Promise<AtlasDevDatabase> {\n const { PGlite } = (await import(\"@electric-sql/pglite\")) as {\n PGlite: { create(options: unknown): Promise<unknown> };\n };\n const { PGLiteSocketServer } = (await import(\"@electric-sql/pglite-socket\")) as {\n PGLiteSocketServer: new (options: unknown) => { start(): Promise<void>; stop(): Promise<void> };\n };\n\n // The same extension bundles as the managed database: a schema that\n // creates `pg_trgm` or `vector` must replay here exactly as it applies\n // there, or Atlas fails on the replay rather than the apply.\n const extensions = await loadExtensions();\n // No `dataDir`: in memory, gone with the process.\n const db = (await PGlite.create({ extensions })) as { close(): Promise<void> };\n const port = await findFreePort();\n const server = new PGLiteSocketServer({\n db,\n port,\n host: \"127.0.0.1\",\n maxConnections: MANAGED_SERVER_MAX_CONNECTIONS\n });\n try {\n await server.start();\n } catch (err) {\n await db.close().catch(() => undefined);\n throw err;\n }\n\n let stopped = false;\n return {\n url: managedUrl(port),\n async stop() {\n if (stopped) return;\n stopped = true;\n await server.stop().catch(() => undefined);\n await db.close().catch(() => undefined);\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,eAAsB,wBAAmD;CACrE,MAAM,EAAE,WAAY,MAAM,OAAO;CAGjC,MAAM,EAAE,uBAAwB,MAAM,OAAO;CAO7C,MAAM,aAAa,MAAM,eAAe;CAExC,MAAM,KAAM,MAAM,OAAO,OAAO,EAAE,WAAW,CAAC;CAC9C,MAAM,OAAO,MAAM,aAAa;CAChC,MAAM,SAAS,IAAI,mBAAmB;EAClC;EACA;EACA,MAAM;EACN,gBAAA;CACJ,CAAC;CACD,IAAI;EACA,MAAM,OAAO,MAAM;CACvB,SAAS,KAAK;EACV,MAAM,GAAG,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EACtC,MAAM;CACV;CAEA,IAAI,UAAU;CACd,OAAO;EACH,KAAK,WAAW,IAAI;EACpB,MAAM,OAAO;GACT,IAAI,SAAS;GACb,UAAU;GACV,MAAM,OAAO,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;GACzC,MAAM,GAAG,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EAC1C;CACJ;AACJ"}
1
+ {"version":3,"file":"atlas-dev-database-BODqdCWt.js","names":[],"sources":["../src/dev-db/atlas-dev-database.ts"],"sourcesContent":["/**\n * A second, throwaway PGlite for Atlas to plan against.\n *\n * Atlas computes a schema change by replaying the desired schema into an\n * **empty** database and diffing. On a real server the driver makes one as\n * `<db>_dev_diff`; PGlite serves exactly one database, so that `CREATE\n * DATABASE` succeeds and creates nothing, and `rebase db push`, `generate` and\n * `migrate` were refused on the managed database outright — which left it with\n * no way to drop, rename or narrow a column: boot only ever adds.\n *\n * So the command that needs one starts one: in memory, in this process, for\n * as long as the command runs. It shares nothing with the managed database's\n * daemon (a separate instance, no data directory, a port of its own), so the\n * project's data is never the thing Atlas fills and clears, and nothing is\n * left behind — not a directory, not a process.\n *\n * Measured with Atlas 1.2.3 against PGlite 0.5.6: `schema apply` with this as\n * `--dev-url` plans and applies a DROP COLUMN and a `varchar(200)` →\n * `varchar(50)` narrowing on a PGlite target, and the dev database is empty\n * again afterwards, so one instance serves every Atlas call of a command.\n *\n * It runs on this process's event loop. The driver runs as a child process,\n * which is what keeps the loop free to serve it; a synchronous wait on that\n * child would hang Atlas.\n */\n\nimport { loadExtensions } from \"./daemon-entry\";\nimport { MANAGED_SERVER_MAX_CONNECTIONS } from \"./constraints\";\nimport { managedUrl } from \"./daemon\";\nimport { findFreePort } from \"./state\";\n\nexport interface AtlasDevDatabase {\n /** Connection string for Atlas's `--dev-url`. */\n url: string;\n /** Stop serving and drop the instance. Safe to call twice. */\n stop(): Promise<void>;\n}\n\nexport async function startAtlasDevDatabase(): Promise<AtlasDevDatabase> {\n const { PGlite } = (await import(\"@electric-sql/pglite\")) as {\n PGlite: { create(options: unknown): Promise<unknown> };\n };\n const { PGLiteSocketServer } = (await import(\"@electric-sql/pglite-socket\")) as {\n PGLiteSocketServer: new (options: unknown) => { start(): Promise<void>; stop(): Promise<void> };\n };\n\n // The same extension bundles as the managed database: a schema that\n // creates `pg_trgm` or `vector` must replay here exactly as it applies\n // there, or Atlas fails on the replay rather than the apply.\n const extensions = await loadExtensions();\n // No `dataDir`: in memory, gone with the process.\n const db = (await PGlite.create({ extensions })) as { close(): Promise<void> };\n const port = await findFreePort();\n const server = new PGLiteSocketServer({\n db,\n port,\n host: \"127.0.0.1\",\n maxConnections: MANAGED_SERVER_MAX_CONNECTIONS\n });\n try {\n await server.start();\n } catch (err) {\n await db.close().catch(() => undefined);\n throw err;\n }\n\n let stopped = false;\n return {\n url: managedUrl(port),\n async stop() {\n if (stopped) return;\n stopped = true;\n await server.stop().catch(() => undefined);\n await db.close().catch(() => undefined);\n }\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,eAAsB,wBAAmD;CACrE,MAAM,EAAE,WAAY,MAAM,OAAO;CAGjC,MAAM,EAAE,uBAAwB,MAAM,OAAO;CAO7C,MAAM,aAAa,MAAM,eAAe;CAExC,MAAM,KAAM,MAAM,OAAO,OAAO,EAAE,WAAW,CAAC;CAC9C,MAAM,OAAO,MAAM,aAAa;CAChC,MAAM,SAAS,IAAI,mBAAmB;EAClC;EACA;EACA,MAAM;EACN,gBAAA;CACJ,CAAC;CACD,IAAI;EACA,MAAM,OAAO,MAAM;CACvB,SAAS,KAAK;EACV,MAAM,GAAG,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EACtC,MAAM;CACV;CAEA,IAAI,UAAU;CACd,OAAO;EACH,KAAK,WAAW,IAAI;EACpB,MAAM,OAAO;GACT,IAAI,SAAS;GACb,UAAU;GACV,MAAM,OAAO,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;GACzC,MAAM,GAAG,MAAM,CAAC,CAAC,YAAY,KAAA,CAAS;EAC1C;CACJ;AACJ"}
@@ -1,5 +1,5 @@
1
- import { C as wantsHelp, D as redactConnectionPasswords, T as unknownCommand, b as parseCommandArgs, d as readEnvFile, f as requireBackendDir, g as resolveTsx, o as findEnvFile, p as requireProjectRoot, r as exitDependenciesNotInstalled } from "./project-g4K6kV1t.js";
2
- import { resolveBackendAddress } from "./api-keys-CSMbsmAn.js";
1
+ import { E as unknownCommand, O as redactConnectionPasswords, d as readEnvFile, f as requireBackendDir, g as resolveTsx, o as findEnvFile, p as requireProjectRoot, r as exitDependenciesNotInstalled, w as wantsHelp, x as parseCommandArgs } from "./project-CasK56vN.js";
2
+ import { cloudTargetNote, resolveBackendAddress } from "./api-keys-CyJ26KEJ.js";
3
3
  import chalk from "chalk";
4
4
  import fs from "fs";
5
5
  import path from "path";
@@ -165,7 +165,10 @@ async function resetPassword(rawArgs) {
165
165
  const state = JSON.parse(fs.readFileSync(statePath, "utf8"));
166
166
  if (state && typeof state === "object" && typeof state.serviceKey === "string" && !serviceKey) serviceKey = state.serviceKey;
167
167
  } catch {}
168
- const baseUrl = resolveBackendAddress(readEnvFile(projectRoot), projectRoot).url;
168
+ const address = resolveBackendAddress(readEnvFile(projectRoot), projectRoot);
169
+ const cloudNote = cloudTargetNote(address);
170
+ if (cloudNote) console.error(chalk.yellow(` ⚠ ${cloudNote}`));
171
+ const baseUrl = address.url;
169
172
  if (baseUrl && serviceKey) {
170
173
  console.log("Trying API-first reset via running backend...");
171
174
  try {
@@ -215,16 +218,16 @@ async function resetPassword(rawArgs) {
215
218
  if (!tsxBin) exitDependenciesNotInstalled(projectRoot);
216
219
  let prepared;
217
220
  try {
218
- const { ensureDockerDatabase } = await import("./db-9P6MnmdC.js");
221
+ const { ensureDockerDatabase } = await import("./db-KzlqddGD.js");
219
222
  await ensureDockerDatabase(projectRoot, rawArgs);
220
- const { prepareDatabaseEnv } = await import("./prepare-1rVNd2PF.js");
223
+ const { prepareDatabaseEnv } = await import("./prepare-CTw9NEkh.js");
221
224
  prepared = await prepareDatabaseEnv(projectRoot, { onProgress: (message) => console.log(chalk.gray(` ${message}`)) });
222
225
  } catch (err) {
223
226
  console.error(chalk.red("✗ Direct database update failed."));
224
227
  console.error(err instanceof Error ? err.message : String(err));
225
228
  process.exit(1);
226
229
  }
227
- const { databaseUrlOf } = await import("./db-9P6MnmdC.js");
230
+ const { databaseUrlOf } = await import("./db-KzlqddGD.js");
228
231
  const url = databaseUrlOf(prepared, readEnvFile(projectRoot));
229
232
  if (url) {
230
233
  const failure = await databaseOpenFailure(url, prepared.database.source);
@@ -470,4 +473,4 @@ ${chalk.green.bold("Examples")}
470
473
  //#endregion
471
474
  export { AUTH_SUBCOMMANDS, authCommand };
472
475
 
473
- //# sourceMappingURL=auth-DRsTWPky.js.map
476
+ //# sourceMappingURL=auth-dII2jCO1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-dII2jCO1.js","names":[],"sources":["../src/commands/auth.ts"],"sourcesContent":["/**\n * CLI command: rebase auth <action>\n *\n * Subcommands:\n * reset-password — Reset a user's password\n */\nimport chalk from \"chalk\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { spawn } from \"child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n requireProjectRoot,\n requireBackendDir,\n findEnvFile,\n readEnvFile,\n resolveTsx,\n exitDependenciesNotInstalled\n} from \"../utils/project\";\nimport { parseEnvBoolean } from \"@rebasepro/types\";\nimport { unknownCommand } from \"../utils/unknown-command\";\nimport { redactConnectionPasswords } from \"../utils/redact\";\nimport type { PreparedDatabase } from \"../dev-db/prepare\";\nimport type { DevDatabaseSource } from \"../dev-db/resolve\";\n\n/** The backend was reached and refused: not a reason to fall back to the database. */\nclass ApiAnswered extends Error {}\n\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const AUTH_SUBCOMMANDS = [\"reset-password\"] as const;\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { cloudTargetNote, resolveBackendAddress } from \"./api-keys\";\n\n/** A user as the admin API returns it, reduced to what this command needs. */\nexport interface ResolvedUser {\n id: string;\n email: string;\n}\n\n/**\n * Pick the user with exactly this email out of a search response.\n *\n * `/api/admin/users?search=` is an `ILIKE '%…%'` over email **or display\n * name**, ordered by role count descending. This used to take row `[0]` and\n * reset it, then print the email it had been *given* as confirmation — so two\n * ordinary situations ended in a successful-looking reset of somebody else's\n * account:\n *\n * - a substring collision: `bob@example.com` also matches\n * `robert.bob@example.com`;\n * - a display name, which is user-controlled and accepted up to 255\n * characters with no constraint on its content, containing an address\n * belonging to someone else.\n *\n * The ordering makes it worse rather than better — `array_length(roles) DESC\n * NULLS LAST` puts the most privileged match first, so the account most likely\n * to be reset by mistake is an admin's.\n *\n * Returns `undefined` when nothing matched exactly, which the caller reports\n * rather than falling through to a guess. The direct-database fallback below\n * has always matched with `eq(usersTable.email, email)`; this is the same\n * definition, so the command no longer resets different accounts depending on\n * whether the backend happened to be running.\n */\nexport function selectUserForEmail(payload: unknown, email: string): ResolvedUser | undefined {\n const wanted = email.trim().toLowerCase();\n if (!wanted) return undefined;\n\n const rows: unknown[] = Array.isArray(payload)\n ? payload\n : (payload && typeof payload === \"object\" && Array.isArray((payload as { users?: unknown }).users)\n ? (payload as { users: unknown[] }).users\n : []);\n\n for (const row of rows) {\n if (!row || typeof row !== \"object\") continue;\n const record = row as Record<string, unknown>;\n const rowEmail = typeof record.email === \"string\" ? record.email.trim().toLowerCase() : undefined;\n if (!rowEmail || rowEmail !== wanted) continue;\n\n const id = typeof record.id === \"string\"\n ? record.id\n : (typeof record.uid === \"string\" ? record.uid : undefined);\n if (!id) continue;\n\n return { id, email: record.email as string };\n }\n\n return undefined;\n}\n\nexport async function authCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n // `--help` is answered here and never reaches a handler. `cli.ts` only\n // rewrites the subcommand to `\"--help\"` when no subcommand was named, so\n // `rebase auth reset-password --help` used to *run the reset*: `--help`\n // became the email, the backend was contacted, `.tmp-reset-password.ts` was\n // written into the user's `backend/`, and a database UPDATE ran for a user\n // named `--help`. A flag whose whole job is to print text cannot be allowed\n // to reach code that writes.\n if (!subcommand || subcommand === \"--help\" || wantsHelp(rawArgs)) {\n printAuthHelp();\n return;\n }\n\n switch (subcommand) {\n case \"reset-password\":\n await resetPassword(rawArgs);\n break;\n default:\n unknownCommand(subcommand, AUTH_SUBCOMMANDS, \"auth\");\n }\n}\n\n/**\n * The flags `rebase auth reset-password` takes.\n *\n * `-p` was advertised in this command's own help and never declared here, so\n * `arg` — running permissively — pushed it into the positionals and the value\n * *after* it shifted out of reach: anyone following the help set the account's\n * password to the two-character string `-p`. Declared now, and `auth.test.ts`\n * asserts that the help and this spec list the same aliases.\n */\nexport const RESET_PASSWORD_FLAGS = {\n \"--email\": String,\n \"--password\": String,\n \"-e\": \"--email\",\n \"-p\": \"--password\"\n} as const;\n\n/**\n * Which account, and which password, this invocation names.\n *\n * Both may still be absent — the caller reports a missing email — but neither\n * can be a flag. `parseCommandArgs` parses the whole line strictly, so an\n * undeclared flag is an error rather than a positional. That is what stops\n * `rebase auth reset-password bob@example.com --debug` from setting Bob's\n * password to `--debug`, which is the flag the CLI itself prints after every\n * failure as the thing to re-run with.\n *\n * Exported so its tests can drive the real parser rather than a copy of it.\n */\nexport function resolveResetPasswordArgs(rawArgs: string[]): {\n email?: string;\n password?: string;\n} {\n const { flags, positionals } = parseCommandArgs({\n spec: RESET_PASSWORD_FLAGS,\n rawArgs,\n commandWords: 2,\n command: \"auth reset-password\",\n maxPositionals: 2\n });\n\n // Both spellings are supported: `<email> [password]` and `--email/--password`.\n return {\n email: flags[\"--email\"] || positionals[0],\n password: flags[\"--password\"] || positionals[1]\n };\n}\n\n/**\n * A password for a reset that was not given one.\n *\n * This used to be a constant, and `--help` printed it as the default. Reset is\n * the documented way back into an account nobody can sign in to — an admin,\n * usually — so the recovery path set every such account to a fixed string that\n * ships inside a public repository and a published npm package, and left it\n * there until somebody remembered to change it.\n *\n * base64url of 18 random bytes: 24 characters, ~144 bits, no shell-quoting\n * hazard, and nothing that reads like a placeholder somebody might keep.\n */\nexport function generatePassword(): string {\n return randomBytes(18).toString(\"base64url\");\n}\n\n/**\n * What a refusing backend said, from its `{ error: { message, code } }` body.\n *\n * The body used to be printed as it came, so a weak password read\n * `{\"error\":{\"message\":\"…\",\"code\":\"…\"}}`. A body that is not the envelope is\n * still shown, since it is the only account of the refusal there is.\n */\nasync function refusalReason(response: Response): Promise<string> {\n const text = await response.text().catch(() => \"\");\n try {\n const parsed: unknown = JSON.parse(text);\n const error = parsed && typeof parsed === \"object\" && \"error\" in parsed ? parsed.error : undefined;\n if (error && typeof error === \"object\" && \"message\" in error && typeof error.message === \"string\") {\n const code = \"code\" in error && typeof error.code === \"string\" ? ` (${error.code})` : \"\";\n return `${error.message}${code}`;\n }\n } catch {\n // Not JSON: the text is the answer.\n }\n return text.trim() || `${response.status} ${response.statusText}`.trim();\n}\n\nasync function resetPassword(rawArgs: string[]): Promise<void> {\n const { email, password: providedPassword } = resolveResetPasswordArgs(rawArgs);\n // Generated once, so both reset paths set and report the same thing.\n const wasGenerated = !providedPassword;\n const newPassword = providedPassword || generatePassword();\n\n if (!email) {\n console.error(chalk.red(\"✗ Email is required.\"));\n console.log(\"\");\n console.log(chalk.gray(\" Usage: rebase auth reset-password <email> [new-password]\"));\n console.log(chalk.gray(\" rebase auth reset-password --email user@example.com --password NewPass123!\"));\n process.exit(1);\n }\n\n const projectRoot = requireProjectRoot();\n\n // 1. Try API-first reset\n // Was a single-key regex, which did not match `export REBASE_SERVICE_KEY=…`\n // and kept a trailing `# comment` in the value. The command then fell\n // through to the direct-database path as though no key were configured.\n const envFile = findEnvFile(projectRoot);\n const envServiceKey: string | undefined = readEnvFile(projectRoot).REBASE_SERVICE_KEY;\n\n let serviceKey = process.env.REBASE_SERVICE_KEY || envServiceKey;\n\n const statePath = path.join(projectRoot, \".rebase\", \"state.json\");\n if (fs.existsSync(statePath)) {\n try {\n const state = JSON.parse(fs.readFileSync(statePath, \"utf8\")) as Record<string, unknown>;\n if (state && typeof state === \"object\" && typeof state.serviceKey === \"string\" && !serviceKey) {\n serviceKey = state.serviceKey;\n }\n } catch {\n // Ignore\n }\n }\n\n // Where the service key may go: a REBASE_BASE_URL the developer named, or\n // this project's backend while the pid that recorded it is alive — see\n // `resolveBackendAddress`. `.rebase/state.json`'s address on its own, and\n // `.rebase-dev-url`, outlive a killed `rebase dev`, and the port they name\n // may be another server's by now. With neither, the reset goes to the\n // database directly.\n const address = resolveBackendAddress(readEnvFile(projectRoot), projectRoot);\n const cloudNote = cloudTargetNote(address);\n if (cloudNote) console.error(chalk.yellow(` ⚠ ${cloudNote}`));\n const baseUrl = address.url;\n\n if (baseUrl && serviceKey) {\n console.log(\"Trying API-first reset via running backend...\");\n try {\n const finalPass = newPassword;\n const cleanBaseUrl = baseUrl.replace(/\\/+$/, \"\");\n // Not `limit=1`: the search is fuzzy and ordered by role count, so\n // the exact match is not necessarily first — asking for one row can\n // make it unreachable. Ask for a page, then match exactly.\n const searchUrl = `${cleanBaseUrl}/api/admin/users?search=${encodeURIComponent(email)}&limit=50`;\n const searchRes = await fetch(searchUrl, {\n headers: {\n \"Authorization\": `Bearer ${serviceKey}`,\n \"Accept\": \"application/json\"\n }\n });\n if (!searchRes.ok) {\n throw new ApiAnswered(`Failed to list users: ${searchRes.status} ${searchRes.statusText}`);\n }\n const searchData = await searchRes.json() as unknown;\n if (!searchData || typeof searchData !== \"object\") {\n throw new Error(\"Invalid response format from user search API.\");\n }\n\n const matched = selectUserForEmail(searchData, email);\n if (!matched) {\n throw new ApiAnswered(`No user has the email ${email}.`);\n }\n\n const resetUrl = `${cleanBaseUrl}/api/admin/users/${matched.id}/reset-password`;\n const resetRes = await fetch(resetUrl, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${serviceKey}`,\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\"\n },\n body: JSON.stringify({ password: finalPass })\n });\n\n if (!resetRes.ok) {\n throw new ApiAnswered(`Password reset refused: ${await refusalReason(resetRes)}`);\n }\n\n console.log(\"API reset successful.\");\n console.log(chalk.bold(\" 🔑 Rebase Auth — Reset Password (via API)\"));\n console.log(\"\");\n // The address as stored, not as typed — they differ in case often\n // enough that echoing the input hides which account was touched.\n console.log(` ${chalk.gray(\"Email:\")} ${matched.email}`);\n // Echoed only when we invented it. A password the operator typed\n // is already theirs; printing it again only adds scrollback.\n console.log(` ${chalk.gray(\"Password:\")} ${wasGenerated ? finalPass : \"*\".repeat(finalPass.length)}`);\n console.log(\"\");\n return;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n // The backend answered and said no — a password too weak, a user\n // it does not have. That answer stands: writing the hash straight\n // into the database instead skipped the strength rule it had just\n // applied, and ended no sessions. Only a backend that could not be\n // reached is a reason to go round it.\n if (err instanceof ApiAnswered) {\n console.error(chalk.red(`✗ ${errMsg}`));\n process.exitCode = 1;\n return;\n }\n console.warn(chalk.yellow(\"API reset failed, falling back to direct database update...\"));\n console.warn(chalk.gray(` Details: ${errMsg}`));\n }\n }\n\n // 2. Direct-DB Fallback\n const backendDir = requireBackendDir(projectRoot);\n const tsxBin = resolveTsx(projectRoot);\n\n if (!tsxBin) {\n exitDependenciesNotInstalled(projectRoot);\n }\n\n // The database the `db` family would use, resolved — and, for a remembered\n // compose container that is stopped, started — the same way. A stock\n // scaffold leaves DATABASE_URL commented out and runs on the managed\n // database, which only exists in a child's environment when something puts\n // it there — without this the script connected with libpq's defaults,\n // localhost:5432 as the OS user. An external DATABASE_URL adds nothing\n // here: the child already reads it.\n let prepared: PreparedDatabase;\n try {\n const { ensureDockerDatabase } = await import(\"./db\");\n await ensureDockerDatabase(projectRoot, rawArgs);\n const { prepareDatabaseEnv } = await import(\"../dev-db/prepare\");\n prepared = await prepareDatabaseEnv(projectRoot, {\n onProgress: (message) => console.log(chalk.gray(` ${message}`))\n });\n } catch (err) {\n console.error(chalk.red(\"✗ Direct database update failed.\"));\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n\n // Opened here first, so a database that does not answer gets the banner\n // every other command prints — not the script's raw error and stack — and\n // no script is written for it.\n const { databaseUrlOf } = await import(\"./db\");\n const url = databaseUrlOf(prepared, readEnvFile(projectRoot));\n if (url) {\n const failure = await databaseOpenFailure(url, prepared.database.source);\n if (failure) {\n for (const line of failure) console.error(line);\n process.exit(1);\n }\n }\n\n try {\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n env.REBASE_RESET_EMAIL = email;\n env.REBASE_RESET_PASSWORD = newPassword;\n env.REBASE_ENV_FILE_PATH = envFile || path.join(projectRoot, \".env\");\n Object.assign(env, prepared.env);\n\n const scriptContent = resetPasswordScript(wasGenerated, parseEnvBoolean(process.env.REBASE_DEBUG) === true);\n\n const tmpScriptPath = path.join(backendDir, \".tmp-reset-password.ts\");\n fs.writeFileSync(tmpScriptPath, scriptContent, \"utf-8\");\n\n console.log(\"\");\n console.log(chalk.bold(\" 🔑 Rebase Auth — Reset Password (Direct DB Fallback)\"));\n console.log(\"\");\n console.log(` ${chalk.gray(\"Email:\")} ${email}`);\n console.log(` ${chalk.gray(\"Database:\")} ${prepared.description}`);\n if (!wasGenerated) {\n console.log(` ${chalk.gray(\"Password:\")} ${\"*\".repeat(newPassword.length)}`);\n }\n console.log(\"\");\n\n const child = spawn(tsxBin, [tmpScriptPath], {\n cwd: backendDir,\n stdio: \"inherit\",\n env\n });\n\n // The script is written into the user's backend directory, so every\n // exit has to remove it. Without an `error` handler a failed spawn\n // raises an unhandled event, the process dies before `close`, and\n // `.tmp-reset-password.ts` is left behind to be committed.\n const cleanup = () => {\n try { fs.unlinkSync(tmpScriptPath); } catch { /* already gone */ }\n };\n\n return new Promise((resolve) => {\n child.on(\"error\", (err) => {\n cleanup();\n console.error(chalk.red(\"✗ Could not run the reset script.\"));\n console.error(chalk.gray(` ${err.message}`));\n process.exit(1);\n });\n child.on(\"close\", (code) => {\n cleanup();\n if (code !== 0) {\n process.exit(code ?? 1);\n }\n resolve();\n });\n });\n } catch (err) {\n console.error(chalk.red(\"✗ Direct database update failed.\"));\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\n/**\n * Why the database the fallback would reset in cannot be opened, as the lines\n * to print — or null when it opens.\n *\n * A stopped database, refused credentials and a database name the server does\n * not have get the boxed banner the other commands print; anything else is one\n * sentence. Either way the password was not reset and no script was written.\n */\nasync function databaseOpenFailure(url: string, source: DevDatabaseSource): Promise<string[] | null> {\n const { Client } = await import(\"pg\");\n const client = new Client({ connectionString: url, connectionTimeoutMillis: 10_000 });\n client.on(\"error\", () => undefined);\n try {\n await client.connect();\n await client.query(\"SELECT 1\");\n return null;\n } catch (error) {\n const { connectionErrorText, connectionFailureBanner, connectionRefusedFixes } =\n await import(\"../dev-db/connection-banner\");\n const consequence = \"The password was not reset.\";\n return connectionFailureBanner(url, error, { consequence, fixes: connectionRefusedFixes(source) }) ?? [\n chalk.red(`✗ Could not open the database: ${redactConnectionPasswords(connectionErrorText(error))}`),\n chalk.gray(` ${consequence}`)\n ];\n } finally {\n await client.end().catch(() => undefined);\n }\n}\n\n/**\n * The script the direct-database fallback runs under the project's own tsx, so\n * it resolves the project's `@rebasepro/server-postgres` and schema.\n *\n * It ends the account's sessions in the transaction that sets the password,\n * as every door through the API does (`replaceUserPassword`): the refresh\n * tokens and outstanding reset links go, and `tokens_valid_after` voids the\n * access tokens already handed out. An operator resetting a phished account\n * with the backend down is the case this exists for, and a reset that left the\n * attacker's refresh token minting access tokens did not recover anything.\n *\n * It exits 0 only when a row was updated: a missing user and a thrown error are\n * both exit 1. `echoPassword` prints the new password, for a generated one;\n * `showStack` prints a failure's stack rather than its sentence (`--debug`).\n *\n * Exported so its tests can run it.\n */\nexport function resetPasswordScript(echoPassword: boolean, showStack = false): string {\n return `\nimport { createPostgresDatabaseConnection } from \"@rebasepro/server-postgres\";\nimport { hashPassword } from \"@rebasepro/server\";\nimport { getTableConfig } from \"drizzle-orm/pg-core\";\nimport * as dotenv from \"dotenv\";\nimport path from \"path\";\nimport fs from \"fs\";\n\ndotenv.config({ path: process.env.REBASE_ENV_FILE_PATH, quiet: true });\n\n// Lowercased, as every address is stored (\\`normalizeEmail\\`): matched as\n// typed, \"Ops@Acme.test\" found no row.\nconst email = process.env.REBASE_RESET_EMAIL!.trim().toLowerCase();\nconst newPassword = process.env.REBASE_RESET_PASSWORD!;\n\nconst quote = (identifier: string) => '\"' + identifier.replace(/\"/g, '\"\"') + '\"';\n\nasync function resetPassword() {\n const { pool } = createPostgresDatabaseConnection(process.env.DATABASE_URL!);\n const hash = await hashPassword(newPassword);\n\n let usersTable;\n try {\n const schemaPath = path.resolve(\"./src/schema.generated.ts\");\n if (fs.existsSync(schemaPath)) {\n const schema = await import(\"file://\" + schemaPath);\n usersTable = schema.users || schema.tables?.users;\n }\n } catch (e) {\n // ignore and fallback\n }\n\n if (!usersTable) {\n const pgServer = await import(\"@rebasepro/server-postgres\");\n usersTable = pgServer.users;\n }\n\n // The physical names, from the table object: the collection may map its\n // properties to other columns, and the statements below are plain SQL.\n const { name: tableName, schema: tableSchema } = getTableConfig(usersTable);\n const usersSchema = tableSchema || \"public\";\n const users = quote(usersSchema) + \".\" + quote(tableName);\n const idColumn = quote(usersTable.id.name);\n const emailColumn = quote(usersTable.email.name);\n const passwordColumn = quote((usersTable.passwordHash ?? usersTable.password_hash).name);\n // Where \\`ensureAuthTablesExist\\` puts the tables that hang off the users\n // table: beside it, or in \\`rebase\\` when it lives in \\`public\\`.\n const authSchema = usersSchema === \"public\" ? \"rebase\" : usersSchema;\n\n const client = await pool.connect();\n try {\n // A database nothing has booted against — or a managed one \\`db reset\\`\n // emptied — has no users table, and so no account to reset. Said as\n // that, not as pg's \\`relation … does not exist\\`.\n const usersTable = await client.query(\"SELECT to_regclass($1) IS NOT NULL AS present\", [users]);\n if (!usersTable.rows[0]?.present) {\n console.error(\"✗ \" + users + \" does not exist in this database, so it holds no account to reset.\");\n console.error(\" Nothing was changed. \\`rebase dev\\` creates it the first time it boots against this database.\");\n process.exit(1);\n }\n\n await client.query(\"BEGIN\");\n const updated = await client.query(\n \"UPDATE \" + users + \" SET \" + passwordColumn + \" = $1 WHERE \" + emailColumn + \" = $2 \" +\n \"RETURNING \" + idColumn + \" AS id, \" + emailColumn + \" AS email\",\n [hash, email]\n );\n if (updated.rows.length === 0) {\n await client.query(\"ROLLBACK\");\n // Nothing was updated, so nothing was reset. Exiting 0 here reported\n // success for a no-op, which is what a script would have believed.\n console.error(\"✗ User not found: \" + email);\n process.exit(1);\n }\n const uid = updated.rows[0].id;\n\n // A table or column the server has not created yet (it never booted\n // against this database) holds no session to end.\n const watermark = await client.query(\n \"SELECT 1 FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = 'tokens_valid_after'\",\n [usersSchema, tableName]\n );\n if (watermark.rows.length > 0) {\n await client.query(\"UPDATE \" + users + \" SET tokens_valid_after = NOW() WHERE \" + idColumn + \" = $1\", [uid]);\n }\n for (const table of [\"refresh_tokens\", \"password_reset_tokens\"]) {\n const qualified = quote(authSchema) + \".\" + quote(table);\n const present = await client.query(\"SELECT to_regclass($1) IS NOT NULL AS present\", [qualified]);\n if (present.rows[0]?.present) {\n await client.query(\"DELETE FROM \" + qualified + \" WHERE uid = $1\", [uid]);\n }\n }\n await client.query(\"COMMIT\");\n\n console.log(\"✅ Password reset for: \" + updated.rows[0].email);\n console.log(\" Every session of this account has ended.\");\n ${echoPassword ? 'console.log(\" Password: \" + newPassword);' : \"\"}\n process.exit(0);\n } catch (error) {\n await client.query(\"ROLLBACK\").catch(() => undefined);\n throw error;\n } finally {\n client.release();\n }\n}\n\n// A thrown error is a failed reset, and exits like one — a refused connection\n// that exits 0 reads as a reset to anything checking the exit code. Said as a\n// sentence: the stack is the script's own, and only --debug asks for it.\nconst describe = (error: unknown): string => {\n if (error instanceof AggregateError && !error.message && error.errors.length > 0) return describe(error.errors[0]);\n const message = error instanceof Error ? error.message : String(error);\n const code = error && typeof error === \"object\" && \"code\" in error && typeof error.code === \"string\" ? error.code : \"\";\n return code && !message.includes(code) ? message + \" (\" + code + \")\" : message;\n};\nresetPassword().catch((error) => {\n ${showStack ? \"console.error(error);\" : \"console.error(\\\"✗ The password was not reset: \\\" + describe(error));\"}\n process.exit(1);\n});\n`;\n}\n\nfunction printAuthHelp() {\n console.log(`\n${chalk.bold(\"rebase auth\")} — Authentication management commands\n\n${chalk.green.bold(\"Usage\")}\n rebase auth ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"reset-password\")} Reset a user's password\n\n${chalk.green.bold(\"reset-password Options\")}\n ${chalk.blue(\"--email, -e\")} User's email address\n ${chalk.blue(\"--password, -p\")} New password (default: one is generated and printed)\n\n${chalk.green.bold(\"Examples\")}\n rebase auth reset-password user@example.com\n rebase auth reset-password --email user@example.com --password MyNewPass!\n`);\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { c as branchDatabaseName, d as clearActiveBranch, f as databaseNameOf, m as writeActiveBranch, p as readActiveBranch } from "./prepare-1rVNd2PF.js";
1
+ import { c as branchDatabaseName, d as clearActiveBranch, f as databaseNameOf, m as writeActiveBranch, p as readActiveBranch } from "./prepare-CTw9NEkh.js";
2
2
  export { branchDatabaseName, clearActiveBranch, databaseNameOf, readActiveBranch, writeActiveBranch };
@@ -1,11 +1,11 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { n as getPMCommands, t as detectPackageManager } from "./package-manager-DSEOwTqM.js";
3
- import { C as wantsHelp, b as parseCommandArgs, p as requireProjectRoot, y as UsageError } from "./project-g4K6kV1t.js";
3
+ import { b as UsageError, p as requireProjectRoot, w as wantsHelp, x as parseCommandArgs } from "./project-CasK56vN.js";
4
4
  import { n as cliVersion } from "./version-Buyyo1ut.js";
5
- import { c as buildableApps, d as findBackendApp, f as formatAppAddress, o as ManifestError, p as loadManifest, v as staticAppAddress } from "./manifest-nvPdLlJY.js";
6
- import { b as toolStdio, o as buildBundle, p as detectFrameworkDepDrift, s as buildStaticBundle, t as DEFAULT_BUNDLE_DIR } from "./bundle-DlqkDYSe.js";
7
- import { i as staticBuildEnv, n as foldFrontendIntoBundle, t as assertBuiltForPath } from "./fold-static-CybSay_W.js";
8
- import { l as writeResourceGraphFile, n as deriveOptionsFor, r as deriveResourceGraph, t as RESOURCE_GRAPH_FILENAME } from "./derive-MTdClnkc.js";
5
+ import { c as buildableApps, d as findBackendApp, f as formatAppAddress, o as ManifestError, p as loadManifest, v as staticAppAddress } from "./manifest-BtzDy7KQ.js";
6
+ import { m as detectFrameworkDepDrift, o as buildBundle, s as buildStaticBundle, t as DEFAULT_BUNDLE_DIR, x as toolStdio } from "./bundle-C6yEtMJ-.js";
7
+ import { i as staticBuildEnv, n as foldFrontendIntoBundle, t as assertBuiltForPath } from "./fold-static-BnAK-anQ.js";
8
+ import { l as writeResourceGraphFile, n as deriveOptionsFor, r as deriveResourceGraph, t as RESOURCE_GRAPH_FILENAME } from "./derive-ae9UOoOB.js";
9
9
  import chalk from "chalk";
10
10
  import fs from "fs";
11
11
  import path from "path";
@@ -332,4 +332,4 @@ async function runWorkspaceBuilds(projectRoot) {
332
332
  //#endregion
333
333
  export { build_exports as n, buildAssetApp as t };
334
334
 
335
- //# sourceMappingURL=build-et7Rccxi.js.map
335
+ //# sourceMappingURL=build-Cza7ZQrp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-et7Rccxi.js","names":[],"sources":["../src/commands/build.ts"],"sourcesContent":["/**\n * CLI command: rebase build [app...]\n *\n * Builds the apps a repository declares in `rebase.json`.\n *\n * For a `backend` app this produces a **bundle** — compiled collections,\n * functions and schema plus a manifest — which is the artifact the runtime\n * loads. For `static` and bundled `admin` apps it runs the declared build\n * command and reports where the output landed.\n *\n * A project with no manifest, or one whose backend has been ejected to its own\n * entrypoint, falls back to the previous behaviour: run every workspace's own\n * `build` script. Nothing that built before stops building.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport type { RebaseAppConfig, RebaseStaticAppConfig } from \"@rebasepro/types\";\nimport { requireProjectRoot } from \"../utils/project\";\nimport { parseCommandArgs, UsageError, wantsHelp } from \"../utils/args\";\nimport { detectPackageManager, getPMCommands } from \"../utils/package-manager\";\nimport { cliVersion } from \"../utils/version\";\nimport { toolStdio } from \"../utils/tool-stdio\";\nimport {\n buildableApps,\n findBackendApp,\n formatAppAddress,\n loadManifest,\n ManifestError,\n resolveBackendPaths,\n staticAppAddress\n} from \"../manifest\";\nimport {\n buildBundle,\n buildStaticBundle,\n detectFrameworkDepDrift,\n DEFAULT_BUNDLE_DIR,\n VENDOR_SIZE_WARN_BYTES\n} from \"../bundle\";\nimport { assertBuiltForPath, foldFrontendIntoBundle, staticBuildEnv } from \"../fold-static\";\nimport { deriveOptionsFor, deriveResourceGraph, RESOURCE_GRAPH_FILENAME, writeResourceGraphFile } from \"../resources/derive\";\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase build\")} — build the apps declared in rebase.json\n\n${chalk.bold(\"Usage\")}\n rebase build [app...] Build the named apps (default: all)\n\n${chalk.bold(\"Options\")}\n --output, --out <dir> Bundle output directory (default: ${DEFAULT_BUNDLE_DIR});\n one app at a time\n --skip-type-check Compile without type checking (faster; use for iteration only)\n --skip-schema Do not regenerate the database schema from collections\n --no-static Do not fold the frontend into the backend bundle (each\n static app still gets its own bundle)\n --skip-static-build Fold the frontend as already built, without running its\n build command — for CI that built it in an earlier step\n --no-vendor Do not install dependencies into the bundle (they\n install on every pod start instead, ~40-60s slower)\n --vendor Install them whatever the tree's size — for a\n deploy that builds from source and never uploads it\n --workspace Run every workspace's own build script instead\n -h, --help Show this help\n\n${chalk.bold(\"Examples\")}\n rebase build Build every app in this repository\n rebase build backend Build only the backend bundle\n rebase build web Build only the \"web\" static app\n`.trim());\n}\n\n/**\n * The two commands that turn a custom-runtime app into an image.\n *\n * Exported for the test, because the failure this replaced was in the printed\n * text and nowhere else. It said:\n *\n * docker build -f backend/Dockerfile .\n *\n * for every custom backend, and the `.` was a guess — `context` was validated,\n * stored on the config, and read by nothing. For the reference project that\n * guess is wrong: `app/backend/Dockerfile` opens by copying `pnpm-lock.yaml`\n * and `pnpm-workspace.yaml`, which live at the monorepo root, so the command\n * `rebase build` handed you died on its first instruction. The deploy that\n * actually works, `infra/cloudbuild.yaml`, has always said\n * `-f app/backend/Dockerfile .` from the root.\n *\n * `dockerfile` is relative to `rebase.json`; `context` is too, and may point\n * above it. Docker resolves `-f` against the working directory, not the\n * context, so the path has to be re-expressed against wherever the command\n * runs — which is what the old line never did and is the whole reason it\n * could not be right for both.\n */\nexport function dockerBuildHint(\n projectRoot: string,\n name: string,\n app: { dockerfile?: string; context?: string }\n): string[] {\n const dockerfile = app.dockerfile ?? \"Dockerfile\";\n const context = app.context ?? \".\";\n const contextDir = path.resolve(projectRoot, context);\n const fromContext = path.relative(contextDir, path.resolve(projectRoot, dockerfile));\n\n const build = `${chalk.cyan(`npm run build --workspace ${name}`)}`;\n\n // A Dockerfile outside its own context is legal to `docker build` but means\n // nothing it copies is reachable, so there is no command to offer. Say what\n // is wrong instead of printing one that cannot work.\n if (fromContext.startsWith(\"..\")) {\n return [\n chalk.dim(` ${build}`),\n chalk.yellow(` ⚠ ${dockerfile} is outside the build context (${context}) — nothing it COPYs is reachable.`),\n chalk.dim(` Widen \"context\" in rebase.json, or move the Dockerfile inside it.`)\n ];\n }\n\n const docker = chalk.cyan(`docker build -f ${fromContext} .`);\n return context === \".\"\n ? [chalk.dim(` ${build} then ${docker}`)]\n : [chalk.dim(` ${build}`), chalk.dim(` ${chalk.cyan(`cd ${context}`)} && ${docker}`)];\n}\n\nexport async function buildCommand(rawArgs: string[] = []): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n const { flags: args, positionals: requested } = parseCommandArgs({\n spec: {\n \"--output\": String,\n // `--out` kept as an accepted alias. `generate-sdk` has always\n // spelled this `--output`, and two names for one concept across one\n // CLI is a thing you have to remember rather than know. `--output`\n // is canonical now; `--out` still works so no script breaks.\n \"--out\": \"--output\",\n \"--skip-type-check\": Boolean,\n /* Do not install the declared dependencies into the bundle. The\n bundle still works — it installs them at boot, as every bundle did\n before vendoring existed — so this is for a build that must not\n shell out to npm, not for a smaller artifact. */\n \"--no-vendor\": Boolean,\n /* Keep the installed tree whatever its size. The size ceiling\n protects an upload that a source-built deploy never performs, so\n that path needs a way to say so. */\n \"--vendor\": Boolean,\n \"--skip-schema\": Boolean,\n /* Do not fold the frontend into the backend bundle. For a project\n that publishes its frontend elsewhere and does not want the assets\n travelling with its API. */\n \"--no-static\": Boolean,\n /* Fold assets that are already built, without re-running the app's\n build command — for a CI job that built the frontend in an earlier\n step. */\n \"--skip-static-build\": Boolean,\n \"--workspace\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"build\"\n });\n\n const projectRoot = requireProjectRoot();\n\n if (args[\"--workspace\"]) {\n await runWorkspaceBuilds(projectRoot);\n return;\n }\n\n let loaded;\n try {\n loaded = loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n console.error(chalk.red(`✗ ${err.message}`));\n for (const issue of err.issues) {\n console.error(chalk.red(` ${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`));\n }\n process.exit(1);\n }\n throw err;\n }\n\n const { manifest, source } = loaded;\n\n let targets = buildableApps(manifest);\n if (requested.length > 0) {\n const known = new Set(targets.map(t => t.name));\n const unknown = requested.filter(name => !known.has(name));\n if (unknown.length > 0) {\n console.error(chalk.red(`✗ Unknown app(s): ${unknown.join(\", \")}`));\n console.error(chalk.dim(` This repository declares: ${targets.map(t => t.name).join(\", \") || \"(none)\"}`));\n process.exit(1);\n }\n targets = targets.filter(t => requested.includes(t.name));\n }\n\n if (targets.length === 0) {\n console.log(chalk.yellow(\"No buildable apps declared. Nothing to do.\"));\n return;\n }\n\n // An ejected backend owns its own build; the workspace scripts are the only\n // thing that knows how to run it.\n const backend = findBackendApp(manifest);\n if (!backend && source === \"synthesized\") {\n console.log(chalk.dim(\"No rebase.json found — building workspace packages.\\n\"));\n await runWorkspaceBuilds(projectRoot);\n return;\n }\n\n // `--output` names one bundle directory, resolved from where it was typed.\n // It is refused for a build that produces several bundles rather than\n // handed to each: every bundle build empties its directory first, so the\n // last app built deleted the others' and the build still reported success.\n const output = args[\"--output\"] ? path.resolve(process.cwd(), args[\"--output\"]) : undefined;\n const bundled = targets.filter(({ app }) =>\n (app.type === \"backend\" && app.runtime !== \"custom\") ||\n (app.type === \"static\" && Boolean(app.build) && Boolean(app.output)));\n if (output && bundled.length > 1) {\n throw new UsageError(\n `--output names one bundle directory, and this build produces ${bundled.length}: ` +\n `${bundled.map(t => t.name).join(\", \")}. Build one app into it: ` +\n `rebase build ${bundled[0].name} --output ${args[\"--output\"]}`\n );\n }\n\n console.log(`${chalk.bold(\"Rebase\")} — building ${targets.length} app(s)\\n`);\n\n // Each static app is built once per run, whichever consumer gets to it\n // first: folding into the backend bundle, or its own static bundle.\n const builtApps = new Set<string>();\n\n for (const { name, app } of targets) {\n console.log(chalk.cyan(`▸ ${name}`) + chalk.dim(` (${app.type})`));\n\n if (app.type === \"backend\" && app.runtime === \"custom\") {\n // An ejected backend's artifact is an IMAGE, not a bundle. Building\n // one anyway produced a `dist-bundle/` the project never deploys,\n // which is worse than doing nothing: it looks like the thing that\n // ships. The workspace's own `build` script compiles this app, and\n // the Dockerfile turns it into the image.\n console.log(chalk.dim(\" custom runtime — this project builds its own image, not a bundle\"));\n for (const line of dockerBuildHint(projectRoot, name, app)) console.log(line);\n console.log(\"\");\n continue;\n }\n\n if (app.type === \"backend\") {\n // Derived per backend app, because each has its own config\n // directory. Issues are fatal here rather than reported: a bundle\n // whose manifest is missing a bucket the code declares would deploy\n // into a tenant with nothing provisioned for it, and the first sign\n // would be uploads failing in production.\n const { graph: resourceGraph, issues } = await deriveResourceGraph(deriveOptionsFor(projectRoot, app));\n if (issues.length > 0) {\n console.error(chalk.red(`\\n ✗ ${issues.length} problem(s) in the declared resources:\\n`));\n for (const issue of issues) console.error(` ${chalk.bold(issue.path)} ${issue.message}`);\n console.error(\"\");\n process.exitCode = 1;\n return;\n }\n // Written alongside the bundle so the repository records what this\n // project needs. `rebase resources --check` is what keeps it honest.\n // Committed, so a change to it is said: the first build of a\n // scaffold otherwise left it untracked with no word on what it is.\n if (writeResourceGraphFile(projectRoot, resourceGraph).changed) {\n console.log(chalk.dim(` ${RESOURCE_GRAPH_FILENAME} updated — commit it: it records what this project needs from a host`));\n }\n\n /* The framework pins, read before the build and reported after it.\n Ranges no single version satisfies are refused by `buildBundle`\n itself, before it builds anything, for every command that builds\n a bundle. */\n const drift = detectFrameworkDepDrift(projectRoot, cliVersion());\n\n const result = await buildBundle({\n projectRoot,\n appName: name,\n app,\n outDir: output,\n runtimeRange: manifest.rebase,\n resources: resourceGraph,\n skipTypeCheck: args[\"--skip-type-check\"],\n skipSchema: args[\"--skip-schema\"],\n vendor: args[\"--no-vendor\"] ? false : (args[\"--vendor\"] ? true : undefined)\n });\n const rel = path.relative(projectRoot, result.outDir);\n console.log(chalk.green(` ✓ bundle → ${rel}/`));\n // A headless build has no schema version — the API is introspected\n // from the live database at boot — and interpolating it anyway left\n // the summary ending in a dangling `schema `, which reads as a value\n // that failed to render rather than one that does not exist.\n const schemaVersion = result.manifest.schemaVersion;\n console.log(chalk.dim(\n ` ${result.collectionCount} collection(s)${schemaVersion ? `, schema ${schemaVersion}` : \"\"}`\n ));\n /* Say what the bundle's cold start will be, at the one moment\n anyone is listening.\n\n A vendored bundle starts in about five seconds; one that installs\n at boot takes forty to sixty, on EVERY pod start — an eviction, a\n node failure, an OOM, a runtime rollout. That is not a build\n detail, it is what each of those events costs in downtime, and it\n is invisible until an incident unless it is said here. */\n if (result.vendor.vendored) {\n console.log(chalk.dim(` dependencies installed into the bundle (${result.vendor.target?.os}/${result.vendor.target?.cpu})`));\n if ((result.vendor.bytes ?? 0) > VENDOR_SIZE_WARN_BYTES) {\n const mb = Math.round((result.vendor.bytes ?? 0) / (1024 * 1024));\n /* The limit is on the *compressed* upload and this is the\n tree on disk, so a number above 100 does not mean the\n upload fails — but \"201 MB, close to the 100 MB limit\"\n reads as nonsense and got ignored for exactly that\n reason. Say which quantity is which. */\n console.log(chalk.yellow(\n ` ⚠ the installed tree is ${mb} MB on disk — enough to risk the control plane's 100 MB ` +\n \"limit on the compressed upload\"));\n console.log(chalk.dim(\" Shrink the declared dependencies, or rebuild with --no-vendor.\"));\n }\n } else if (Object.keys(result.manifest.deps.declared).length === 0) {\n // Nothing to install is not a degraded state — this bundle\n // already starts as fast as a vendored one. Warning here would\n // train people to ignore the warning that matters.\n console.log(chalk.dim(\" no dependencies to install — nothing to bundle\"));\n } else {\n console.log(chalk.yellow(` ⚠ dependencies not bundled: ${result.vendor.skipped}`));\n console.log(chalk.dim(\" They install on every pod start instead, which is ~40-60s of cold start.\"));\n }\n\n if (result.manifest.hooks.native) {\n const names = (result.manifest.hooks.nativeModules ?? []).map(m => m.name).join(\", \");\n console.log(chalk.yellow(` ⚠ native dependencies detected: ${names}`));\n console.log(chalk.dim(\" These cannot run on the managed runtime. See `rebase doctor`.\"));\n }\n\n /* Framework pins older than this CLI.\n\n Warned here because this is the only moment anyone can be told.\n Locally every `@rebasepro/*` resolves through pnpm's workspace and\n `link:` overrides to the checkout, so the version strings in\n package.json are never exercised — the project runs fine on a\n developer's machine while declaring something years old. Those\n strings are first honoured when the runtime npm-installs them in\n the cloud, and by then the symptom is a tenant that boots and then\n misbehaves against its database.\n\n A warning rather than a hard failure: the CLI cannot know that a\n newer package has actually been published, and refusing to build\n over a guess would be worse than saying it out loud. (`drift` was\n read before the build, above.) */\n if (drift.behind.length > 0) {\n console.log(chalk.yellow(` ⚠ framework dependencies older than this CLI (${cliVersion()}):`));\n for (const dep of drift.behind) {\n console.log(chalk.dim(` ${dep.name}@${dep.range} (${dep.file})`));\n }\n console.log(chalk.dim(\" The image supplies the server, but your bundle supplies the database\"));\n console.log(chalk.dim(\" driver — a newer runtime does not update it.\"));\n console.log(chalk.dim(` Run \\`${upgradeToThisCli()}\\`, then rebuild.`));\n } else if (drift.disagreeing.length > 0) {\n console.log(chalk.yellow(` ⚠ mixed @rebasepro versions declared: ${drift.disagreeing.join(\", \")}`));\n console.log(chalk.dim(\" These are published together and expect to run together.\"));\n console.log(chalk.dim(` Run \\`${upgradeToThisCli()}\\` to pin them alike, then rebuild.`));\n }\n\n /* Fold the project's static apps into the backend bundle, so ONE\n runtime serves the site at `/`, the admin at `/admin` and the API\n at `/api` — the shape the scaffolded template produces and the\n shape a custom container already had.\n\n Without this, moving a project to the managed runtime silently\n removed its website: the API answered perfectly and every page\n 404'd, because the managed pod runs the backend bundle and nothing\n else. Parity with the container being replaced is the only honest\n baseline for calling managed a drop-in.\n\n `--no-static` opts out, for a project that publishes its frontend\n somewhere else and does not want the assets in its bundle. */\n if (!args[\"--no-static\"]) {\n const folded = await foldFrontendIntoBundle({\n projectRoot,\n manifest,\n bundleDir: result.outDir,\n skipBuild: args[\"--skip-static-build\"] === true,\n builtApps,\n log: (m) => console.log(m)\n }).catch((err: unknown) => {\n console.error(chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n });\n for (const outcome of folded ?? []) {\n console.log(\n chalk.green(` ✓ ${outcome.appName} folded in`) +\n chalk.dim(` (${outcome.fileCount} file(s) → served at ${formatAppAddress(outcome)})`)\n );\n }\n }\n } else if (app.type === \"static\") {\n await buildAssetApp(projectRoot, name, app, manifest.rebase, output, { builtApps }).catch((err: unknown) => {\n console.error(chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n });\n }\n\n console.log(\"\");\n }\n\n console.log(chalk.green(\"✓ Build complete.\"));\n}\n\n/**\n * Build a static app and package it into a static bundle.\n *\n * Runs the app's own build command, checks it produced the declared output, then\n * packages that output into a `static`-kind bundle — the same deployable shape as\n * a backend bundle, so a frontend or admin app deploys through the identical\n * path and runs on the identical image, just serving files instead of an API.\n *\n * Throws when the build fails or produces nothing usable, so the caller answers\n * in its own way: `rebase build` with a red line, `rebase cloud deploy --json`\n * with its JSON error.\n */\nexport async function buildAssetApp(\n projectRoot: string,\n name: string,\n app: RebaseAppConfig,\n runtimeRange: string,\n outOverride?: string,\n /**\n * `quietStdout`: every line, the build command's included, goes to stderr. See `toolStdio`.\n * `builtApps`: the static apps already built in this run (see `FoldOptions.builtApps`).\n */\n options: { quietStdout?: boolean; builtApps?: Set<string> } = {}\n): Promise<string | undefined> {\n const asset = app as RebaseStaticAppConfig;\n // The path part is what the app is built for and mounted at; the hostname,\n // when `path` names one, only travels in the bundle.\n const address = staticAppAddress(name, asset);\n const basePath = address.path;\n const say = (line: string): void => {\n if (options.quietStdout) console.error(line);\n else console.log(line);\n };\n\n if (!asset.build) {\n say(chalk.dim(\" no build command declared — skipping\"));\n return undefined;\n }\n\n if (options.builtApps?.has(name)) {\n say(chalk.dim(\" built once already in this run — packaging that output\"));\n } else {\n try {\n await execa(asset.build, {\n cwd: projectRoot,\n stdio: toolStdio(options.quietStdout),\n shell: true,\n env: staticBuildEnv(basePath, name)\n });\n } catch {\n throw new Error(`build command failed for \"${name}\"`);\n }\n options.builtApps?.add(name);\n }\n\n if (!asset.output) {\n say(chalk.yellow(\" no output directory declared — built, but nothing to bundle\"));\n return undefined;\n }\n\n const outputPath = path.join(projectRoot, asset.output);\n if (!fs.existsSync(outputPath)) {\n // The command exited 0 but produced nothing where the manifest says it\n // should. Bundling that would ship an empty site.\n throw new Error(`declared output \"${asset.output}\" does not exist after building`);\n }\n\n // The assets were built for `basePath`; refusing here is the difference\n // between a build error and a blank page nobody can diagnose.\n const indexHtml = path.join(outputPath, \"index.html\");\n if (fs.existsSync(indexHtml)) {\n assertBuiltForPath(fs.readFileSync(indexHtml, \"utf8\"), basePath, name);\n }\n\n // Per-app bundle directory, so a project's several static apps do not clobber\n // one another or the backend's `dist-bundle`.\n const outDir = outOverride\n ? path.resolve(process.cwd(), outOverride)\n : path.join(projectRoot, `dist-bundle-${name}`);\n const result = buildStaticBundle({\n projectRoot,\n appName: name,\n assetsDir: outputPath,\n outDir,\n runtimeRange,\n path: basePath,\n host: address.host,\n spa: asset.spa ?? true,\n cms: asset.cms\n });\n const rel = path.relative(projectRoot, result.outDir);\n say(\n chalk.green(` ✓ static bundle → ${rel}/`) +\n chalk.dim(` (${result.fileCount} file(s) → served at ${formatAppAddress(address)})`)\n );\n return result.outDir;\n}\n\n/**\n * The `rebase upgrade` line the drift warnings print.\n *\n * Aimed at this CLI's own version, because that is what the warning measured\n * against: \"older than this CLI\" is answered by moving to exactly this CLI, not\n * to whatever `latest` happens to be — which, on a canary, is older still.\n */\nfunction upgradeToThisCli(): string {\n const version = cliVersion();\n return version === \"unknown\" ? \"rebase upgrade\" : `rebase upgrade --to ${version}`;\n}\n\n/** The pre-manifest behaviour: build every workspace package. */\nasync function runWorkspaceBuilds(projectRoot: string): Promise<void> {\n const pm = detectPackageManager(projectRoot);\n const cmds = getPMCommands(pm);\n const buildCmd = cmds.runAll(\"build\");\n\n console.log(`${chalk.bold(\"Rebase\")} — Building all workspaces with ${chalk.cyan(pm)}...\\n`);\n\n try {\n await execa(buildCmd[0], buildCmd.slice(1), {\n cwd: projectRoot,\n stdio: \"inherit\"\n });\n } catch {\n console.error(chalk.red(\"\\n✗ Build failed.\"));\n process.exit(1);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"build-Cza7ZQrp.js","names":[],"sources":["../src/commands/build.ts"],"sourcesContent":["/**\n * CLI command: rebase build [app...]\n *\n * Builds the apps a repository declares in `rebase.json`.\n *\n * For a `backend` app this produces a **bundle** — compiled collections,\n * functions and schema plus a manifest — which is the artifact the runtime\n * loads. For `static` and bundled `admin` apps it runs the declared build\n * command and reports where the output landed.\n *\n * A project with no manifest, or one whose backend has been ejected to its own\n * entrypoint, falls back to the previous behaviour: run every workspace's own\n * `build` script. Nothing that built before stops building.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport type { RebaseAppConfig, RebaseStaticAppConfig } from \"@rebasepro/types\";\nimport { requireProjectRoot } from \"../utils/project\";\nimport { parseCommandArgs, UsageError, wantsHelp } from \"../utils/args\";\nimport { detectPackageManager, getPMCommands } from \"../utils/package-manager\";\nimport { cliVersion } from \"../utils/version\";\nimport { toolStdio } from \"../utils/tool-stdio\";\nimport {\n buildableApps,\n findBackendApp,\n formatAppAddress,\n loadManifest,\n ManifestError,\n resolveBackendPaths,\n staticAppAddress\n} from \"../manifest\";\nimport {\n buildBundle,\n buildStaticBundle,\n detectFrameworkDepDrift,\n DEFAULT_BUNDLE_DIR,\n VENDOR_SIZE_WARN_BYTES\n} from \"../bundle\";\nimport { assertBuiltForPath, foldFrontendIntoBundle, staticBuildEnv } from \"../fold-static\";\nimport { deriveOptionsFor, deriveResourceGraph, RESOURCE_GRAPH_FILENAME, writeResourceGraphFile } from \"../resources/derive\";\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase build\")} — build the apps declared in rebase.json\n\n${chalk.bold(\"Usage\")}\n rebase build [app...] Build the named apps (default: all)\n\n${chalk.bold(\"Options\")}\n --output, --out <dir> Bundle output directory (default: ${DEFAULT_BUNDLE_DIR});\n one app at a time\n --skip-type-check Compile without type checking (faster; use for iteration only)\n --skip-schema Do not regenerate the database schema from collections\n --no-static Do not fold the frontend into the backend bundle (each\n static app still gets its own bundle)\n --skip-static-build Fold the frontend as already built, without running its\n build command — for CI that built it in an earlier step\n --no-vendor Do not install dependencies into the bundle (they\n install on every pod start instead, ~40-60s slower)\n --vendor Install them whatever the tree's size — for a\n deploy that builds from source and never uploads it\n --workspace Run every workspace's own build script instead\n -h, --help Show this help\n\n${chalk.bold(\"Examples\")}\n rebase build Build every app in this repository\n rebase build backend Build only the backend bundle\n rebase build web Build only the \"web\" static app\n`.trim());\n}\n\n/**\n * The two commands that turn a custom-runtime app into an image.\n *\n * Exported for the test, because the failure this replaced was in the printed\n * text and nowhere else. It said:\n *\n * docker build -f backend/Dockerfile .\n *\n * for every custom backend, and the `.` was a guess — `context` was validated,\n * stored on the config, and read by nothing. For the reference project that\n * guess is wrong: `app/backend/Dockerfile` opens by copying `pnpm-lock.yaml`\n * and `pnpm-workspace.yaml`, which live at the monorepo root, so the command\n * `rebase build` handed you died on its first instruction. The deploy that\n * actually works, `infra/cloudbuild.yaml`, has always said\n * `-f app/backend/Dockerfile .` from the root.\n *\n * `dockerfile` is relative to `rebase.json`; `context` is too, and may point\n * above it. Docker resolves `-f` against the working directory, not the\n * context, so the path has to be re-expressed against wherever the command\n * runs — which is what the old line never did and is the whole reason it\n * could not be right for both.\n */\nexport function dockerBuildHint(\n projectRoot: string,\n name: string,\n app: { dockerfile?: string; context?: string }\n): string[] {\n const dockerfile = app.dockerfile ?? \"Dockerfile\";\n const context = app.context ?? \".\";\n const contextDir = path.resolve(projectRoot, context);\n const fromContext = path.relative(contextDir, path.resolve(projectRoot, dockerfile));\n\n const build = `${chalk.cyan(`npm run build --workspace ${name}`)}`;\n\n // A Dockerfile outside its own context is legal to `docker build` but means\n // nothing it copies is reachable, so there is no command to offer. Say what\n // is wrong instead of printing one that cannot work.\n if (fromContext.startsWith(\"..\")) {\n return [\n chalk.dim(` ${build}`),\n chalk.yellow(` ⚠ ${dockerfile} is outside the build context (${context}) — nothing it COPYs is reachable.`),\n chalk.dim(` Widen \"context\" in rebase.json, or move the Dockerfile inside it.`)\n ];\n }\n\n const docker = chalk.cyan(`docker build -f ${fromContext} .`);\n return context === \".\"\n ? [chalk.dim(` ${build} then ${docker}`)]\n : [chalk.dim(` ${build}`), chalk.dim(` ${chalk.cyan(`cd ${context}`)} && ${docker}`)];\n}\n\nexport async function buildCommand(rawArgs: string[] = []): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n const { flags: args, positionals: requested } = parseCommandArgs({\n spec: {\n \"--output\": String,\n // `--out` kept as an accepted alias. `generate-sdk` has always\n // spelled this `--output`, and two names for one concept across one\n // CLI is a thing you have to remember rather than know. `--output`\n // is canonical now; `--out` still works so no script breaks.\n \"--out\": \"--output\",\n \"--skip-type-check\": Boolean,\n /* Do not install the declared dependencies into the bundle. The\n bundle still works — it installs them at boot, as every bundle did\n before vendoring existed — so this is for a build that must not\n shell out to npm, not for a smaller artifact. */\n \"--no-vendor\": Boolean,\n /* Keep the installed tree whatever its size. The size ceiling\n protects an upload that a source-built deploy never performs, so\n that path needs a way to say so. */\n \"--vendor\": Boolean,\n \"--skip-schema\": Boolean,\n /* Do not fold the frontend into the backend bundle. For a project\n that publishes its frontend elsewhere and does not want the assets\n travelling with its API. */\n \"--no-static\": Boolean,\n /* Fold assets that are already built, without re-running the app's\n build command — for a CI job that built the frontend in an earlier\n step. */\n \"--skip-static-build\": Boolean,\n \"--workspace\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"build\"\n });\n\n const projectRoot = requireProjectRoot();\n\n if (args[\"--workspace\"]) {\n await runWorkspaceBuilds(projectRoot);\n return;\n }\n\n let loaded;\n try {\n loaded = loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n console.error(chalk.red(`✗ ${err.message}`));\n for (const issue of err.issues) {\n console.error(chalk.red(` ${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`));\n }\n process.exit(1);\n }\n throw err;\n }\n\n const { manifest, source } = loaded;\n\n let targets = buildableApps(manifest);\n if (requested.length > 0) {\n const known = new Set(targets.map(t => t.name));\n const unknown = requested.filter(name => !known.has(name));\n if (unknown.length > 0) {\n console.error(chalk.red(`✗ Unknown app(s): ${unknown.join(\", \")}`));\n console.error(chalk.dim(` This repository declares: ${targets.map(t => t.name).join(\", \") || \"(none)\"}`));\n process.exit(1);\n }\n targets = targets.filter(t => requested.includes(t.name));\n }\n\n if (targets.length === 0) {\n console.log(chalk.yellow(\"No buildable apps declared. Nothing to do.\"));\n return;\n }\n\n // An ejected backend owns its own build; the workspace scripts are the only\n // thing that knows how to run it.\n const backend = findBackendApp(manifest);\n if (!backend && source === \"synthesized\") {\n console.log(chalk.dim(\"No rebase.json found — building workspace packages.\\n\"));\n await runWorkspaceBuilds(projectRoot);\n return;\n }\n\n // `--output` names one bundle directory, resolved from where it was typed.\n // It is refused for a build that produces several bundles rather than\n // handed to each: every bundle build empties its directory first, so the\n // last app built deleted the others' and the build still reported success.\n const output = args[\"--output\"] ? path.resolve(process.cwd(), args[\"--output\"]) : undefined;\n const bundled = targets.filter(({ app }) =>\n (app.type === \"backend\" && app.runtime !== \"custom\") ||\n (app.type === \"static\" && Boolean(app.build) && Boolean(app.output)));\n if (output && bundled.length > 1) {\n throw new UsageError(\n `--output names one bundle directory, and this build produces ${bundled.length}: ` +\n `${bundled.map(t => t.name).join(\", \")}. Build one app into it: ` +\n `rebase build ${bundled[0].name} --output ${args[\"--output\"]}`\n );\n }\n\n console.log(`${chalk.bold(\"Rebase\")} — building ${targets.length} app(s)\\n`);\n\n // Each static app is built once per run, whichever consumer gets to it\n // first: folding into the backend bundle, or its own static bundle.\n const builtApps = new Set<string>();\n\n for (const { name, app } of targets) {\n console.log(chalk.cyan(`▸ ${name}`) + chalk.dim(` (${app.type})`));\n\n if (app.type === \"backend\" && app.runtime === \"custom\") {\n // An ejected backend's artifact is an IMAGE, not a bundle. Building\n // one anyway produced a `dist-bundle/` the project never deploys,\n // which is worse than doing nothing: it looks like the thing that\n // ships. The workspace's own `build` script compiles this app, and\n // the Dockerfile turns it into the image.\n console.log(chalk.dim(\" custom runtime — this project builds its own image, not a bundle\"));\n for (const line of dockerBuildHint(projectRoot, name, app)) console.log(line);\n console.log(\"\");\n continue;\n }\n\n if (app.type === \"backend\") {\n // Derived per backend app, because each has its own config\n // directory. Issues are fatal here rather than reported: a bundle\n // whose manifest is missing a bucket the code declares would deploy\n // into a tenant with nothing provisioned for it, and the first sign\n // would be uploads failing in production.\n const { graph: resourceGraph, issues } = await deriveResourceGraph(deriveOptionsFor(projectRoot, app));\n if (issues.length > 0) {\n console.error(chalk.red(`\\n ✗ ${issues.length} problem(s) in the declared resources:\\n`));\n for (const issue of issues) console.error(` ${chalk.bold(issue.path)} ${issue.message}`);\n console.error(\"\");\n process.exitCode = 1;\n return;\n }\n // Written alongside the bundle so the repository records what this\n // project needs. `rebase resources --check` is what keeps it honest.\n // Committed, so a change to it is said: the first build of a\n // scaffold otherwise left it untracked with no word on what it is.\n if (writeResourceGraphFile(projectRoot, resourceGraph).changed) {\n console.log(chalk.dim(` ${RESOURCE_GRAPH_FILENAME} updated — commit it: it records what this project needs from a host`));\n }\n\n /* The framework pins, read before the build and reported after it.\n Ranges no single version satisfies are refused by `buildBundle`\n itself, before it builds anything, for every command that builds\n a bundle. */\n const drift = detectFrameworkDepDrift(projectRoot, cliVersion());\n\n const result = await buildBundle({\n projectRoot,\n appName: name,\n app,\n outDir: output,\n runtimeRange: manifest.rebase,\n resources: resourceGraph,\n skipTypeCheck: args[\"--skip-type-check\"],\n skipSchema: args[\"--skip-schema\"],\n vendor: args[\"--no-vendor\"] ? false : (args[\"--vendor\"] ? true : undefined)\n });\n const rel = path.relative(projectRoot, result.outDir);\n console.log(chalk.green(` ✓ bundle → ${rel}/`));\n // A headless build has no schema version — the API is introspected\n // from the live database at boot — and interpolating it anyway left\n // the summary ending in a dangling `schema `, which reads as a value\n // that failed to render rather than one that does not exist.\n const schemaVersion = result.manifest.schemaVersion;\n console.log(chalk.dim(\n ` ${result.collectionCount} collection(s)${schemaVersion ? `, schema ${schemaVersion}` : \"\"}`\n ));\n /* Say what the bundle's cold start will be, at the one moment\n anyone is listening.\n\n A vendored bundle starts in about five seconds; one that installs\n at boot takes forty to sixty, on EVERY pod start — an eviction, a\n node failure, an OOM, a runtime rollout. That is not a build\n detail, it is what each of those events costs in downtime, and it\n is invisible until an incident unless it is said here. */\n if (result.vendor.vendored) {\n console.log(chalk.dim(` dependencies installed into the bundle (${result.vendor.target?.os}/${result.vendor.target?.cpu})`));\n if ((result.vendor.bytes ?? 0) > VENDOR_SIZE_WARN_BYTES) {\n const mb = Math.round((result.vendor.bytes ?? 0) / (1024 * 1024));\n /* The limit is on the *compressed* upload and this is the\n tree on disk, so a number above 100 does not mean the\n upload fails — but \"201 MB, close to the 100 MB limit\"\n reads as nonsense and got ignored for exactly that\n reason. Say which quantity is which. */\n console.log(chalk.yellow(\n ` ⚠ the installed tree is ${mb} MB on disk — enough to risk the control plane's 100 MB ` +\n \"limit on the compressed upload\"));\n console.log(chalk.dim(\" Shrink the declared dependencies, or rebuild with --no-vendor.\"));\n }\n } else if (Object.keys(result.manifest.deps.declared).length === 0) {\n // Nothing to install is not a degraded state — this bundle\n // already starts as fast as a vendored one. Warning here would\n // train people to ignore the warning that matters.\n console.log(chalk.dim(\" no dependencies to install — nothing to bundle\"));\n } else {\n console.log(chalk.yellow(` ⚠ dependencies not bundled: ${result.vendor.skipped}`));\n console.log(chalk.dim(\" They install on every pod start instead, which is ~40-60s of cold start.\"));\n }\n\n if (result.manifest.hooks.native) {\n const names = (result.manifest.hooks.nativeModules ?? []).map(m => m.name).join(\", \");\n console.log(chalk.yellow(` ⚠ native dependencies detected: ${names}`));\n console.log(chalk.dim(\" These cannot run on the managed runtime. See `rebase doctor`.\"));\n }\n\n /* Framework pins older than this CLI.\n\n Warned here because this is the only moment anyone can be told.\n Locally every `@rebasepro/*` resolves through pnpm's workspace and\n `link:` overrides to the checkout, so the version strings in\n package.json are never exercised — the project runs fine on a\n developer's machine while declaring something years old. Those\n strings are first honoured when the runtime npm-installs them in\n the cloud, and by then the symptom is a tenant that boots and then\n misbehaves against its database.\n\n A warning rather than a hard failure: the CLI cannot know that a\n newer package has actually been published, and refusing to build\n over a guess would be worse than saying it out loud. (`drift` was\n read before the build, above.) */\n if (drift.behind.length > 0) {\n console.log(chalk.yellow(` ⚠ framework dependencies older than this CLI (${cliVersion()}):`));\n for (const dep of drift.behind) {\n console.log(chalk.dim(` ${dep.name}@${dep.range} (${dep.file})`));\n }\n console.log(chalk.dim(\" The image supplies the server, but your bundle supplies the database\"));\n console.log(chalk.dim(\" driver — a newer runtime does not update it.\"));\n console.log(chalk.dim(` Run \\`${upgradeToThisCli()}\\`, then rebuild.`));\n } else if (drift.disagreeing.length > 0) {\n console.log(chalk.yellow(` ⚠ mixed @rebasepro versions declared: ${drift.disagreeing.join(\", \")}`));\n console.log(chalk.dim(\" These are published together and expect to run together.\"));\n console.log(chalk.dim(` Run \\`${upgradeToThisCli()}\\` to pin them alike, then rebuild.`));\n }\n\n /* Fold the project's static apps into the backend bundle, so ONE\n runtime serves the site at `/`, the admin at `/admin` and the API\n at `/api` — the shape the scaffolded template produces and the\n shape a custom container already had.\n\n Without this, moving a project to the managed runtime silently\n removed its website: the API answered perfectly and every page\n 404'd, because the managed pod runs the backend bundle and nothing\n else. Parity with the container being replaced is the only honest\n baseline for calling managed a drop-in.\n\n `--no-static` opts out, for a project that publishes its frontend\n somewhere else and does not want the assets in its bundle. */\n if (!args[\"--no-static\"]) {\n const folded = await foldFrontendIntoBundle({\n projectRoot,\n manifest,\n bundleDir: result.outDir,\n skipBuild: args[\"--skip-static-build\"] === true,\n builtApps,\n log: (m) => console.log(m)\n }).catch((err: unknown) => {\n console.error(chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n });\n for (const outcome of folded ?? []) {\n console.log(\n chalk.green(` ✓ ${outcome.appName} folded in`) +\n chalk.dim(` (${outcome.fileCount} file(s) → served at ${formatAppAddress(outcome)})`)\n );\n }\n }\n } else if (app.type === \"static\") {\n await buildAssetApp(projectRoot, name, app, manifest.rebase, output, { builtApps }).catch((err: unknown) => {\n console.error(chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n });\n }\n\n console.log(\"\");\n }\n\n console.log(chalk.green(\"✓ Build complete.\"));\n}\n\n/**\n * Build a static app and package it into a static bundle.\n *\n * Runs the app's own build command, checks it produced the declared output, then\n * packages that output into a `static`-kind bundle — the same deployable shape as\n * a backend bundle, so a frontend or admin app deploys through the identical\n * path and runs on the identical image, just serving files instead of an API.\n *\n * Throws when the build fails or produces nothing usable, so the caller answers\n * in its own way: `rebase build` with a red line, `rebase cloud deploy --json`\n * with its JSON error.\n */\nexport async function buildAssetApp(\n projectRoot: string,\n name: string,\n app: RebaseAppConfig,\n runtimeRange: string,\n outOverride?: string,\n /**\n * `quietStdout`: every line, the build command's included, goes to stderr. See `toolStdio`.\n * `builtApps`: the static apps already built in this run (see `FoldOptions.builtApps`).\n */\n options: { quietStdout?: boolean; builtApps?: Set<string> } = {}\n): Promise<string | undefined> {\n const asset = app as RebaseStaticAppConfig;\n // The path part is what the app is built for and mounted at; the hostname,\n // when `path` names one, only travels in the bundle.\n const address = staticAppAddress(name, asset);\n const basePath = address.path;\n const say = (line: string): void => {\n if (options.quietStdout) console.error(line);\n else console.log(line);\n };\n\n if (!asset.build) {\n say(chalk.dim(\" no build command declared — skipping\"));\n return undefined;\n }\n\n if (options.builtApps?.has(name)) {\n say(chalk.dim(\" built once already in this run — packaging that output\"));\n } else {\n try {\n await execa(asset.build, {\n cwd: projectRoot,\n stdio: toolStdio(options.quietStdout),\n shell: true,\n env: staticBuildEnv(basePath, name)\n });\n } catch {\n throw new Error(`build command failed for \"${name}\"`);\n }\n options.builtApps?.add(name);\n }\n\n if (!asset.output) {\n say(chalk.yellow(\" no output directory declared — built, but nothing to bundle\"));\n return undefined;\n }\n\n const outputPath = path.join(projectRoot, asset.output);\n if (!fs.existsSync(outputPath)) {\n // The command exited 0 but produced nothing where the manifest says it\n // should. Bundling that would ship an empty site.\n throw new Error(`declared output \"${asset.output}\" does not exist after building`);\n }\n\n // The assets were built for `basePath`; refusing here is the difference\n // between a build error and a blank page nobody can diagnose.\n const indexHtml = path.join(outputPath, \"index.html\");\n if (fs.existsSync(indexHtml)) {\n assertBuiltForPath(fs.readFileSync(indexHtml, \"utf8\"), basePath, name);\n }\n\n // Per-app bundle directory, so a project's several static apps do not clobber\n // one another or the backend's `dist-bundle`.\n const outDir = outOverride\n ? path.resolve(process.cwd(), outOverride)\n : path.join(projectRoot, `dist-bundle-${name}`);\n const result = buildStaticBundle({\n projectRoot,\n appName: name,\n assetsDir: outputPath,\n outDir,\n runtimeRange,\n path: basePath,\n host: address.host,\n spa: asset.spa ?? true,\n cms: asset.cms\n });\n const rel = path.relative(projectRoot, result.outDir);\n say(\n chalk.green(` ✓ static bundle → ${rel}/`) +\n chalk.dim(` (${result.fileCount} file(s) → served at ${formatAppAddress(address)})`)\n );\n return result.outDir;\n}\n\n/**\n * The `rebase upgrade` line the drift warnings print.\n *\n * Aimed at this CLI's own version, because that is what the warning measured\n * against: \"older than this CLI\" is answered by moving to exactly this CLI, not\n * to whatever `latest` happens to be — which, on a canary, is older still.\n */\nfunction upgradeToThisCli(): string {\n const version = cliVersion();\n return version === \"unknown\" ? \"rebase upgrade\" : `rebase upgrade --to ${version}`;\n}\n\n/** The pre-manifest behaviour: build every workspace package. */\nasync function runWorkspaceBuilds(projectRoot: string): Promise<void> {\n const pm = detectPackageManager(projectRoot);\n const cmds = getPMCommands(pm);\n const buildCmd = cmds.runAll(\"build\");\n\n console.log(`${chalk.bold(\"Rebase\")} — Building all workspaces with ${chalk.cyan(pm)}...\\n`);\n\n try {\n await execa(buildCmd[0], buildCmd.slice(1), {\n cwd: projectRoot,\n stdio: \"inherit\"\n });\n } catch {\n console.error(chalk.red(\"\\n✗ Build failed.\"));\n process.exit(1);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,SAAS,YAAkB;CACvB,QAAQ,IAAI;EACd,MAAM,KAAK,cAAc,EAAE;;EAE3B,MAAM,KAAK,OAAO,EAAE;;;EAGpB,MAAM,KAAK,SAAS,EAAE;mEAC2C,mBAAmB;;;;;;;;;;;;;;;EAepF,MAAM,KAAK,UAAU,EAAE;;;;EAIvB,KAAK,CAAC;AACR;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,gBACZ,aACA,MACA,KACQ;CACR,MAAM,aAAa,IAAI,cAAc;CACrC,MAAM,UAAU,IAAI,WAAW;CAC/B,MAAM,aAAa,KAAK,QAAQ,aAAa,OAAO;CACpD,MAAM,cAAc,KAAK,SAAS,YAAY,KAAK,QAAQ,aAAa,UAAU,CAAC;CAEnF,MAAM,QAAQ,GAAG,MAAM,KAAK,6BAA6B,MAAM;CAK/D,IAAI,YAAY,WAAW,IAAI,GAC3B,OAAO;EACH,MAAM,IAAI,OAAO,OAAO;EACxB,MAAM,OAAO,SAAS,WAAW,iCAAiC,QAAQ,mCAAmC;EAC7G,MAAM,IAAI,yEAAyE;CACvF;CAGJ,MAAM,SAAS,MAAM,KAAK,mBAAmB,YAAY,GAAG;CAC5D,OAAO,YAAY,MACb,CAAC,MAAM,IAAI,OAAO,MAAM,UAAU,QAAQ,CAAC,IAC3C,CAAC,MAAM,IAAI,OAAO,OAAO,GAAG,MAAM,IAAI,OAAO,MAAM,KAAK,MAAM,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClG;AAEA,eAAsB,aAAa,UAAoB,CAAC,GAAkB;CACtE,IAAI,UAAU,OAAO,GAAG;EACpB,UAAU;EACV;CACJ;CAEA,MAAM,EAAE,OAAO,MAAM,aAAa,cAAc,iBAAiB;EAC7D,MAAM;GACF,YAAY;GAKZ,SAAS;GACT,qBAAqB;GAKrB,eAAe;GAIf,YAAY;GACZ,iBAAiB;GAIjB,eAAe;GAIf,uBAAuB;GACvB,eAAe;EACnB;EACA;EACA,cAAc;EACd,SAAS;CACb,CAAC;CAED,MAAM,cAAc,mBAAmB;CAEvC,IAAI,KAAK,gBAAgB;EACrB,MAAM,mBAAmB,WAAW;EACpC;CACJ;CAEA,IAAI;CACJ,IAAI;EACA,SAAS,aAAa,WAAW;CACrC,SAAS,KAAK;EACV,IAAI,eAAe,eAAe;GAC9B,QAAQ,MAAM,MAAM,IAAI,KAAK,IAAI,SAAS,CAAC;GAC3C,KAAK,MAAM,SAAS,IAAI,QACpB,QAAQ,MAAM,MAAM,IAAI,OAAO,MAAM,OAAO,GAAG,MAAM,KAAK,MAAM,KAAK,MAAM,SAAS,CAAC;GAEzF,QAAQ,KAAK,CAAC;EAClB;EACA,MAAM;CACV;CAEA,MAAM,EAAE,UAAU,WAAW;CAE7B,IAAI,UAAU,cAAc,QAAQ;CACpC,IAAI,UAAU,SAAS,GAAG;EACtB,MAAM,QAAQ,IAAI,IAAI,QAAQ,KAAI,MAAK,EAAE,IAAI,CAAC;EAC9C,MAAM,UAAU,UAAU,QAAO,SAAQ,CAAC,MAAM,IAAI,IAAI,CAAC;EACzD,IAAI,QAAQ,SAAS,GAAG;GACpB,QAAQ,MAAM,MAAM,IAAI,qBAAqB,QAAQ,KAAK,IAAI,GAAG,CAAC;GAClE,QAAQ,MAAM,MAAM,IAAI,+BAA+B,QAAQ,KAAI,MAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,UAAU,CAAC;GACzG,QAAQ,KAAK,CAAC;EAClB;EACA,UAAU,QAAQ,QAAO,MAAK,UAAU,SAAS,EAAE,IAAI,CAAC;CAC5D;CAEA,IAAI,QAAQ,WAAW,GAAG;EACtB,QAAQ,IAAI,MAAM,OAAO,4CAA4C,CAAC;EACtE;CACJ;CAKA,IAAI,CADY,eAAe,QAC1B,KAAW,WAAW,eAAe;EACtC,QAAQ,IAAI,MAAM,IAAI,uDAAuD,CAAC;EAC9E,MAAM,mBAAmB,WAAW;EACpC;CACJ;CAMA,MAAM,SAAS,KAAK,cAAc,KAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK,WAAW,IAAI,KAAA;CAClF,MAAM,UAAU,QAAQ,QAAQ,EAAE,UAC7B,IAAI,SAAS,aAAa,IAAI,YAAY,YAC1C,IAAI,SAAS,YAAY,QAAQ,IAAI,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAE;CACxE,IAAI,UAAU,QAAQ,SAAS,GAC3B,MAAM,IAAI,WACN,gEAAgE,QAAQ,OAAO,IAC5E,QAAQ,KAAI,MAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,wCACvB,QAAQ,EAAE,CAAC,KAAK,YAAY,KAAK,aACrD;CAGJ,QAAQ,IAAI,GAAG,MAAM,KAAK,QAAQ,EAAE,cAAc,QAAQ,OAAO,UAAU;CAI3E,MAAM,4BAAY,IAAI,IAAY;CAElC,KAAK,MAAM,EAAE,MAAM,SAAS,SAAS;EACjC,QAAQ,IAAI,MAAM,KAAK,KAAK,MAAM,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;EAEjE,IAAI,IAAI,SAAS,aAAa,IAAI,YAAY,UAAU;GAMpD,QAAQ,IAAI,MAAM,IAAI,oEAAoE,CAAC;GAC3F,KAAK,MAAM,QAAQ,gBAAgB,aAAa,MAAM,GAAG,GAAG,QAAQ,IAAI,IAAI;GAC5E,QAAQ,IAAI,EAAE;GACd;EACJ;EAEA,IAAI,IAAI,SAAS,WAAW;GAMxB,MAAM,EAAE,OAAO,eAAe,WAAW,MAAM,oBAAoB,iBAAiB,aAAa,GAAG,CAAC;GACrG,IAAI,OAAO,SAAS,GAAG;IACnB,QAAQ,MAAM,MAAM,IAAI,SAAS,OAAO,OAAO,yCAAyC,CAAC;IACzF,KAAK,MAAM,SAAS,QAAQ,QAAQ,MAAM,OAAO,MAAM,KAAK,MAAM,IAAI,EAAE,IAAI,MAAM,SAAS;IAC3F,QAAQ,MAAM,EAAE;IAChB,QAAQ,WAAW;IACnB;GACJ;GAKA,IAAI,uBAAuB,aAAa,aAAa,CAAC,CAAC,SACnD,QAAQ,IAAI,MAAM,IAAI,KAAK,wBAAwB,qEAAqE,CAAC;GAO7H,MAAM,QAAQ,wBAAwB,aAAa,WAAW,CAAC;GAE/D,MAAM,SAAS,MAAM,YAAY;IAC7B;IACA,SAAS;IACT;IACA,QAAQ;IACR,cAAc,SAAS;IACvB,WAAW;IACX,eAAe,KAAK;IACpB,YAAY,KAAK;IACjB,QAAQ,KAAK,iBAAiB,QAAS,KAAK,cAAc,OAAO,KAAA;GACrE,CAAC;GACD,MAAM,MAAM,KAAK,SAAS,aAAa,OAAO,MAAM;GACpD,QAAQ,IAAI,MAAM,MAAM,gBAAgB,IAAI,EAAE,CAAC;GAK/C,MAAM,gBAAgB,OAAO,SAAS;GACtC,QAAQ,IAAI,MAAM,IACd,OAAO,OAAO,gBAAgB,gBAAgB,gBAAgB,YAAY,kBAAkB,IAChG,CAAC;GASD,IAAI,OAAO,OAAO,UAAU;IACxB,QAAQ,IAAI,MAAM,IAAI,+CAA+C,OAAO,OAAO,QAAQ,GAAG,GAAG,OAAO,OAAO,QAAQ,IAAI,EAAE,CAAC;IAC9H,KAAK,OAAO,OAAO,SAAS,KAAA,WAA6B;KACrD,MAAM,KAAK,KAAK,OAAO,OAAO,OAAO,SAAS,MAAM,OAAO,KAAK;KAMhE,QAAQ,IAAI,MAAM,OACd,+BAA+B,GAAG,uFACF,CAAC;KACrC,QAAQ,IAAI,MAAM,IAAI,sEAAsE,CAAC;IACjG;GACJ,OAAO,IAAI,OAAO,KAAK,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,WAAW,GAI7D,QAAQ,IAAI,MAAM,IAAI,oDAAoD,CAAC;QACxE;IACH,QAAQ,IAAI,MAAM,OAAO,mCAAmC,OAAO,OAAO,SAAS,CAAC;IACpF,QAAQ,IAAI,MAAM,IAAI,gFAAgF,CAAC;GAC3G;GAEA,IAAI,OAAO,SAAS,MAAM,QAAQ;IAC9B,MAAM,SAAS,OAAO,SAAS,MAAM,iBAAiB,CAAC,EAAA,CAAG,KAAI,MAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI;IACpF,QAAQ,IAAI,MAAM,OAAO,uCAAuC,OAAO,CAAC;IACxE,QAAQ,IAAI,MAAM,IAAI,qEAAqE,CAAC;GAChG;GAiBA,IAAI,MAAM,OAAO,SAAS,GAAG;IACzB,QAAQ,IAAI,MAAM,OAAO,qDAAqD,WAAW,EAAE,GAAG,CAAC;IAC/F,KAAK,MAAM,OAAO,MAAM,QACpB,QAAQ,IAAI,MAAM,IAAI,SAAS,IAAI,KAAK,GAAG,IAAI,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;IAE1E,QAAQ,IAAI,MAAM,IAAI,4EAA4E,CAAC;IACnG,QAAQ,IAAI,MAAM,IAAI,oDAAoD,CAAC;IAC3E,QAAQ,IAAI,MAAM,IAAI,eAAe,iBAAiB,EAAE,kBAAkB,CAAC;GAC/E,OAAO,IAAI,MAAM,YAAY,SAAS,GAAG;IACrC,QAAQ,IAAI,MAAM,OAAO,6CAA6C,MAAM,YAAY,KAAK,IAAI,GAAG,CAAC;IACrG,QAAQ,IAAI,MAAM,IAAI,gEAAgE,CAAC;IACvF,QAAQ,IAAI,MAAM,IAAI,eAAe,iBAAiB,EAAE,oCAAoC,CAAC;GACjG;GAeA,IAAI,CAAC,KAAK,gBAAgB;IACtB,MAAM,SAAS,MAAM,uBAAuB;KACxC;KACA;KACA,WAAW,OAAO;KAClB,WAAW,KAAK,2BAA2B;KAC3C;KACA,MAAM,MAAM,QAAQ,IAAI,CAAC;IAC7B,CAAC,CAAC,CAAC,OAAO,QAAiB;KACvB,QAAQ,MAAM,MAAM,IAAI,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAAG,CAAC;KACpF,QAAQ,KAAK,CAAC;IAClB,CAAC;IACD,KAAK,MAAM,WAAW,UAAU,CAAC,GAC7B,QAAQ,IACJ,MAAM,MAAM,SAAS,QAAQ,QAAQ,WAAW,IAChD,MAAM,IAAI,KAAK,QAAQ,UAAU,uBAAuB,iBAAiB,OAAO,EAAE,EAAE,CACxF;GAER;EACJ,OAAO,IAAI,IAAI,SAAS,UACpB,MAAM,cAAc,aAAa,MAAM,KAAK,SAAS,QAAQ,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,QAAiB;GACxG,QAAQ,MAAM,MAAM,IAAI,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAAG,CAAC;GAClF,QAAQ,KAAK,CAAC;EAClB,CAAC;EAGL,QAAQ,IAAI,EAAE;CAClB;CAEA,QAAQ,IAAI,MAAM,MAAM,mBAAmB,CAAC;AAChD;;;;;;;;;;;;;AAcA,eAAsB,cAClB,aACA,MACA,KACA,cACA,aAKA,UAA8D,CAAC,GACpC;CAC3B,MAAM,QAAQ;CAGd,MAAM,UAAU,iBAAiB,MAAM,KAAK;CAC5C,MAAM,WAAW,QAAQ;CACzB,MAAM,OAAO,SAAuB;EAChC,IAAI,QAAQ,aAAa,QAAQ,MAAM,IAAI;OACtC,QAAQ,IAAI,IAAI;CACzB;CAEA,IAAI,CAAC,MAAM,OAAO;EACd,IAAI,MAAM,IAAI,wCAAwC,CAAC;EACvD;CACJ;CAEA,IAAI,QAAQ,WAAW,IAAI,IAAI,GAC3B,IAAI,MAAM,IAAI,0DAA0D,CAAC;MACtE;EACH,IAAI;GACA,MAAM,MAAM,MAAM,OAAO;IACrB,KAAK;IACL,OAAO,UAAU,QAAQ,WAAW;IACpC,OAAO;IACP,KAAK,eAAe,UAAU,IAAI;GACtC,CAAC;EACL,QAAQ;GACJ,MAAM,IAAI,MAAM,6BAA6B,KAAK,EAAE;EACxD;EACA,QAAQ,WAAW,IAAI,IAAI;CAC/B;CAEA,IAAI,CAAC,MAAM,QAAQ;EACf,IAAI,MAAM,OAAO,+DAA+D,CAAC;EACjF;CACJ;CAEA,MAAM,aAAa,KAAK,KAAK,aAAa,MAAM,MAAM;CACtD,IAAI,CAAC,GAAG,WAAW,UAAU,GAGzB,MAAM,IAAI,MAAM,oBAAoB,MAAM,OAAO,gCAAgC;CAKrF,MAAM,YAAY,KAAK,KAAK,YAAY,YAAY;CACpD,IAAI,GAAG,WAAW,SAAS,GACvB,mBAAmB,GAAG,aAAa,WAAW,MAAM,GAAG,UAAU,IAAI;CAQzE,MAAM,SAAS,kBAAkB;EAC7B;EACA,SAAS;EACT,WAAW;EACX,QAPW,cACT,KAAK,QAAQ,QAAQ,IAAI,GAAG,WAAW,IACvC,KAAK,KAAK,aAAa,eAAe,MAAM;EAM9C;EACA,MAAM;EACN,MAAM,QAAQ;EACd,KAAK,MAAM,OAAO;EAClB,KAAK,MAAM;CACf,CAAC;CACD,MAAM,MAAM,KAAK,SAAS,aAAa,OAAO,MAAM;CACpD,IACI,MAAM,MAAM,uBAAuB,IAAI,EAAE,IACzC,MAAM,IAAI,KAAK,OAAO,UAAU,uBAAuB,iBAAiB,OAAO,EAAE,EAAE,CACvF;CACA,OAAO,OAAO;AAClB;;;;;;;;AASA,SAAS,mBAA2B;CAChC,MAAM,UAAU,WAAW;CAC3B,OAAO,YAAY,YAAY,mBAAmB,uBAAuB;AAC7E;;AAGA,eAAe,mBAAmB,aAAoC;CAClE,MAAM,KAAK,qBAAqB,WAAW;CAE3C,MAAM,WADO,cAAc,EACV,CAAA,CAAK,OAAO,OAAO;CAEpC,QAAQ,IAAI,GAAG,MAAM,KAAK,QAAQ,EAAE,kCAAkC,MAAM,KAAK,EAAE,EAAE,MAAM;CAE3F,IAAI;EACA,MAAM,MAAM,SAAS,IAAI,SAAS,MAAM,CAAC,GAAG;GACxC,KAAK;GACL,OAAO;EACX,CAAC;CACL,QAAQ;EACJ,QAAQ,MAAM,MAAM,IAAI,mBAAmB,CAAC;EAC5C,QAAQ,KAAK,CAAC;CAClB;AACJ"}
@@ -1,6 +1,6 @@
1
- import { g as resolveTsx, h as resolvePluginCliScript, l as getActiveBackendPlugin, m as resolveLocalBin } from "./project-g4K6kV1t.js";
1
+ import { g as resolveTsx, h as resolvePluginCliScript, l as getActiveBackendPlugin, m as resolveLocalBin } from "./project-CasK56vN.js";
2
2
  import { n as cliVersion } from "./version-Buyyo1ut.js";
3
- import { g as resolveBackendPaths, u as compareMountOrder } from "./manifest-nvPdLlJY.js";
3
+ import { g as resolveBackendPaths, u as compareMountOrder } from "./manifest-BtzDy7KQ.js";
4
4
  import { n as summarisePortability, t as analyseFunctionsDirectory } from "./function-portability-BIvlvR9q.js";
5
5
  import chalk from "chalk";
6
6
  import fs from "fs";
@@ -16,7 +16,7 @@ import zlib from "zlib";
16
16
  *
17
17
  * Inherited, so its output streams as it happens. With `quietStdout` its stdout
18
18
  * goes to stderr instead, for a command whose own stdout carries a result:
19
- * `rebase cloud deploy` in JSON mode — every piped run — owes stdout exactly one
19
+ * `rebase cloud deploy --json` owes stdout exactly one
20
20
  * JSON value, and a `vite v6 building…` line in front of it is a result no
21
21
  * parser can read. The tool's output still reaches the person watching.
22
22
  */
@@ -570,6 +570,47 @@ var BUNDLE_DEP_MANIFESTS = [
570
570
  "backend/package.json"
571
571
  ];
572
572
  /**
573
+ * Where a project's npm configuration may live, in the order they are joined.
574
+ * npm reads the last value of a repeated key, so the backend's own file wins.
575
+ */
576
+ var BUNDLE_NPMRC_FILES = [".npmrc", "backend/.npmrc"];
577
+ /** npm keys whose value is a credential, bare or scoped to a registry (`//host/:_authToken`). */
578
+ var NPMRC_CREDENTIAL_KEY = /(^|:)(_authToken|_auth|_password|password|username|email|certfile|keyfile)$/;
579
+ /** A value npm expands from the environment at install time: `${NPM_TOKEN}`. */
580
+ var NPMRC_ENV_REFERENCE = /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
581
+ /**
582
+ * The npm configuration a bundle carries, so the runtime's `npm ci` can reach a
583
+ * private registry — or `null` when the project has none.
584
+ *
585
+ * A pod installs the bundle's dependencies when it starts, from the public
586
+ * registry unless told otherwise, so a dependency published to a private
587
+ * registry or under a private scope could not install. This hands npm the
588
+ * project's own `.npmrc`. Credentials stay out of the bundle: every credential
589
+ * must be a `${VAR}` reference, which npm expands from the pod's environment —
590
+ * `rebase cloud env set NPM_TOKEN=… --secret`. A literal token would be
591
+ * uploaded with the code and stored beside every deployment, so it fails the
592
+ * build instead.
593
+ */
594
+ function bundledNpmrc(projectRoot) {
595
+ const parts = [];
596
+ for (const relative of BUNDLE_NPMRC_FILES) {
597
+ const file = path.join(projectRoot, relative);
598
+ if (!fs.existsSync(file)) continue;
599
+ const text = fs.readFileSync(file, "utf8");
600
+ text.split(/\r?\n/).forEach((line, index) => {
601
+ const trimmed = line.trim();
602
+ if (trimmed === "" || trimmed.startsWith("#") || trimmed.startsWith(";")) return;
603
+ const eq = trimmed.indexOf("=");
604
+ if (eq === -1) return;
605
+ const key = trimmed.slice(0, eq).trim();
606
+ const value = trimmed.slice(eq + 1).trim();
607
+ if (NPMRC_CREDENTIAL_KEY.test(key) && !NPMRC_ENV_REFERENCE.test(value)) throw new Error(`${relative}:${index + 1} sets ${key} to a literal value. The bundle would carry it to the platform with your code. Write it as a reference instead — ${key}=\${NPM_TOKEN} — and set the value with \`rebase cloud env set NPM_TOKEN=… --secret\`.`);
608
+ });
609
+ parts.push(`# from ${relative}\n${text.trimEnd()}\n`);
610
+ }
611
+ return parts.length > 0 ? parts.join("\n") : null;
612
+ }
613
+ /**
573
614
  * Specifiers the registry the managed runtime installs from cannot resolve.
574
615
  *
575
616
  * `workspace:` is handled separately (it is normal and expected inside this
@@ -1109,6 +1150,11 @@ async function buildBundle(options) {
1109
1150
  if (fs.existsSync(path.join(projectRoot, paths.schema))) includes.push(paths.schema);
1110
1151
  if (includes.length === 0) throw new Error(`Nothing to build for app "${appName}". Expected a config directory at "${paths.config}" or functions at "${paths.functions}".`);
1111
1152
  if (paths.hasCollections && options.skipSchema !== true) await regenerateSchema(projectRoot, paths.config, options);
1153
+ if (paths.hasCollections) {
1154
+ const { writeRegistrationForBuild } = await import("./generate_sdk-BvcWvoUh.js");
1155
+ const registered = await writeRegistrationForBuild(path.join(projectRoot, paths.config, "collections"), app.registerDatabase === true);
1156
+ if (registered) log(options, chalk.dim(` registered the Database for server-side code in ${path.relative(projectRoot, registered)}/`));
1157
+ }
1112
1158
  const unusedEntry = findUnusedServerEntry(projectRoot, paths.functions);
1113
1159
  if (unusedEntry) {
1114
1160
  const parts = [
@@ -1206,6 +1252,8 @@ async function buildBundle(options) {
1206
1252
  }
1207
1253
  });
1208
1254
  fs.writeFileSync(path.join(outDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
1255
+ const npmrc = bundledNpmrc(projectRoot);
1256
+ if (npmrc) fs.writeFileSync(path.join(outDir, ".npmrc"), npmrc, "utf8");
1209
1257
  fs.writeFileSync(path.join(outDir, "package.json"), `${JSON.stringify({
1210
1258
  name: "rebase-bundle",
1211
1259
  private: true,
@@ -1601,6 +1649,6 @@ function resolveServerVersion(projectRoot) {
1601
1649
  return "unknown";
1602
1650
  }
1603
1651
  //#endregion
1604
- export { foldStaticIntoBundle as _, VENDOR_TARGET_OS as a, toolStdio as b, collectDeclaredDependencies as c, describeDepConflicts as d, detectDeclaredDepConflicts as f, findUnusedServerEntry as g, detectStorageAuthorize as h, VENDOR_TARGET_CPU as i, commentSpans as l, detectNativeDependencies as m, VENDOR_SIZE_MAX_BYTES as n, buildBundle as o, detectFrameworkDepDrift as p, VENDOR_SIZE_WARN_BYTES as r, buildStaticBundle as s, DEFAULT_BUNDLE_DIR as t, composeBundleManifest as u, normalizeEsmSpecifiers as v, vendorDependencies as y };
1652
+ export { findUnusedServerEntry as _, VENDOR_TARGET_OS as a, vendorDependencies as b, bundledNpmrc as c, composeBundleManifest as d, describeDepConflicts as f, detectStorageAuthorize as g, detectNativeDependencies as h, VENDOR_TARGET_CPU as i, collectDeclaredDependencies as l, detectFrameworkDepDrift as m, VENDOR_SIZE_MAX_BYTES as n, buildBundle as o, detectDeclaredDepConflicts as p, VENDOR_SIZE_WARN_BYTES as r, buildStaticBundle as s, DEFAULT_BUNDLE_DIR as t, commentSpans as u, foldStaticIntoBundle as v, toolStdio as x, normalizeEsmSpecifiers as y };
1605
1653
 
1606
- //# sourceMappingURL=bundle-DlqkDYSe.js.map
1654
+ //# sourceMappingURL=bundle-C6yEtMJ-.js.map