everything-dev 1.53.1 → 2.0.0-rc.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 (713) hide show
  1. package/README.md +2 -11
  2. package/dist/_virtual/_rolldown/runtime.cjs +17 -2
  3. package/dist/_virtual/_rolldown/runtime.mjs +36 -0
  4. package/dist/api/auth-middleware.cjs +161 -0
  5. package/dist/api/auth-middleware.cjs.map +1 -0
  6. package/dist/api/auth-middleware.d.cts +69 -0
  7. package/dist/api/auth-middleware.d.mts +69 -0
  8. package/dist/api/auth-middleware.mjs +160 -0
  9. package/dist/api/auth-middleware.mjs.map +1 -0
  10. package/dist/api-contract.cjs +250 -62
  11. package/dist/api-contract.cjs.map +1 -1
  12. package/dist/api-contract.mjs +246 -65
  13. package/dist/api-contract.mjs.map +1 -1
  14. package/dist/app.cjs +99 -26
  15. package/dist/app.cjs.map +1 -1
  16. package/dist/app.d.cts +3 -0
  17. package/dist/app.d.mts +3 -0
  18. package/dist/app.mjs +100 -27
  19. package/dist/app.mjs.map +1 -1
  20. package/dist/auth-login.cjs +163 -0
  21. package/dist/auth-login.cjs.map +1 -0
  22. package/dist/auth-login.mjs +162 -0
  23. package/dist/auth-login.mjs.map +1 -0
  24. package/dist/auth-session.cjs +64 -0
  25. package/dist/auth-session.cjs.map +1 -0
  26. package/dist/auth-session.mjs +58 -0
  27. package/dist/auth-session.mjs.map +1 -0
  28. package/dist/auth-types-gen.cjs +0 -1
  29. package/dist/auth-types-gen.cjs.map +1 -1
  30. package/dist/build.cjs +37 -173
  31. package/dist/build.cjs.map +1 -1
  32. package/dist/build.mjs +37 -171
  33. package/dist/build.mjs.map +1 -1
  34. package/dist/bundle-cache.cjs +74 -0
  35. package/dist/bundle-cache.cjs.map +1 -0
  36. package/dist/bundle-cache.d.cts +27 -0
  37. package/dist/bundle-cache.d.mts +27 -0
  38. package/dist/bundle-cache.mjs +68 -0
  39. package/dist/bundle-cache.mjs.map +1 -0
  40. package/dist/bundle-fs-resolve.cjs +209 -0
  41. package/dist/bundle-fs-resolve.cjs.map +1 -0
  42. package/dist/bundle-fs-resolve.d.cts +76 -0
  43. package/dist/bundle-fs-resolve.d.mts +76 -0
  44. package/dist/bundle-fs-resolve.mjs +202 -0
  45. package/dist/bundle-fs-resolve.mjs.map +1 -0
  46. package/dist/cdn-deploy.cjs +126 -0
  47. package/dist/cdn-deploy.cjs.map +1 -0
  48. package/dist/cdn-deploy.mjs +124 -0
  49. package/dist/cdn-deploy.mjs.map +1 -0
  50. package/dist/cli/db-doctor.cjs +19 -19
  51. package/dist/cli/db-doctor.cjs.map +1 -1
  52. package/dist/cli/db-doctor.mjs +18 -18
  53. package/dist/cli/db-doctor.mjs.map +1 -1
  54. package/dist/cli/db-repair.cjs +9 -32
  55. package/dist/cli/db-repair.cjs.map +1 -1
  56. package/dist/cli/db-repair.mjs +9 -32
  57. package/dist/cli/db-repair.mjs.map +1 -1
  58. package/dist/cli/framework-version.cjs +7 -3
  59. package/dist/cli/framework-version.cjs.map +1 -1
  60. package/dist/cli/framework-version.mjs +7 -3
  61. package/dist/cli/framework-version.mjs.map +1 -1
  62. package/dist/cli/infra.cjs +159 -251
  63. package/dist/cli/infra.cjs.map +1 -1
  64. package/dist/cli/infra.mjs +154 -242
  65. package/dist/cli/infra.mjs.map +1 -1
  66. package/dist/cli/init.cjs +624 -196
  67. package/dist/cli/init.cjs.map +1 -1
  68. package/dist/cli/init.d.cts +61 -8
  69. package/dist/cli/init.d.mts +61 -8
  70. package/dist/cli/init.mjs +613 -194
  71. package/dist/cli/init.mjs.map +1 -1
  72. package/dist/cli/parse.cjs +8 -7
  73. package/dist/cli/parse.cjs.map +1 -1
  74. package/dist/cli/parse.mjs +9 -7
  75. package/dist/cli/parse.mjs.map +1 -1
  76. package/dist/cli/prompts.cjs +14 -1
  77. package/dist/cli/prompts.cjs.map +1 -1
  78. package/dist/cli/prompts.mjs +14 -1
  79. package/dist/cli/prompts.mjs.map +1 -1
  80. package/dist/cli/prune.cjs +220 -0
  81. package/dist/cli/prune.cjs.map +1 -0
  82. package/dist/cli/prune.mjs +220 -0
  83. package/dist/cli/prune.mjs.map +1 -0
  84. package/dist/cli/snapshot.cjs +2 -1
  85. package/dist/cli/snapshot.cjs.map +1 -1
  86. package/dist/cli/snapshot.mjs +2 -1
  87. package/dist/cli/snapshot.mjs.map +1 -1
  88. package/dist/cli/status.cjs +5 -4
  89. package/dist/cli/status.cjs.map +1 -1
  90. package/dist/cli/status.mjs +6 -5
  91. package/dist/cli/status.mjs.map +1 -1
  92. package/dist/cli/sync.cjs +156 -58
  93. package/dist/cli/sync.cjs.map +1 -1
  94. package/dist/cli/sync.mjs +158 -63
  95. package/dist/cli/sync.mjs.map +1 -1
  96. package/dist/cli/timing.cjs +0 -1
  97. package/dist/cli/timing.cjs.map +1 -1
  98. package/dist/cli/upgrade.cjs +95 -69
  99. package/dist/cli/upgrade.cjs.map +1 -1
  100. package/dist/cli/upgrade.mjs +97 -72
  101. package/dist/cli/upgrade.mjs.map +1 -1
  102. package/dist/cli/utils/helpers.cjs.map +1 -1
  103. package/dist/cli.cjs +320 -72
  104. package/dist/cli.cjs.map +1 -1
  105. package/dist/cli.mjs +316 -68
  106. package/dist/cli.mjs.map +1 -1
  107. package/dist/code-artifacts.cjs +76 -8
  108. package/dist/code-artifacts.cjs.map +1 -1
  109. package/dist/code-artifacts.mjs +76 -10
  110. package/dist/code-artifacts.mjs.map +1 -1
  111. package/dist/commands/build.cjs +65 -0
  112. package/dist/commands/build.cjs.map +1 -0
  113. package/dist/commands/build.mjs +65 -0
  114. package/dist/commands/build.mjs.map +1 -0
  115. package/dist/commands/config.cjs +77 -0
  116. package/dist/commands/config.cjs.map +1 -0
  117. package/dist/commands/config.d.cts +8 -0
  118. package/dist/commands/config.d.mts +8 -0
  119. package/dist/commands/config.mjs +74 -0
  120. package/dist/commands/config.mjs.map +1 -0
  121. package/dist/commands/db.cjs +107 -0
  122. package/dist/commands/db.cjs.map +1 -0
  123. package/dist/commands/db.mjs +107 -0
  124. package/dist/commands/db.mjs.map +1 -0
  125. package/dist/commands/deploy.cjs +336 -0
  126. package/dist/commands/deploy.cjs.map +1 -0
  127. package/dist/commands/deploy.mjs +334 -0
  128. package/dist/commands/deploy.mjs.map +1 -0
  129. package/dist/commands/dev.cjs +75 -0
  130. package/dist/commands/dev.cjs.map +1 -0
  131. package/dist/commands/dev.mjs +73 -0
  132. package/dist/commands/dev.mjs.map +1 -0
  133. package/dist/commands/init.cjs +234 -0
  134. package/dist/commands/init.cjs.map +1 -0
  135. package/dist/commands/init.mjs +231 -0
  136. package/dist/commands/init.mjs.map +1 -0
  137. package/dist/commands/keys.cjs +255 -0
  138. package/dist/commands/keys.cjs.map +1 -0
  139. package/dist/commands/keys.mjs +253 -0
  140. package/dist/commands/keys.mjs.map +1 -0
  141. package/dist/commands/ops.cjs +199 -0
  142. package/dist/commands/ops.cjs.map +1 -0
  143. package/dist/commands/ops.mjs +197 -0
  144. package/dist/commands/ops.mjs.map +1 -0
  145. package/dist/commands/plugins.cjs +211 -0
  146. package/dist/commands/plugins.cjs.map +1 -0
  147. package/dist/commands/plugins.mjs +211 -0
  148. package/dist/commands/plugins.mjs.map +1 -0
  149. package/dist/commands/shared.cjs +8 -0
  150. package/dist/commands/shared.cjs.map +1 -0
  151. package/dist/commands/shared.d.cts +6 -0
  152. package/dist/commands/shared.d.mts +6 -0
  153. package/dist/commands/shared.mjs +8 -0
  154. package/dist/commands/shared.mjs.map +1 -0
  155. package/dist/commands/upgrade.cjs +325 -0
  156. package/dist/commands/upgrade.cjs.map +1 -0
  157. package/dist/commands/upgrade.mjs +323 -0
  158. package/dist/commands/upgrade.mjs.map +1 -0
  159. package/dist/components/dev-render.cjs +340 -0
  160. package/dist/components/dev-render.cjs.map +1 -0
  161. package/dist/components/dev-render.mjs +332 -0
  162. package/dist/components/dev-render.mjs.map +1 -0
  163. package/dist/config.cjs +460 -221
  164. package/dist/config.cjs.map +1 -1
  165. package/dist/config.d.cts +491 -48
  166. package/dist/config.d.mts +491 -48
  167. package/dist/config.mjs +439 -212
  168. package/dist/config.mjs.map +1 -1
  169. package/dist/contract.cjs +327 -50
  170. package/dist/contract.cjs.map +1 -1
  171. package/dist/contract.d.cts +1951 -1062
  172. package/dist/contract.d.mts +1951 -1062
  173. package/dist/contract.meta.cjs +107 -12
  174. package/dist/contract.meta.cjs.map +1 -1
  175. package/dist/contract.meta.d.cts +166 -8
  176. package/dist/contract.meta.d.mts +166 -8
  177. package/dist/contract.meta.mjs +107 -11
  178. package/dist/contract.meta.mjs.map +1 -1
  179. package/dist/contract.mjs +580 -327
  180. package/dist/contract.mjs.map +1 -1
  181. package/dist/dag.cjs +5 -3
  182. package/dist/dag.cjs.map +1 -1
  183. package/dist/dag.mjs +6 -3
  184. package/dist/dag.mjs.map +1 -1
  185. package/dist/db/binding.cjs +80 -0
  186. package/dist/db/binding.cjs.map +1 -0
  187. package/dist/db/binding.d.cts +39 -0
  188. package/dist/db/binding.d.mts +39 -0
  189. package/dist/db/binding.mjs +78 -0
  190. package/dist/db/binding.mjs.map +1 -0
  191. package/dist/db/bindings.cjs +78 -0
  192. package/dist/db/bindings.cjs.map +1 -0
  193. package/dist/db/bindings.d.cts +34 -0
  194. package/dist/db/bindings.d.mts +34 -0
  195. package/dist/db/bindings.mjs +76 -0
  196. package/dist/db/bindings.mjs.map +1 -0
  197. package/dist/db/core.cjs +204 -0
  198. package/dist/db/core.cjs.map +1 -0
  199. package/dist/db/core.d.cts +69 -0
  200. package/dist/db/core.d.mts +69 -0
  201. package/dist/db/core.mjs +192 -0
  202. package/dist/db/core.mjs.map +1 -0
  203. package/dist/db/driver.cjs +167 -0
  204. package/dist/db/driver.cjs.map +1 -0
  205. package/dist/db/driver.d.cts +50 -0
  206. package/dist/db/driver.d.mts +50 -0
  207. package/dist/db/driver.mjs +165 -0
  208. package/dist/db/driver.mjs.map +1 -0
  209. package/dist/db/drizzle-kit.cjs +177 -0
  210. package/dist/db/drizzle-kit.cjs.map +1 -0
  211. package/dist/db/drizzle-kit.d.cts +25 -0
  212. package/dist/db/drizzle-kit.d.mts +25 -0
  213. package/dist/db/drizzle-kit.mjs +175 -0
  214. package/dist/db/drizzle-kit.mjs.map +1 -0
  215. package/dist/db/errors.cjs +27 -0
  216. package/dist/db/errors.cjs.map +1 -0
  217. package/dist/db/errors.d.cts +16 -0
  218. package/dist/db/errors.d.mts +16 -0
  219. package/dist/db/errors.mjs +26 -0
  220. package/dist/db/errors.mjs.map +1 -0
  221. package/dist/db/identity.cjs +55 -0
  222. package/dist/db/identity.cjs.map +1 -0
  223. package/dist/db/identity.d.cts +40 -0
  224. package/dist/db/identity.d.mts +40 -0
  225. package/dist/db/identity.mjs +53 -0
  226. package/dist/db/identity.mjs.map +1 -0
  227. package/dist/db/index.cjs +43 -0
  228. package/dist/db/index.d.cts +9 -0
  229. package/dist/db/index.d.mts +9 -0
  230. package/dist/db/index.mjs +10 -0
  231. package/dist/db/run-migrations.cjs +343 -0
  232. package/dist/db/run-migrations.cjs.map +1 -0
  233. package/dist/db/run-migrations.d.cts +87 -0
  234. package/dist/db/run-migrations.d.mts +87 -0
  235. package/dist/db/run-migrations.mjs +341 -0
  236. package/dist/db/run-migrations.mjs.map +1 -0
  237. package/dist/delegate-signer.cjs +85 -0
  238. package/dist/delegate-signer.cjs.map +1 -0
  239. package/dist/delegate-signer.mjs +84 -0
  240. package/dist/delegate-signer.mjs.map +1 -0
  241. package/dist/deploy-diff.cjs +119 -0
  242. package/dist/deploy-diff.cjs.map +1 -0
  243. package/dist/deploy-diff.mjs +109 -0
  244. package/dist/deploy-diff.mjs.map +1 -0
  245. package/dist/descriptor/constructors.cjs +49 -0
  246. package/dist/descriptor/constructors.cjs.map +1 -0
  247. package/dist/descriptor/constructors.d.cts +27 -0
  248. package/dist/descriptor/constructors.d.mts +27 -0
  249. package/dist/descriptor/constructors.mjs +45 -0
  250. package/dist/descriptor/constructors.mjs.map +1 -0
  251. package/dist/descriptor/index.cjs +24 -0
  252. package/dist/descriptor/index.d.cts +5 -0
  253. package/dist/descriptor/index.d.mts +5 -0
  254. package/dist/descriptor/index.mjs +6 -0
  255. package/dist/descriptor/resolve.cjs +258 -0
  256. package/dist/descriptor/resolve.cjs.map +1 -0
  257. package/dist/descriptor/resolve.d.cts +50 -0
  258. package/dist/descriptor/resolve.d.mts +50 -0
  259. package/dist/descriptor/resolve.mjs +252 -0
  260. package/dist/descriptor/resolve.mjs.map +1 -0
  261. package/dist/descriptor/schema.cjs +109 -0
  262. package/dist/descriptor/schema.cjs.map +1 -0
  263. package/dist/descriptor/schema.d.cts +217 -0
  264. package/dist/descriptor/schema.d.mts +217 -0
  265. package/dist/descriptor/schema.mjs +102 -0
  266. package/dist/descriptor/schema.mjs.map +1 -0
  267. package/dist/descriptor/serialize.cjs +45 -0
  268. package/dist/descriptor/serialize.cjs.map +1 -0
  269. package/dist/descriptor/serialize.d.cts +7 -0
  270. package/dist/descriptor/serialize.d.mts +7 -0
  271. package/dist/descriptor/serialize.mjs +45 -0
  272. package/dist/descriptor/serialize.mjs.map +1 -0
  273. package/dist/dev-log-pipeline.cjs +273 -0
  274. package/dist/dev-log-pipeline.cjs.map +1 -0
  275. package/dist/dev-log-pipeline.mjs +267 -0
  276. package/dist/dev-log-pipeline.mjs.map +1 -0
  277. package/dist/dev-logs.cjs +39 -8
  278. package/dist/dev-logs.cjs.map +1 -1
  279. package/dist/dev-logs.mjs +37 -9
  280. package/dist/dev-logs.mjs.map +1 -1
  281. package/dist/dev-program.cjs +405 -0
  282. package/dist/dev-program.cjs.map +1 -0
  283. package/dist/dev-program.d.cts +10 -0
  284. package/dist/dev-program.d.mts +10 -0
  285. package/dist/dev-program.mjs +395 -0
  286. package/dist/dev-program.mjs.map +1 -0
  287. package/dist/dev-session-data.d.cts +27 -0
  288. package/dist/dev-session-data.d.mts +27 -0
  289. package/dist/dev-session.cjs +178 -105
  290. package/dist/dev-session.cjs.map +1 -1
  291. package/dist/dev-session.mjs +180 -105
  292. package/dist/dev-session.mjs.map +1 -1
  293. package/dist/env/process-env.cjs +16 -0
  294. package/dist/env/process-env.cjs.map +1 -0
  295. package/dist/env/process-env.mjs +13 -0
  296. package/dist/env/process-env.mjs.map +1 -0
  297. package/dist/env/project-env.cjs +144 -0
  298. package/dist/env/project-env.cjs.map +1 -0
  299. package/dist/env/project-env.d.cts +1 -0
  300. package/dist/env/project-env.d.mts +1 -0
  301. package/dist/env/project-env.mjs +132 -0
  302. package/dist/env/project-env.mjs.map +1 -0
  303. package/dist/fastkv.cjs +59 -12
  304. package/dist/fastkv.cjs.map +1 -1
  305. package/dist/fastkv.d.cts +42 -6
  306. package/dist/fastkv.d.mts +42 -6
  307. package/dist/fastkv.mjs +58 -13
  308. package/dist/fastkv.mjs.map +1 -1
  309. package/dist/fingerprint.cjs +57 -0
  310. package/dist/fingerprint.cjs.map +1 -0
  311. package/dist/fingerprint.d.cts +14 -0
  312. package/dist/fingerprint.d.mts +14 -0
  313. package/dist/fingerprint.mjs +55 -0
  314. package/dist/fingerprint.mjs.map +1 -0
  315. package/dist/http-client.cjs +17 -17
  316. package/dist/http-client.cjs.map +1 -1
  317. package/dist/http-client.mjs +17 -17
  318. package/dist/http-client.mjs.map +1 -1
  319. package/dist/image-deploy.cjs +186 -0
  320. package/dist/image-deploy.cjs.map +1 -0
  321. package/dist/image-deploy.mjs +182 -0
  322. package/dist/image-deploy.mjs.map +1 -0
  323. package/dist/index.cjs +66 -18
  324. package/dist/index.d.cts +8 -7
  325. package/dist/index.d.mts +8 -7
  326. package/dist/index.mjs +6 -5
  327. package/dist/infra/docker.cjs +77 -0
  328. package/dist/infra/docker.cjs.map +1 -0
  329. package/dist/infra/docker.d.cts +10 -0
  330. package/dist/infra/docker.d.mts +10 -0
  331. package/dist/infra/docker.mjs +69 -0
  332. package/dist/infra/docker.mjs.map +1 -0
  333. package/dist/infra/materializer.cjs +74 -0
  334. package/dist/infra/materializer.cjs.map +1 -0
  335. package/dist/infra/materializer.mjs +70 -0
  336. package/dist/infra/materializer.mjs.map +1 -0
  337. package/dist/infra/planner.cjs +135 -103
  338. package/dist/infra/planner.cjs.map +1 -1
  339. package/dist/infra/planner.mjs +137 -104
  340. package/dist/infra/planner.mjs.map +1 -1
  341. package/dist/infra/port-ownership.cjs +57 -0
  342. package/dist/infra/port-ownership.cjs.map +1 -0
  343. package/dist/infra/port-ownership.mjs +57 -0
  344. package/dist/infra/port-ownership.mjs.map +1 -0
  345. package/dist/infra/preflight.cjs +45 -33
  346. package/dist/infra/preflight.cjs.map +1 -1
  347. package/dist/infra/preflight.d.cts +1 -0
  348. package/dist/infra/preflight.d.mts +1 -0
  349. package/dist/infra/preflight.mjs +46 -34
  350. package/dist/infra/preflight.mjs.map +1 -1
  351. package/dist/infra/types.cjs.map +1 -1
  352. package/dist/infra/types.d.cts +2 -0
  353. package/dist/infra/types.d.mts +2 -0
  354. package/dist/infra/types.mjs.map +1 -1
  355. package/dist/integrity.cjs +50 -61
  356. package/dist/integrity.cjs.map +1 -1
  357. package/dist/integrity.d.cts +16 -10
  358. package/dist/integrity.d.mts +16 -10
  359. package/dist/integrity.mjs +50 -59
  360. package/dist/integrity.mjs.map +1 -1
  361. package/dist/internal/manifest-normalizer.cjs +8 -2
  362. package/dist/internal/manifest-normalizer.cjs.map +1 -1
  363. package/dist/internal/manifest-normalizer.mjs +9 -3
  364. package/dist/internal/manifest-normalizer.mjs.map +1 -1
  365. package/dist/merge.cjs +19 -1
  366. package/dist/merge.cjs.map +1 -1
  367. package/dist/merge.d.cts +1 -1
  368. package/dist/merge.d.mts +1 -1
  369. package/dist/merge.mjs +19 -2
  370. package/dist/merge.mjs.map +1 -1
  371. package/dist/mf.cjs +190 -3
  372. package/dist/mf.cjs.map +1 -1
  373. package/dist/mf.d.cts +24 -2
  374. package/dist/mf.d.mts +24 -2
  375. package/dist/mf.mjs +189 -4
  376. package/dist/mf.mjs.map +1 -1
  377. package/dist/near-cli.cjs +59 -91
  378. package/dist/near-cli.cjs.map +1 -1
  379. package/dist/near-cli.mjs +58 -90
  380. package/dist/near-cli.mjs.map +1 -1
  381. package/dist/near-signer.cjs +73 -0
  382. package/dist/near-signer.cjs.map +1 -0
  383. package/dist/near-signer.mjs +70 -0
  384. package/dist/near-signer.mjs.map +1 -0
  385. package/dist/network.cjs +0 -1
  386. package/dist/network.cjs.map +1 -1
  387. package/dist/orchestrator.cjs +256 -87
  388. package/dist/orchestrator.cjs.map +1 -1
  389. package/dist/orchestrator.mjs +248 -87
  390. package/dist/orchestrator.mjs.map +1 -1
  391. package/dist/platform-deploy.cjs +81 -0
  392. package/dist/platform-deploy.cjs.map +1 -0
  393. package/dist/platform-deploy.mjs +80 -0
  394. package/dist/platform-deploy.mjs.map +1 -0
  395. package/dist/plugin.cjs +54 -1389
  396. package/dist/plugin.cjs.map +1 -1
  397. package/dist/plugin.d.cts +6 -896
  398. package/dist/plugin.d.mts +6 -896
  399. package/dist/plugin.mjs +53 -1387
  400. package/dist/plugin.mjs.map +1 -1
  401. package/dist/process-kill.cjs +44 -0
  402. package/dist/process-kill.cjs.map +1 -0
  403. package/dist/process-kill.mjs +43 -0
  404. package/dist/process-kill.mjs.map +1 -0
  405. package/dist/process-registry.cjs +64 -9
  406. package/dist/process-registry.cjs.map +1 -1
  407. package/dist/process-registry.mjs +61 -10
  408. package/dist/process-registry.mjs.map +1 -1
  409. package/dist/progress.cjs +45 -0
  410. package/dist/progress.cjs.map +1 -0
  411. package/dist/progress.d.cts +13 -0
  412. package/dist/progress.d.mts +13 -0
  413. package/dist/progress.mjs +42 -0
  414. package/dist/progress.mjs.map +1 -0
  415. package/dist/publish.cjs +513 -79
  416. package/dist/publish.cjs.map +1 -1
  417. package/dist/publish.mjs +515 -82
  418. package/dist/publish.mjs.map +1 -1
  419. package/dist/registry-use.cjs +41 -0
  420. package/dist/registry-use.cjs.map +1 -0
  421. package/dist/registry-use.mjs +40 -0
  422. package/dist/registry-use.mjs.map +1 -0
  423. package/dist/resolution/session.cjs +335 -0
  424. package/dist/resolution/session.cjs.map +1 -0
  425. package/dist/resolution/session.d.cts +105 -0
  426. package/dist/resolution/session.d.mts +105 -0
  427. package/dist/resolution/session.mjs +331 -0
  428. package/dist/resolution/session.mjs.map +1 -0
  429. package/dist/rollback.cjs +131 -0
  430. package/dist/rollback.cjs.map +1 -0
  431. package/dist/rollback.mjs +128 -0
  432. package/dist/rollback.mjs.map +1 -0
  433. package/dist/sdk.cjs +7 -7
  434. package/dist/sdk.d.cts +3 -3
  435. package/dist/sdk.d.mts +3 -3
  436. package/dist/sdk.mjs +2 -2
  437. package/dist/service-descriptor.cjs +67 -34
  438. package/dist/service-descriptor.cjs.map +1 -1
  439. package/dist/service-descriptor.d.cts +4 -1
  440. package/dist/service-descriptor.d.mts +3 -0
  441. package/dist/service-descriptor.mjs +63 -35
  442. package/dist/service-descriptor.mjs.map +1 -1
  443. package/dist/shared-deps.cjs +17 -16
  444. package/dist/shared-deps.cjs.map +1 -1
  445. package/dist/shared-deps.mjs +17 -16
  446. package/dist/shared-deps.mjs.map +1 -1
  447. package/dist/start-config-source.cjs +24 -0
  448. package/dist/start-config-source.cjs.map +1 -0
  449. package/dist/start-config-source.d.cts +29 -0
  450. package/dist/start-config-source.d.mts +29 -0
  451. package/dist/start-config-source.mjs +22 -0
  452. package/dist/start-config-source.mjs.map +1 -0
  453. package/dist/storage-upload.cjs +145 -0
  454. package/dist/storage-upload.cjs.map +1 -0
  455. package/dist/storage-upload.mjs +143 -0
  456. package/dist/storage-upload.mjs.map +1 -0
  457. package/dist/types.cjs +126 -20
  458. package/dist/types.cjs.map +1 -1
  459. package/dist/types.d.cts +867 -585
  460. package/dist/types.d.mts +867 -585
  461. package/dist/types.mjs +307 -208
  462. package/dist/types.mjs.map +1 -1
  463. package/dist/ui/api.cjs +105 -0
  464. package/dist/ui/api.cjs.map +1 -0
  465. package/dist/ui/api.d.cts +31 -0
  466. package/dist/ui/api.d.mts +31 -0
  467. package/dist/ui/api.mjs +99 -0
  468. package/dist/ui/api.mjs.map +1 -0
  469. package/dist/ui/auth-guards.cjs +50 -0
  470. package/dist/ui/auth-guards.cjs.map +1 -0
  471. package/dist/ui/auth-guards.d.cts +39 -0
  472. package/dist/ui/auth-guards.d.mts +39 -0
  473. package/dist/ui/auth-guards.mjs +48 -0
  474. package/dist/ui/auth-guards.mjs.map +1 -0
  475. package/dist/ui/auth.cjs +197 -0
  476. package/dist/ui/auth.cjs.map +1 -0
  477. package/dist/ui/auth.d.cts +56 -0
  478. package/dist/ui/auth.d.mts +56 -0
  479. package/dist/ui/auth.mjs +179 -0
  480. package/dist/ui/auth.mjs.map +1 -0
  481. package/dist/ui/entry.cjs +16 -0
  482. package/dist/ui/entry.cjs.map +1 -0
  483. package/dist/ui/entry.d.cts +12 -0
  484. package/dist/ui/entry.d.mts +12 -0
  485. package/dist/ui/entry.mjs +15 -0
  486. package/dist/ui/entry.mjs.map +1 -0
  487. package/dist/ui/head.cjs +14 -7
  488. package/dist/ui/head.cjs.map +1 -1
  489. package/dist/ui/head.mjs +15 -7
  490. package/dist/ui/head.mjs.map +1 -1
  491. package/dist/ui/hydrate.cjs +265 -0
  492. package/dist/ui/hydrate.cjs.map +1 -0
  493. package/dist/ui/hydrate.d.cts +48 -0
  494. package/dist/ui/hydrate.d.mts +48 -0
  495. package/dist/ui/hydrate.mjs +263 -0
  496. package/dist/ui/hydrate.mjs.map +1 -0
  497. package/dist/ui/i18n.cjs +153 -0
  498. package/dist/ui/i18n.cjs.map +1 -0
  499. package/dist/ui/i18n.d.cts +29 -0
  500. package/dist/ui/i18n.d.mts +29 -0
  501. package/dist/ui/i18n.mjs +140 -0
  502. package/dist/ui/i18n.mjs.map +1 -0
  503. package/dist/ui/index.cjs +19 -1
  504. package/dist/ui/index.d.cts +6 -3
  505. package/dist/ui/index.d.mts +6 -3
  506. package/dist/ui/index.mjs +5 -2
  507. package/dist/ui/locale.cjs +53 -0
  508. package/dist/ui/locale.cjs.map +1 -0
  509. package/dist/ui/locale.d.cts +18 -0
  510. package/dist/ui/locale.d.mts +18 -0
  511. package/dist/ui/locale.mjs +49 -0
  512. package/dist/ui/locale.mjs.map +1 -0
  513. package/dist/ui/manifest/index.cjs +25 -0
  514. package/dist/ui/manifest/index.cjs.map +1 -0
  515. package/dist/ui/manifest/index.d.cts +9 -0
  516. package/dist/ui/manifest/index.d.mts +9 -0
  517. package/dist/ui/manifest/index.mjs +13 -0
  518. package/dist/ui/manifest/index.mjs.map +1 -0
  519. package/dist/ui/manifest-generator.cjs +8 -0
  520. package/dist/ui/manifest-generator.d.cts +1 -0
  521. package/dist/ui/manifest-generator.d.mts +1 -0
  522. package/dist/ui/manifest-generator.mjs +3 -0
  523. package/dist/ui/message-catalogs.cjs +8 -0
  524. package/dist/ui/message-catalogs.cjs.map +1 -0
  525. package/dist/ui/message-catalogs.d.cts +5 -0
  526. package/dist/ui/message-catalogs.d.mts +5 -0
  527. package/dist/ui/message-catalogs.mjs +8 -0
  528. package/dist/ui/message-catalogs.mjs.map +1 -0
  529. package/dist/ui/metadata.cjs +0 -1
  530. package/dist/ui/metadata.cjs.map +1 -1
  531. package/dist/ui/metadata.d.cts +1 -1
  532. package/dist/ui/metadata.d.mts +1 -1
  533. package/dist/ui/plugin-path.cjs +37 -0
  534. package/dist/ui/plugin-path.cjs.map +1 -0
  535. package/dist/ui/plugin-path.d.cts +25 -0
  536. package/dist/ui/plugin-path.d.mts +25 -0
  537. package/dist/ui/plugin-path.mjs +35 -0
  538. package/dist/ui/plugin-path.mjs.map +1 -0
  539. package/dist/ui/router-client.cjs +61 -0
  540. package/dist/ui/router-client.cjs.map +1 -0
  541. package/dist/ui/router-client.d.cts +20 -0
  542. package/dist/ui/router-client.d.mts +20 -0
  543. package/dist/ui/router-client.mjs +60 -0
  544. package/dist/ui/router-client.mjs.map +1 -0
  545. package/dist/ui/router-defaults.cjs +48 -0
  546. package/dist/ui/router-defaults.cjs.map +1 -0
  547. package/dist/ui/router-defaults.d.cts +8 -0
  548. package/dist/ui/router-defaults.d.mts +8 -0
  549. package/dist/ui/router-defaults.mjs +45 -0
  550. package/dist/ui/router-defaults.mjs.map +1 -0
  551. package/dist/ui/router-error.cjs +70 -0
  552. package/dist/ui/router-error.cjs.map +1 -0
  553. package/dist/ui/router-error.d.cts +19 -0
  554. package/dist/ui/router-error.d.mts +19 -0
  555. package/dist/ui/router-error.mjs +69 -0
  556. package/dist/ui/router-error.mjs.map +1 -0
  557. package/dist/ui/router-server.cjs +153 -0
  558. package/dist/ui/router-server.cjs.map +1 -0
  559. package/dist/ui/router-server.d.cts +38 -0
  560. package/dist/ui/router-server.d.mts +38 -0
  561. package/dist/ui/router-server.mjs +152 -0
  562. package/dist/ui/router-server.mjs.map +1 -0
  563. package/dist/ui/router.cjs +4 -16
  564. package/dist/ui/router.cjs.map +1 -1
  565. package/dist/ui/router.mjs +4 -15
  566. package/dist/ui/router.mjs.map +1 -1
  567. package/dist/ui/runtime.cjs +5 -1
  568. package/dist/ui/runtime.cjs.map +1 -1
  569. package/dist/ui/runtime.d.cts +2 -1
  570. package/dist/ui/runtime.d.mts +2 -1
  571. package/dist/ui/runtime.mjs +5 -1
  572. package/dist/ui/runtime.mjs.map +1 -1
  573. package/dist/ui/slot.cjs +34 -0
  574. package/dist/ui/slot.cjs.map +1 -0
  575. package/dist/ui/slot.d.cts +43 -0
  576. package/dist/ui/slot.d.mts +43 -0
  577. package/dist/ui/slot.mjs +34 -0
  578. package/dist/ui/slot.mjs.map +1 -0
  579. package/dist/ui/tenant.cjs +300 -0
  580. package/dist/ui/tenant.cjs.map +1 -0
  581. package/dist/ui/tenant.d.cts +122 -0
  582. package/dist/ui/tenant.d.mts +122 -0
  583. package/dist/ui/tenant.mjs +279 -0
  584. package/dist/ui/tenant.mjs.map +1 -0
  585. package/dist/ui/types.d.cts +32 -2
  586. package/dist/ui/types.d.mts +32 -2
  587. package/dist/ui/version-check.cjs +47 -0
  588. package/dist/ui/version-check.cjs.map +1 -0
  589. package/dist/ui/version-check.d.cts +23 -0
  590. package/dist/ui/version-check.d.mts +23 -0
  591. package/dist/ui/version-check.mjs +46 -0
  592. package/dist/ui/version-check.mjs.map +1 -0
  593. package/dist/utils/banner.cjs +2 -2
  594. package/dist/utils/banner.cjs.map +1 -1
  595. package/dist/utils/banner.mjs +2 -2
  596. package/dist/utils/banner.mjs.map +1 -1
  597. package/dist/utils/linkify.cjs +1 -1
  598. package/dist/utils/linkify.cjs.map +1 -1
  599. package/dist/utils/linkify.mjs +1 -0
  600. package/dist/utils/linkify.mjs.map +1 -1
  601. package/dist/utils/run.cjs +6 -6
  602. package/dist/utils/run.cjs.map +1 -1
  603. package/dist/utils/run.mjs +6 -6
  604. package/dist/utils/run.mjs.map +1 -1
  605. package/dist/utils/save-config.cjs +12 -0
  606. package/dist/utils/save-config.cjs.map +1 -1
  607. package/dist/utils/save-config.mjs +12 -0
  608. package/dist/utils/save-config.mjs.map +1 -1
  609. package/dist/utils/snapshot-hash.cjs +10 -0
  610. package/dist/utils/snapshot-hash.cjs.map +1 -0
  611. package/dist/utils/snapshot-hash.mjs +10 -0
  612. package/dist/utils/snapshot-hash.mjs.map +1 -0
  613. package/dist/utils/string.cjs +0 -1
  614. package/dist/utils/string.cjs.map +1 -1
  615. package/dist/utils/theme.cjs +30 -12
  616. package/dist/utils/theme.cjs.map +1 -1
  617. package/dist/utils/theme.mjs +30 -11
  618. package/dist/utils/theme.mjs.map +1 -1
  619. package/dist/version-manifest-deploy.cjs +50 -0
  620. package/dist/version-manifest-deploy.cjs.map +1 -0
  621. package/dist/version-manifest-deploy.mjs +49 -0
  622. package/dist/version-manifest-deploy.mjs.map +1 -0
  623. package/dist/version-manifest-resolve.cjs +42 -0
  624. package/dist/version-manifest-resolve.cjs.map +1 -0
  625. package/dist/version-manifest-resolve.d.cts +38 -0
  626. package/dist/version-manifest-resolve.d.mts +38 -0
  627. package/dist/version-manifest-resolve.mjs +40 -0
  628. package/dist/version-manifest-resolve.mjs.map +1 -0
  629. package/dist/version-status.cjs +18 -0
  630. package/dist/version-status.cjs.map +1 -0
  631. package/dist/version-status.d.cts +22 -0
  632. package/dist/version-status.d.mts +22 -0
  633. package/dist/version-status.mjs +17 -0
  634. package/dist/version-status.mjs.map +1 -0
  635. package/dist/workspace-catalog.cjs +53 -0
  636. package/dist/workspace-catalog.cjs.map +1 -0
  637. package/dist/workspace-catalog.mjs +51 -0
  638. package/dist/workspace-catalog.mjs.map +1 -0
  639. package/dist/workspace.cjs +237 -0
  640. package/dist/workspace.cjs.map +1 -0
  641. package/dist/workspace.mjs +233 -0
  642. package/dist/workspace.mjs.map +1 -0
  643. package/package.json +179 -27
  644. package/skills/add-a-route/SKILL.md +132 -0
  645. package/skills/api-and-auth/SKILL.md +87 -21
  646. package/skills/api-and-auth/references/middleware.md +1 -1
  647. package/skills/cli-reference/SKILL.md +48 -21
  648. package/skills/code-style/SKILL.md +8 -0
  649. package/skills/dev-workflow/SKILL.md +50 -26
  650. package/skills/extends-config/SKILL.md +31 -19
  651. package/skills/init-upgrade/SKILL.md +29 -16
  652. package/skills/plugin-development/SKILL.md +46 -112
  653. package/skills/plugin-development/references/database.md +82 -0
  654. package/skills/plugin-development/references/request-context.md +67 -0
  655. package/skills/publish-sync/SKILL.md +99 -22
  656. package/skills/registry/SKILL.md +82 -0
  657. package/skills/super-app/SKILL.md +25 -15
  658. package/skills/talk-to-the-app/SKILL.md +138 -0
  659. package/skills/ui-integration/SKILL.md +93 -11
  660. package/dist/cli/db-studio.cjs +0 -131
  661. package/dist/cli/db-studio.cjs.map +0 -1
  662. package/dist/cli/db-studio.mjs +0 -127
  663. package/dist/cli/db-studio.mjs.map +0 -1
  664. package/dist/cli/init.d.cts.map +0 -1
  665. package/dist/cli/init.d.mts.map +0 -1
  666. package/dist/components/dev-view.cjs +0 -309
  667. package/dist/components/dev-view.cjs.map +0 -1
  668. package/dist/components/dev-view.mjs +0 -309
  669. package/dist/components/dev-view.mjs.map +0 -1
  670. package/dist/components/streaming-view.cjs +0 -134
  671. package/dist/components/streaming-view.cjs.map +0 -1
  672. package/dist/components/streaming-view.mjs +0 -132
  673. package/dist/components/streaming-view.mjs.map +0 -1
  674. package/dist/config.d.cts.map +0 -1
  675. package/dist/config.d.mts.map +0 -1
  676. package/dist/contract.d.cts.map +0 -1
  677. package/dist/contract.d.mts.map +0 -1
  678. package/dist/contract.meta.d.cts.map +0 -1
  679. package/dist/contract.meta.d.mts.map +0 -1
  680. package/dist/dag.d.cts.map +0 -1
  681. package/dist/dag.d.mts.map +0 -1
  682. package/dist/db.cjs +0 -81
  683. package/dist/db.cjs.map +0 -1
  684. package/dist/db.d.cts +0 -30
  685. package/dist/db.d.cts.map +0 -1
  686. package/dist/db.d.mts +0 -30
  687. package/dist/db.d.mts.map +0 -1
  688. package/dist/db.mjs +0 -75
  689. package/dist/db.mjs.map +0 -1
  690. package/dist/fastkv.d.cts.map +0 -1
  691. package/dist/fastkv.d.mts.map +0 -1
  692. package/dist/integrity.d.cts.map +0 -1
  693. package/dist/integrity.d.mts.map +0 -1
  694. package/dist/merge.d.cts.map +0 -1
  695. package/dist/merge.d.mts.map +0 -1
  696. package/dist/mf.d.cts.map +0 -1
  697. package/dist/mf.d.mts.map +0 -1
  698. package/dist/plugin.d.cts.map +0 -1
  699. package/dist/plugin.d.mts.map +0 -1
  700. package/dist/service-descriptor.d.cts.map +0 -1
  701. package/dist/service-descriptor.d.mts.map +0 -1
  702. package/dist/types.d.cts.map +0 -1
  703. package/dist/types.d.mts.map +0 -1
  704. package/dist/ui/head.d.cts.map +0 -1
  705. package/dist/ui/head.d.mts.map +0 -1
  706. package/dist/ui/metadata.d.cts.map +0 -1
  707. package/dist/ui/metadata.d.mts.map +0 -1
  708. package/dist/ui/router.d.cts.map +0 -1
  709. package/dist/ui/router.d.mts.map +0 -1
  710. package/dist/ui/runtime.d.cts.map +0 -1
  711. package/dist/ui/runtime.d.mts.map +0 -1
  712. package/dist/ui/types.d.cts.map +0 -1
  713. package/dist/ui/types.d.mts.map +0 -1
@@ -0,0 +1,126 @@
1
+ //#region src/cdn-deploy.ts
2
+ const LOCAL_HOSTNAMES = /* @__PURE__ */ new Set([
3
+ "localhost",
4
+ "127.0.0.1",
5
+ "::1",
6
+ "[::1]",
7
+ "0.0.0.0",
8
+ "local"
9
+ ]);
10
+ /** Local/private destinations can never serve production bundles. */
11
+ function isLocalOrigin(url) {
12
+ try {
13
+ const { hostname, protocol } = new URL(url);
14
+ if (protocol !== "http:" && protocol !== "https:") return true;
15
+ const host = hostname.toLowerCase().replace(/^\[|\]$/g, "");
16
+ return LOCAL_HOSTNAMES.has(host) || host.endsWith(".localhost") || host.endsWith(".local") || /^127\.\d+\.\d+\.\d+$/.test(host) || /^10\.\d+\.\d+\.\d+$/.test(host) || /^192\.168\.\d+\.\d+$/.test(host) || /^172\.(1[6-9]|2\d|3[01])\.\d+\.\d+$/.test(host) || host.startsWith("169.254.") || host.includes(":") && (host.startsWith("fe80:") || host.startsWith("fc") || host.startsWith("fd"));
17
+ } catch {
18
+ return true;
19
+ }
20
+ }
21
+ /**
22
+ * Deploy origin resolution (ADR 0020, as amended): the CDN origin comes from
23
+ * the env or the authored `cdn.origin` (inherited via extends) — a hard
24
+ * requirement when uploads are planned, because the host never serves
25
+ * `/bundles` itself. The upload origin is the env, the `bos login` session's
26
+ * siteUrl, or the runtime's own gateway. A session pinned to a local site is
27
+ * a hard error (the origin can only ever be a squatter's port); an env-pinned
28
+ * local origin is deliberate local testing and only warns. Config-only
29
+ * publishes (`uploadsPlanned: false`) ship the committed config verbatim —
30
+ * no origins are resolved and nothing is required.
31
+ */
32
+ function resolveCdnDeployInputs(input) {
33
+ const envCdnOrigin = input.env.BOS_BUNDLE_CDN_ORIGIN?.replace(/\/$/, "");
34
+ const configCdnOrigin = input.bosConfig?.cdn?.origin?.replace(/\/$/, "");
35
+ const storageEnvOrigin = input.env.BOS_STORAGE_ORIGIN?.replace(/\/$/, "");
36
+ const sessionSite = input.session?.siteUrl?.replace(/\/$/, "");
37
+ const apiKey = input.env.BOS_STORAGE_API_KEY ?? input.session?.apiKey;
38
+ const uploadsPlanned = input.uploadsPlanned;
39
+ const storageOriginDefault = storageEnvOrigin ?? sessionSite ?? `https://${input.gateway}`;
40
+ if (!uploadsPlanned) return {
41
+ cdnOrigin: void 0,
42
+ storageOrigin: storageOriginDefault,
43
+ apiKey
44
+ };
45
+ let cdnOrigin;
46
+ let warning;
47
+ if (envCdnOrigin) {
48
+ cdnOrigin = envCdnOrigin;
49
+ if (isLocalOrigin(envCdnOrigin)) warning = `BOS_BUNDLE_CDN_ORIGIN is a local URL (${envCdnOrigin}) — deploying to a local stack, published bundle URLs will not resolve publicly.`;
50
+ } else if (configCdnOrigin) {
51
+ if (isLocalOrigin(configCdnOrigin)) return {
52
+ cdnOrigin,
53
+ storageOrigin: storageOriginDefault,
54
+ apiKey,
55
+ error: `the authored config sets cdn.origin to the local URL ${configCdnOrigin} — deploy bundle origins must be publicly reachable. Set BOS_BUNDLE_CDN_ORIGIN for a local deploy, or fix cdn.origin (inherited via extends).`
56
+ };
57
+ cdnOrigin = configCdnOrigin;
58
+ } else return {
59
+ cdnOrigin,
60
+ storageOrigin: storageOriginDefault,
61
+ apiKey,
62
+ error: "CDN deploy requires a bundle origin — set `cdn.origin` in bos.config.json (children inherit it from the base runtime via extends) or BOS_BUNDLE_CDN_ORIGIN in the environment."
63
+ };
64
+ let storageOrigin;
65
+ if (storageEnvOrigin) {
66
+ storageOrigin = storageEnvOrigin;
67
+ if (isLocalOrigin(storageEnvOrigin) && !warning) warning = `BOS_STORAGE_ORIGIN is a local URL (${storageEnvOrigin}) — uploading to a local stack.`;
68
+ } else if (sessionSite) {
69
+ if (isLocalOrigin(sessionSite)) return {
70
+ cdnOrigin,
71
+ storageOrigin: sessionSite,
72
+ apiKey,
73
+ error: `The CLI session pins uploads to ${sessionSite} — a local site can never receive production bundles. Re-run \`bos login\` against the production site, or set BOS_STORAGE_ORIGIN explicitly.`
74
+ };
75
+ storageOrigin = sessionSite;
76
+ } else storageOrigin = `https://${input.gateway}`;
77
+ if (!apiKey) return {
78
+ cdnOrigin,
79
+ storageOrigin,
80
+ apiKey,
81
+ warning,
82
+ error: "CDN deploy requires bundle-upload credentials — run `bos login --key` and add the printed key to GitHub secrets as BOS_STORAGE_API_KEY (or run `bos login` for interactive deploys)"
83
+ };
84
+ if (input.session?.accountId && input.session.accountId !== input.account) return {
85
+ cdnOrigin,
86
+ storageOrigin,
87
+ apiKey,
88
+ warning,
89
+ error: `The CLI session was created for ${input.session.accountId}, but the configured account is ${input.account}. Re-run bos login under the matching account.`
90
+ };
91
+ return {
92
+ cdnOrigin,
93
+ storageOrigin,
94
+ apiKey,
95
+ warning
96
+ };
97
+ }
98
+ /**
99
+ * Pre-upload probe: the storage origin must actually be the platform API.
100
+ * `/.well-known/mcp.json` is the cheapest unauthenticated platform
101
+ * fingerprint — a random service squatting the port (or a stale session
102
+ * pointing at the wrong server) fails here before megabytes move.
103
+ */
104
+ async function probeStorageOrigin(storageOrigin, fetchImpl = fetch) {
105
+ const probeUrl = `${storageOrigin.replace(/\/$/, "")}/.well-known/mcp.json`;
106
+ let response;
107
+ try {
108
+ response = await fetchImpl(probeUrl, { headers: { accept: "application/json" } });
109
+ } catch (error) {
110
+ return `unreachable (${String(error instanceof Error ? error.message : error)})`;
111
+ }
112
+ if (!response.ok) return `GET /.well-known/mcp.json responded ${response.status}`;
113
+ let body;
114
+ try {
115
+ body = await response.json();
116
+ } catch {
117
+ return "did not return the platform MCP descriptor (non-JSON response)";
118
+ }
119
+ if (!body || typeof body !== "object") return "did not return the platform MCP descriptor";
120
+ }
121
+
122
+ //#endregion
123
+ exports.isLocalOrigin = isLocalOrigin;
124
+ exports.probeStorageOrigin = probeStorageOrigin;
125
+ exports.resolveCdnDeployInputs = resolveCdnDeployInputs;
126
+ //# sourceMappingURL=cdn-deploy.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdn-deploy.cjs","names":[],"sources":["../src/cdn-deploy.ts"],"sourcesContent":["interface SessionCredentialLike {\n apiKey?: string;\n siteUrl?: string;\n accountId?: string | null;\n}\n\nexport interface CdnDeployInputs {\n cdnOrigin: string | undefined;\n storageOrigin: string;\n apiKey: string | undefined;\n warning?: string;\n error?: string;\n}\n\nconst LOCAL_HOSTNAMES = new Set([\"localhost\", \"127.0.0.1\", \"::1\", \"[::1]\", \"0.0.0.0\", \"local\"]);\n\n/** Local/private destinations can never serve production bundles. */\nexport function isLocalOrigin(url: string): boolean {\n try {\n const { hostname, protocol } = new URL(url);\n if (protocol !== \"http:\" && protocol !== \"https:\") return true;\n const host = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n return (\n LOCAL_HOSTNAMES.has(host) ||\n host.endsWith(\".localhost\") ||\n host.endsWith(\".local\") ||\n /^127\\.\\d+\\.\\d+\\.\\d+$/.test(host) ||\n /^10\\.\\d+\\.\\d+\\.\\d+$/.test(host) ||\n /^192\\.168\\.\\d+\\.\\d+$/.test(host) ||\n /^172\\.(1[6-9]|2\\d|3[01])\\.\\d+\\.\\d+$/.test(host) ||\n host.startsWith(\"169.254.\") ||\n (host.includes(\":\") &&\n (host.startsWith(\"fe80:\") || host.startsWith(\"fc\") || host.startsWith(\"fd\")))\n );\n } catch {\n return true;\n }\n}\n\n/**\n * Deploy origin resolution (ADR 0020, as amended): the CDN origin comes from\n * the env or the authored `cdn.origin` (inherited via extends) — a hard\n * requirement when uploads are planned, because the host never serves\n * `/bundles` itself. The upload origin is the env, the `bos login` session's\n * siteUrl, or the runtime's own gateway. A session pinned to a local site is\n * a hard error (the origin can only ever be a squatter's port); an env-pinned\n * local origin is deliberate local testing and only warns. Config-only\n * publishes (`uploadsPlanned: false`) ship the committed config verbatim —\n * no origins are resolved and nothing is required.\n */\nexport function resolveCdnDeployInputs(input: {\n env: Record<string, string | undefined>;\n bosConfig: { cdn?: { origin?: string } } | null;\n session: SessionCredentialLike | null;\n account: string;\n gateway: string;\n uploadsPlanned: boolean;\n}): CdnDeployInputs {\n const envCdnOrigin = input.env.BOS_BUNDLE_CDN_ORIGIN?.replace(/\\/$/, \"\");\n const configCdnOrigin = input.bosConfig?.cdn?.origin?.replace(/\\/$/, \"\");\n const storageEnvOrigin = input.env.BOS_STORAGE_ORIGIN?.replace(/\\/$/, \"\");\n const sessionSite = input.session?.siteUrl?.replace(/\\/$/, \"\");\n const apiKey = input.env.BOS_STORAGE_API_KEY ?? input.session?.apiKey;\n const uploadsPlanned = input.uploadsPlanned;\n\n const storageOriginDefault = storageEnvOrigin ?? sessionSite ?? `https://${input.gateway}`;\n\n if (!uploadsPlanned) {\n return { cdnOrigin: undefined, storageOrigin: storageOriginDefault, apiKey };\n }\n\n let cdnOrigin: string | undefined;\n let warning: string | undefined;\n if (envCdnOrigin) {\n cdnOrigin = envCdnOrigin;\n if (isLocalOrigin(envCdnOrigin)) {\n warning = `BOS_BUNDLE_CDN_ORIGIN is a local URL (${envCdnOrigin}) — deploying to a local stack, published bundle URLs will not resolve publicly.`;\n }\n } else if (configCdnOrigin) {\n if (isLocalOrigin(configCdnOrigin)) {\n return {\n cdnOrigin,\n storageOrigin: storageOriginDefault,\n apiKey,\n error:\n `the authored config sets cdn.origin to the local URL ${configCdnOrigin} — deploy bundle ` +\n \"origins must be publicly reachable. Set BOS_BUNDLE_CDN_ORIGIN for a local deploy, \" +\n \"or fix cdn.origin (inherited via extends).\",\n };\n }\n cdnOrigin = configCdnOrigin;\n } else {\n return {\n cdnOrigin,\n storageOrigin: storageOriginDefault,\n apiKey,\n error:\n \"CDN deploy requires a bundle origin — set `cdn.origin` in bos.config.json \" +\n \"(children inherit it from the base runtime via extends) or BOS_BUNDLE_CDN_ORIGIN \" +\n \"in the environment.\",\n };\n }\n\n let storageOrigin: string;\n if (storageEnvOrigin) {\n storageOrigin = storageEnvOrigin;\n if (isLocalOrigin(storageEnvOrigin) && !warning) {\n warning = `BOS_STORAGE_ORIGIN is a local URL (${storageEnvOrigin}) — uploading to a local stack.`;\n }\n } else if (sessionSite) {\n if (isLocalOrigin(sessionSite)) {\n return {\n cdnOrigin,\n storageOrigin: sessionSite,\n apiKey,\n error:\n `The CLI session pins uploads to ${sessionSite} — a local site can never receive ` +\n \"production bundles. Re-run `bos login` against the production site, or set \" +\n \"BOS_STORAGE_ORIGIN explicitly.\",\n };\n }\n storageOrigin = sessionSite;\n } else {\n storageOrigin = `https://${input.gateway}`;\n }\n\n if (!apiKey) {\n return {\n cdnOrigin,\n storageOrigin,\n apiKey,\n warning,\n error:\n \"CDN deploy requires bundle-upload credentials — run `bos login --key` and add the printed key \" +\n \"to GitHub secrets as BOS_STORAGE_API_KEY (or run `bos login` for interactive deploys)\",\n };\n }\n if (input.session?.accountId && input.session.accountId !== input.account) {\n return {\n cdnOrigin,\n storageOrigin,\n apiKey,\n warning,\n error: `The CLI session was created for ${input.session.accountId}, but the configured account is ${input.account}. Re-run bos login under the matching account.`,\n };\n }\n return { cdnOrigin, storageOrigin, apiKey, warning };\n}\n\n/**\n * Pre-upload probe: the storage origin must actually be the platform API.\n * `/.well-known/mcp.json` is the cheapest unauthenticated platform\n * fingerprint — a random service squatting the port (or a stale session\n * pointing at the wrong server) fails here before megabytes move.\n */\nexport async function probeStorageOrigin(\n storageOrigin: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<string | undefined> {\n const probeUrl = `${storageOrigin.replace(/\\/$/, \"\")}/.well-known/mcp.json`;\n let response: Response;\n try {\n response = await fetchImpl(probeUrl, { headers: { accept: \"application/json\" } });\n } catch (error) {\n return `unreachable (${String(error instanceof Error ? error.message : error)})`;\n }\n if (!response.ok) {\n return `GET /.well-known/mcp.json responded ${response.status}`;\n }\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n return \"did not return the platform MCP descriptor (non-JSON response)\";\n }\n if (!body || typeof body !== \"object\") {\n return \"did not return the platform MCP descriptor\";\n }\n return undefined;\n}\n"],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ //#region src/cdn-deploy.ts
2
+ const LOCAL_HOSTNAMES = /* @__PURE__ */ new Set([
3
+ "localhost",
4
+ "127.0.0.1",
5
+ "::1",
6
+ "[::1]",
7
+ "0.0.0.0",
8
+ "local"
9
+ ]);
10
+ /** Local/private destinations can never serve production bundles. */
11
+ function isLocalOrigin(url) {
12
+ try {
13
+ const { hostname, protocol } = new URL(url);
14
+ if (protocol !== "http:" && protocol !== "https:") return true;
15
+ const host = hostname.toLowerCase().replace(/^\[|\]$/g, "");
16
+ return LOCAL_HOSTNAMES.has(host) || host.endsWith(".localhost") || host.endsWith(".local") || /^127\.\d+\.\d+\.\d+$/.test(host) || /^10\.\d+\.\d+\.\d+$/.test(host) || /^192\.168\.\d+\.\d+$/.test(host) || /^172\.(1[6-9]|2\d|3[01])\.\d+\.\d+$/.test(host) || host.startsWith("169.254.") || host.includes(":") && (host.startsWith("fe80:") || host.startsWith("fc") || host.startsWith("fd"));
17
+ } catch {
18
+ return true;
19
+ }
20
+ }
21
+ /**
22
+ * Deploy origin resolution (ADR 0020, as amended): the CDN origin comes from
23
+ * the env or the authored `cdn.origin` (inherited via extends) — a hard
24
+ * requirement when uploads are planned, because the host never serves
25
+ * `/bundles` itself. The upload origin is the env, the `bos login` session's
26
+ * siteUrl, or the runtime's own gateway. A session pinned to a local site is
27
+ * a hard error (the origin can only ever be a squatter's port); an env-pinned
28
+ * local origin is deliberate local testing and only warns. Config-only
29
+ * publishes (`uploadsPlanned: false`) ship the committed config verbatim —
30
+ * no origins are resolved and nothing is required.
31
+ */
32
+ function resolveCdnDeployInputs(input) {
33
+ const envCdnOrigin = input.env.BOS_BUNDLE_CDN_ORIGIN?.replace(/\/$/, "");
34
+ const configCdnOrigin = input.bosConfig?.cdn?.origin?.replace(/\/$/, "");
35
+ const storageEnvOrigin = input.env.BOS_STORAGE_ORIGIN?.replace(/\/$/, "");
36
+ const sessionSite = input.session?.siteUrl?.replace(/\/$/, "");
37
+ const apiKey = input.env.BOS_STORAGE_API_KEY ?? input.session?.apiKey;
38
+ const uploadsPlanned = input.uploadsPlanned;
39
+ const storageOriginDefault = storageEnvOrigin ?? sessionSite ?? `https://${input.gateway}`;
40
+ if (!uploadsPlanned) return {
41
+ cdnOrigin: void 0,
42
+ storageOrigin: storageOriginDefault,
43
+ apiKey
44
+ };
45
+ let cdnOrigin;
46
+ let warning;
47
+ if (envCdnOrigin) {
48
+ cdnOrigin = envCdnOrigin;
49
+ if (isLocalOrigin(envCdnOrigin)) warning = `BOS_BUNDLE_CDN_ORIGIN is a local URL (${envCdnOrigin}) — deploying to a local stack, published bundle URLs will not resolve publicly.`;
50
+ } else if (configCdnOrigin) {
51
+ if (isLocalOrigin(configCdnOrigin)) return {
52
+ cdnOrigin,
53
+ storageOrigin: storageOriginDefault,
54
+ apiKey,
55
+ error: `the authored config sets cdn.origin to the local URL ${configCdnOrigin} — deploy bundle origins must be publicly reachable. Set BOS_BUNDLE_CDN_ORIGIN for a local deploy, or fix cdn.origin (inherited via extends).`
56
+ };
57
+ cdnOrigin = configCdnOrigin;
58
+ } else return {
59
+ cdnOrigin,
60
+ storageOrigin: storageOriginDefault,
61
+ apiKey,
62
+ error: "CDN deploy requires a bundle origin — set `cdn.origin` in bos.config.json (children inherit it from the base runtime via extends) or BOS_BUNDLE_CDN_ORIGIN in the environment."
63
+ };
64
+ let storageOrigin;
65
+ if (storageEnvOrigin) {
66
+ storageOrigin = storageEnvOrigin;
67
+ if (isLocalOrigin(storageEnvOrigin) && !warning) warning = `BOS_STORAGE_ORIGIN is a local URL (${storageEnvOrigin}) — uploading to a local stack.`;
68
+ } else if (sessionSite) {
69
+ if (isLocalOrigin(sessionSite)) return {
70
+ cdnOrigin,
71
+ storageOrigin: sessionSite,
72
+ apiKey,
73
+ error: `The CLI session pins uploads to ${sessionSite} — a local site can never receive production bundles. Re-run \`bos login\` against the production site, or set BOS_STORAGE_ORIGIN explicitly.`
74
+ };
75
+ storageOrigin = sessionSite;
76
+ } else storageOrigin = `https://${input.gateway}`;
77
+ if (!apiKey) return {
78
+ cdnOrigin,
79
+ storageOrigin,
80
+ apiKey,
81
+ warning,
82
+ error: "CDN deploy requires bundle-upload credentials — run `bos login --key` and add the printed key to GitHub secrets as BOS_STORAGE_API_KEY (or run `bos login` for interactive deploys)"
83
+ };
84
+ if (input.session?.accountId && input.session.accountId !== input.account) return {
85
+ cdnOrigin,
86
+ storageOrigin,
87
+ apiKey,
88
+ warning,
89
+ error: `The CLI session was created for ${input.session.accountId}, but the configured account is ${input.account}. Re-run bos login under the matching account.`
90
+ };
91
+ return {
92
+ cdnOrigin,
93
+ storageOrigin,
94
+ apiKey,
95
+ warning
96
+ };
97
+ }
98
+ /**
99
+ * Pre-upload probe: the storage origin must actually be the platform API.
100
+ * `/.well-known/mcp.json` is the cheapest unauthenticated platform
101
+ * fingerprint — a random service squatting the port (or a stale session
102
+ * pointing at the wrong server) fails here before megabytes move.
103
+ */
104
+ async function probeStorageOrigin(storageOrigin, fetchImpl = fetch) {
105
+ const probeUrl = `${storageOrigin.replace(/\/$/, "")}/.well-known/mcp.json`;
106
+ let response;
107
+ try {
108
+ response = await fetchImpl(probeUrl, { headers: { accept: "application/json" } });
109
+ } catch (error) {
110
+ return `unreachable (${String(error instanceof Error ? error.message : error)})`;
111
+ }
112
+ if (!response.ok) return `GET /.well-known/mcp.json responded ${response.status}`;
113
+ let body;
114
+ try {
115
+ body = await response.json();
116
+ } catch {
117
+ return "did not return the platform MCP descriptor (non-JSON response)";
118
+ }
119
+ if (!body || typeof body !== "object") return "did not return the platform MCP descriptor";
120
+ }
121
+
122
+ //#endregion
123
+ export { isLocalOrigin, probeStorageOrigin, resolveCdnDeployInputs };
124
+ //# sourceMappingURL=cdn-deploy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdn-deploy.mjs","names":[],"sources":["../src/cdn-deploy.ts"],"sourcesContent":["interface SessionCredentialLike {\n apiKey?: string;\n siteUrl?: string;\n accountId?: string | null;\n}\n\nexport interface CdnDeployInputs {\n cdnOrigin: string | undefined;\n storageOrigin: string;\n apiKey: string | undefined;\n warning?: string;\n error?: string;\n}\n\nconst LOCAL_HOSTNAMES = new Set([\"localhost\", \"127.0.0.1\", \"::1\", \"[::1]\", \"0.0.0.0\", \"local\"]);\n\n/** Local/private destinations can never serve production bundles. */\nexport function isLocalOrigin(url: string): boolean {\n try {\n const { hostname, protocol } = new URL(url);\n if (protocol !== \"http:\" && protocol !== \"https:\") return true;\n const host = hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n return (\n LOCAL_HOSTNAMES.has(host) ||\n host.endsWith(\".localhost\") ||\n host.endsWith(\".local\") ||\n /^127\\.\\d+\\.\\d+\\.\\d+$/.test(host) ||\n /^10\\.\\d+\\.\\d+\\.\\d+$/.test(host) ||\n /^192\\.168\\.\\d+\\.\\d+$/.test(host) ||\n /^172\\.(1[6-9]|2\\d|3[01])\\.\\d+\\.\\d+$/.test(host) ||\n host.startsWith(\"169.254.\") ||\n (host.includes(\":\") &&\n (host.startsWith(\"fe80:\") || host.startsWith(\"fc\") || host.startsWith(\"fd\")))\n );\n } catch {\n return true;\n }\n}\n\n/**\n * Deploy origin resolution (ADR 0020, as amended): the CDN origin comes from\n * the env or the authored `cdn.origin` (inherited via extends) — a hard\n * requirement when uploads are planned, because the host never serves\n * `/bundles` itself. The upload origin is the env, the `bos login` session's\n * siteUrl, or the runtime's own gateway. A session pinned to a local site is\n * a hard error (the origin can only ever be a squatter's port); an env-pinned\n * local origin is deliberate local testing and only warns. Config-only\n * publishes (`uploadsPlanned: false`) ship the committed config verbatim —\n * no origins are resolved and nothing is required.\n */\nexport function resolveCdnDeployInputs(input: {\n env: Record<string, string | undefined>;\n bosConfig: { cdn?: { origin?: string } } | null;\n session: SessionCredentialLike | null;\n account: string;\n gateway: string;\n uploadsPlanned: boolean;\n}): CdnDeployInputs {\n const envCdnOrigin = input.env.BOS_BUNDLE_CDN_ORIGIN?.replace(/\\/$/, \"\");\n const configCdnOrigin = input.bosConfig?.cdn?.origin?.replace(/\\/$/, \"\");\n const storageEnvOrigin = input.env.BOS_STORAGE_ORIGIN?.replace(/\\/$/, \"\");\n const sessionSite = input.session?.siteUrl?.replace(/\\/$/, \"\");\n const apiKey = input.env.BOS_STORAGE_API_KEY ?? input.session?.apiKey;\n const uploadsPlanned = input.uploadsPlanned;\n\n const storageOriginDefault = storageEnvOrigin ?? sessionSite ?? `https://${input.gateway}`;\n\n if (!uploadsPlanned) {\n return { cdnOrigin: undefined, storageOrigin: storageOriginDefault, apiKey };\n }\n\n let cdnOrigin: string | undefined;\n let warning: string | undefined;\n if (envCdnOrigin) {\n cdnOrigin = envCdnOrigin;\n if (isLocalOrigin(envCdnOrigin)) {\n warning = `BOS_BUNDLE_CDN_ORIGIN is a local URL (${envCdnOrigin}) — deploying to a local stack, published bundle URLs will not resolve publicly.`;\n }\n } else if (configCdnOrigin) {\n if (isLocalOrigin(configCdnOrigin)) {\n return {\n cdnOrigin,\n storageOrigin: storageOriginDefault,\n apiKey,\n error:\n `the authored config sets cdn.origin to the local URL ${configCdnOrigin} — deploy bundle ` +\n \"origins must be publicly reachable. Set BOS_BUNDLE_CDN_ORIGIN for a local deploy, \" +\n \"or fix cdn.origin (inherited via extends).\",\n };\n }\n cdnOrigin = configCdnOrigin;\n } else {\n return {\n cdnOrigin,\n storageOrigin: storageOriginDefault,\n apiKey,\n error:\n \"CDN deploy requires a bundle origin — set `cdn.origin` in bos.config.json \" +\n \"(children inherit it from the base runtime via extends) or BOS_BUNDLE_CDN_ORIGIN \" +\n \"in the environment.\",\n };\n }\n\n let storageOrigin: string;\n if (storageEnvOrigin) {\n storageOrigin = storageEnvOrigin;\n if (isLocalOrigin(storageEnvOrigin) && !warning) {\n warning = `BOS_STORAGE_ORIGIN is a local URL (${storageEnvOrigin}) — uploading to a local stack.`;\n }\n } else if (sessionSite) {\n if (isLocalOrigin(sessionSite)) {\n return {\n cdnOrigin,\n storageOrigin: sessionSite,\n apiKey,\n error:\n `The CLI session pins uploads to ${sessionSite} — a local site can never receive ` +\n \"production bundles. Re-run `bos login` against the production site, or set \" +\n \"BOS_STORAGE_ORIGIN explicitly.\",\n };\n }\n storageOrigin = sessionSite;\n } else {\n storageOrigin = `https://${input.gateway}`;\n }\n\n if (!apiKey) {\n return {\n cdnOrigin,\n storageOrigin,\n apiKey,\n warning,\n error:\n \"CDN deploy requires bundle-upload credentials — run `bos login --key` and add the printed key \" +\n \"to GitHub secrets as BOS_STORAGE_API_KEY (or run `bos login` for interactive deploys)\",\n };\n }\n if (input.session?.accountId && input.session.accountId !== input.account) {\n return {\n cdnOrigin,\n storageOrigin,\n apiKey,\n warning,\n error: `The CLI session was created for ${input.session.accountId}, but the configured account is ${input.account}. Re-run bos login under the matching account.`,\n };\n }\n return { cdnOrigin, storageOrigin, apiKey, warning };\n}\n\n/**\n * Pre-upload probe: the storage origin must actually be the platform API.\n * `/.well-known/mcp.json` is the cheapest unauthenticated platform\n * fingerprint — a random service squatting the port (or a stale session\n * pointing at the wrong server) fails here before megabytes move.\n */\nexport async function probeStorageOrigin(\n storageOrigin: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<string | undefined> {\n const probeUrl = `${storageOrigin.replace(/\\/$/, \"\")}/.well-known/mcp.json`;\n let response: Response;\n try {\n response = await fetchImpl(probeUrl, { headers: { accept: \"application/json\" } });\n } catch (error) {\n return `unreachable (${String(error instanceof Error ? error.message : error)})`;\n }\n if (!response.ok) {\n return `GET /.well-known/mcp.json responded ${response.status}`;\n }\n let body: unknown;\n try {\n body = await response.json();\n } catch {\n return \"did not return the platform MCP descriptor (non-JSON response)\";\n }\n if (!body || typeof body !== \"object\") {\n return \"did not return the platform MCP descriptor\";\n }\n return undefined;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const require_db = require('../db.cjs');
1
+ const require_core = require('../db/core.cjs');
2
2
  let node_fs = require("node:fs");
3
3
  let node_path = require("node:path");
4
4
  let node_crypto = require("node:crypto");
@@ -9,7 +9,8 @@ function hashFile(raw) {
9
9
  }
10
10
  function readLocalMigrations(workspaceDir) {
11
11
  const migrationsDir = (0, node_path.resolve)(workspaceDir, "src/db/migrations");
12
- const journalPath = (0, node_path.join)((0, node_path.join)(migrationsDir, "meta"), "_journal.json");
12
+ const metaDir = (0, node_path.join)(migrationsDir, "meta");
13
+ const journalPath = (0, node_path.join)(metaDir, "_journal.json");
13
14
  if (!(0, node_fs.existsSync)(journalPath)) return [];
14
15
  return JSON.parse((0, node_fs.readFileSync)(journalPath, "utf8")).entries.map((entry) => {
15
16
  const sqlPath = (0, node_path.join)(migrationsDir, `${entry.tag}.sql`);
@@ -27,20 +28,19 @@ function readLocalMigrations(workspaceDir) {
27
28
  };
28
29
  });
29
30
  }
30
- async function diagnosePlugin(info) {
31
+ async function diagnosePlugin(binding) {
31
32
  const { Pool } = await import("pg");
32
- const slug = require_db.pluginMigrationSlug(info.key);
33
- const storage = require_db.getMigrationStorage(slug);
34
- const journalTable = storage.table;
35
- const journalSchema = storage.schema;
33
+ const slug = binding.identity.slug;
34
+ const journalTable = binding.identity.journal.table;
35
+ const journalSchema = binding.identity.journal.schema;
36
36
  const journalRef = `"${journalSchema}"."${journalTable}"`;
37
- const localMigrations = info.workspaceDir ? readLocalMigrations(info.workspaceDir) : [];
38
- const expectedTables = require_db.extractExpectedTables(localMigrations);
37
+ const localMigrations = binding.identity.workspaceDir ? readLocalMigrations(binding.identity.workspaceDir) : [];
38
+ const expectedTables = require_core.extractExpectedTables(localMigrations);
39
39
  const localHashes = localMigrations.map((m) => m.hash).filter(Boolean);
40
40
  const migrationHashes = localHashes;
41
41
  const pool = new Pool({
42
- connectionString: info.databaseUrl,
43
- ssl: info.databaseUrl.includes("localhost") || info.databaseUrl.includes("127.0.0.1") ? false : { rejectUnauthorized: false },
42
+ connectionString: binding.url,
43
+ ssl: binding.url.includes("localhost") || binding.url.includes("127.0.0.1") ? false : { rejectUnauthorized: false },
44
44
  max: 1,
45
45
  connectionTimeoutMillis: 1e4
46
46
  });
@@ -70,15 +70,15 @@ async function diagnosePlugin(info) {
70
70
  else if (missingTables.length === 0) diagnosis = "healthy";
71
71
  else if (missingTables.length === expectedTables.length) diagnosis = "drift-safe-repair";
72
72
  else diagnosis = "drift-manual";
73
- const masked = info.databaseUrl.replace(/\/\/[^:]+:[^@]+@/, "//***:***@");
73
+ const masked = binding.url.replace(/\/\/[^:]+:[^@]+@/, "//***:***@");
74
74
  return {
75
- plugin: info.key,
75
+ plugin: binding.key,
76
76
  slug,
77
77
  journalTable,
78
78
  journalSchema,
79
- dbSecret: info.databaseSecret,
79
+ dbSecret: binding.identity.secretName,
80
80
  dbUrl: masked,
81
- workspaceDir: info.workspaceDir,
81
+ workspaceDir: binding.identity.workspaceDir,
82
82
  localMigrationCount: localMigrations.length,
83
83
  appliedHashCount,
84
84
  expectedTables,
@@ -88,13 +88,13 @@ async function diagnosePlugin(info) {
88
88
  };
89
89
  } catch (error) {
90
90
  return {
91
- plugin: info.key,
91
+ plugin: binding.key,
92
92
  slug,
93
93
  journalTable,
94
94
  journalSchema,
95
- dbSecret: info.databaseSecret,
96
- dbUrl: info.databaseUrl.replace(/\/\/[^:]+:[^@]+@/, "//***:***@"),
97
- workspaceDir: info.workspaceDir,
95
+ dbSecret: binding.identity.secretName,
96
+ dbUrl: binding.url.replace(/\/\/[^:]+:[^@]+@/, "//***:***@"),
97
+ workspaceDir: binding.identity.workspaceDir,
98
98
  localMigrationCount: localMigrations.length,
99
99
  appliedHashCount: 0,
100
100
  expectedTables,
@@ -1 +1 @@
1
- {"version":3,"file":"db-doctor.cjs","names":["pluginMigrationSlug","getMigrationStorage","extractExpectedTables"],"sources":["../../src/cli/db-doctor.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { extractExpectedTables, getMigrationStorage, pluginMigrationSlug } from \"../db\";\nimport type { PluginDbInfo } from \"./db-studio\";\n\nexport interface DoctorReport {\n plugin: string;\n slug: string;\n journalTable: string;\n journalSchema: string;\n dbSecret: string;\n dbUrl: string;\n workspaceDir: string | undefined;\n localMigrationCount: number;\n appliedHashCount: number;\n expectedTables: string[];\n missingTables: string[];\n migrationHashes: string[];\n diagnosis: string;\n error?: string;\n}\n\nfunction hashFile(raw: string): string {\n return createHash(\"sha256\").update(raw).digest(\"hex\");\n}\n\ninterface LocalMigration {\n tag: string;\n hash: string;\n sql: string[];\n}\n\nfunction readLocalMigrations(workspaceDir: string): LocalMigration[] {\n const migrationsDir = resolve(workspaceDir, \"src/db/migrations\");\n const metaDir = join(migrationsDir, \"meta\");\n const journalPath = join(metaDir, \"_journal.json\");\n if (!existsSync(journalPath)) return [];\n\n const journal = JSON.parse(readFileSync(journalPath, \"utf8\")) as {\n entries: { idx: number; tag: string }[];\n };\n\n return journal.entries.map((entry) => {\n const sqlPath = join(migrationsDir, `${entry.tag}.sql`);\n if (!existsSync(sqlPath)) {\n return { tag: entry.tag, hash: \"\", sql: [] };\n }\n const raw = readFileSync(sqlPath, \"utf8\");\n const sql = raw.split(\"--> statement-breakpoint\").map((s) => s.trim());\n return { tag: entry.tag, hash: hashFile(raw), sql };\n });\n}\n\nexport async function diagnosePlugin(info: PluginDbInfo): Promise<DoctorReport> {\n const { Pool } = await import(\"pg\");\n\n const slug = pluginMigrationSlug(info.key);\n const storage = getMigrationStorage(slug);\n const journalTable = storage.table;\n const journalSchema = storage.schema;\n const journalRef = `\"${journalSchema}\".\"${journalTable}\"`;\n\n const localMigrations = info.workspaceDir ? readLocalMigrations(info.workspaceDir) : [];\n\n const expectedTables = extractExpectedTables(localMigrations);\n const localHashes = localMigrations.map((m) => m.hash).filter(Boolean);\n const migrationHashes = localHashes;\n\n const pool = new Pool({\n connectionString: info.databaseUrl,\n ssl:\n info.databaseUrl.includes(\"localhost\") || info.databaseUrl.includes(\"127.0.0.1\")\n ? false\n : { rejectUnauthorized: false },\n max: 1,\n connectionTimeoutMillis: 10_000,\n });\n\n try {\n const journalExists = await pool.query(`\n SELECT EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = '${journalSchema}' AND table_name = '${journalTable}'\n ) AS exists\n `);\n\n let appliedHashCount = 0;\n if (journalExists.rows[0]?.exists) {\n const result = await pool.query(`SELECT hash FROM ${journalRef}`);\n appliedHashCount = result.rows.length;\n }\n\n let missingTables: string[] = [];\n if (expectedTables.length > 0) {\n const tableResult = await pool.query(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = 'public'\n AND table_name = ANY($1)\n `,\n [expectedTables],\n );\n const existing = new Set(tableResult.rows.map((r: any) => r.table_name));\n missingTables = expectedTables.filter((t) => !existing.has(t));\n }\n\n let diagnosis: string;\n if (localMigrations.length === 0) {\n diagnosis = \"no-local-migrations\";\n } else if (appliedHashCount === 0 && missingTables.length === 0 && localHashes.length > 0) {\n // Journal is empty but all expected public tables exist.\n diagnosis = \"untracked-existing-schema\";\n } else if (appliedHashCount === 0 && localHashes.length > 0) {\n diagnosis = \"unapplied\";\n } else if (missingTables.length === 0) {\n diagnosis = \"healthy\";\n } else if (missingTables.length === expectedTables.length) {\n diagnosis = \"drift-safe-repair\";\n } else {\n diagnosis = \"drift-manual\";\n }\n\n const masked = info.databaseUrl.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\");\n\n return {\n plugin: info.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: info.databaseSecret,\n dbUrl: masked,\n workspaceDir: info.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount,\n expectedTables,\n missingTables,\n migrationHashes,\n diagnosis,\n };\n } catch (error) {\n return {\n plugin: info.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: info.databaseSecret,\n dbUrl: info.databaseUrl.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\"),\n workspaceDir: info.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount: 0,\n expectedTables,\n missingTables: [],\n migrationHashes: [],\n diagnosis: \"error\",\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n await pool.end().catch(() => {});\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"db-doctor.cjs","names":["createHash","resolve","join","existsSync","readFileSync","extractExpectedTables"],"sources":["../../src/cli/db-doctor.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { DatabaseBinding } from \"../db\";\nimport { extractExpectedTables } from \"../db\";\n\nexport interface DoctorReport {\n plugin: string;\n slug: string;\n journalTable: string;\n journalSchema: string;\n dbSecret: string;\n dbUrl: string;\n workspaceDir: string | undefined;\n localMigrationCount: number;\n appliedHashCount: number;\n expectedTables: string[];\n missingTables: string[];\n migrationHashes: string[];\n diagnosis: string;\n error?: string;\n}\n\nfunction hashFile(raw: string): string {\n return createHash(\"sha256\").update(raw).digest(\"hex\");\n}\n\ninterface LocalMigration {\n tag: string;\n hash: string;\n sql: string[];\n}\n\nfunction readLocalMigrations(workspaceDir: string): LocalMigration[] {\n const migrationsDir = resolve(workspaceDir, \"src/db/migrations\");\n const metaDir = join(migrationsDir, \"meta\");\n const journalPath = join(metaDir, \"_journal.json\");\n if (!existsSync(journalPath)) return [];\n\n const journal = JSON.parse(readFileSync(journalPath, \"utf8\")) as {\n entries: { idx: number; tag: string }[];\n };\n\n return journal.entries.map((entry) => {\n const sqlPath = join(migrationsDir, `${entry.tag}.sql`);\n if (!existsSync(sqlPath)) {\n return { tag: entry.tag, hash: \"\", sql: [] };\n }\n const raw = readFileSync(sqlPath, \"utf8\");\n const sql = raw.split(\"--> statement-breakpoint\").map((s) => s.trim());\n return { tag: entry.tag, hash: hashFile(raw), sql };\n });\n}\n\nexport async function diagnosePlugin(binding: DatabaseBinding): Promise<DoctorReport> {\n const { Pool } = await import(\"pg\");\n\n const slug = binding.identity.slug;\n const journalTable = binding.identity.journal.table;\n const journalSchema = binding.identity.journal.schema;\n const journalRef = `\"${journalSchema}\".\"${journalTable}\"`;\n\n const localMigrations = binding.identity.workspaceDir\n ? readLocalMigrations(binding.identity.workspaceDir)\n : [];\n\n const expectedTables = extractExpectedTables(localMigrations);\n const localHashes = localMigrations.map((m) => m.hash).filter(Boolean);\n const migrationHashes = localHashes;\n\n const pool = new Pool({\n connectionString: binding.url,\n ssl:\n binding.url.includes(\"localhost\") || binding.url.includes(\"127.0.0.1\")\n ? false\n : { rejectUnauthorized: false },\n max: 1,\n connectionTimeoutMillis: 10_000,\n });\n\n try {\n const journalExists = await pool.query(`\n SELECT EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = '${journalSchema}' AND table_name = '${journalTable}'\n ) AS exists\n `);\n\n let appliedHashCount = 0;\n if (journalExists.rows[0]?.exists) {\n const result = await pool.query(`SELECT hash FROM ${journalRef}`);\n appliedHashCount = result.rows.length;\n }\n\n let missingTables: string[] = [];\n if (expectedTables.length > 0) {\n const tableResult = await pool.query(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = 'public'\n AND table_name = ANY($1)\n `,\n [expectedTables],\n );\n const existing = new Set(tableResult.rows.map((r: any) => r.table_name));\n missingTables = expectedTables.filter((t) => !existing.has(t));\n }\n\n let diagnosis: string;\n if (localMigrations.length === 0) {\n diagnosis = \"no-local-migrations\";\n } else if (appliedHashCount === 0 && missingTables.length === 0 && localHashes.length > 0) {\n // Journal is empty but all expected public tables exist.\n diagnosis = \"untracked-existing-schema\";\n } else if (appliedHashCount === 0 && localHashes.length > 0) {\n diagnosis = \"unapplied\";\n } else if (missingTables.length === 0) {\n diagnosis = \"healthy\";\n } else if (missingTables.length === expectedTables.length) {\n diagnosis = \"drift-safe-repair\";\n } else {\n diagnosis = \"drift-manual\";\n }\n\n const masked = binding.url.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\");\n\n return {\n plugin: binding.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: binding.identity.secretName,\n dbUrl: masked,\n workspaceDir: binding.identity.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount,\n expectedTables,\n missingTables,\n migrationHashes,\n diagnosis,\n };\n } catch (error) {\n return {\n plugin: binding.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: binding.identity.secretName,\n dbUrl: binding.url.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\"),\n workspaceDir: binding.identity.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount: 0,\n expectedTables,\n missingTables: [],\n migrationHashes: [],\n diagnosis: \"error\",\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n await pool.end().catch(() => {});\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { extractExpectedTables, getMigrationStorage, pluginMigrationSlug } from "../db.mjs";
1
+ import { extractExpectedTables } from "../db/core.mjs";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import { join, resolve } from "node:path";
4
4
  import { createHash } from "node:crypto";
@@ -9,7 +9,8 @@ function hashFile(raw) {
9
9
  }
10
10
  function readLocalMigrations(workspaceDir) {
11
11
  const migrationsDir = resolve(workspaceDir, "src/db/migrations");
12
- const journalPath = join(join(migrationsDir, "meta"), "_journal.json");
12
+ const metaDir = join(migrationsDir, "meta");
13
+ const journalPath = join(metaDir, "_journal.json");
13
14
  if (!existsSync(journalPath)) return [];
14
15
  return JSON.parse(readFileSync(journalPath, "utf8")).entries.map((entry) => {
15
16
  const sqlPath = join(migrationsDir, `${entry.tag}.sql`);
@@ -27,20 +28,19 @@ function readLocalMigrations(workspaceDir) {
27
28
  };
28
29
  });
29
30
  }
30
- async function diagnosePlugin(info) {
31
+ async function diagnosePlugin(binding) {
31
32
  const { Pool } = await import("pg");
32
- const slug = pluginMigrationSlug(info.key);
33
- const storage = getMigrationStorage(slug);
34
- const journalTable = storage.table;
35
- const journalSchema = storage.schema;
33
+ const slug = binding.identity.slug;
34
+ const journalTable = binding.identity.journal.table;
35
+ const journalSchema = binding.identity.journal.schema;
36
36
  const journalRef = `"${journalSchema}"."${journalTable}"`;
37
- const localMigrations = info.workspaceDir ? readLocalMigrations(info.workspaceDir) : [];
37
+ const localMigrations = binding.identity.workspaceDir ? readLocalMigrations(binding.identity.workspaceDir) : [];
38
38
  const expectedTables = extractExpectedTables(localMigrations);
39
39
  const localHashes = localMigrations.map((m) => m.hash).filter(Boolean);
40
40
  const migrationHashes = localHashes;
41
41
  const pool = new Pool({
42
- connectionString: info.databaseUrl,
43
- ssl: info.databaseUrl.includes("localhost") || info.databaseUrl.includes("127.0.0.1") ? false : { rejectUnauthorized: false },
42
+ connectionString: binding.url,
43
+ ssl: binding.url.includes("localhost") || binding.url.includes("127.0.0.1") ? false : { rejectUnauthorized: false },
44
44
  max: 1,
45
45
  connectionTimeoutMillis: 1e4
46
46
  });
@@ -70,15 +70,15 @@ async function diagnosePlugin(info) {
70
70
  else if (missingTables.length === 0) diagnosis = "healthy";
71
71
  else if (missingTables.length === expectedTables.length) diagnosis = "drift-safe-repair";
72
72
  else diagnosis = "drift-manual";
73
- const masked = info.databaseUrl.replace(/\/\/[^:]+:[^@]+@/, "//***:***@");
73
+ const masked = binding.url.replace(/\/\/[^:]+:[^@]+@/, "//***:***@");
74
74
  return {
75
- plugin: info.key,
75
+ plugin: binding.key,
76
76
  slug,
77
77
  journalTable,
78
78
  journalSchema,
79
- dbSecret: info.databaseSecret,
79
+ dbSecret: binding.identity.secretName,
80
80
  dbUrl: masked,
81
- workspaceDir: info.workspaceDir,
81
+ workspaceDir: binding.identity.workspaceDir,
82
82
  localMigrationCount: localMigrations.length,
83
83
  appliedHashCount,
84
84
  expectedTables,
@@ -88,13 +88,13 @@ async function diagnosePlugin(info) {
88
88
  };
89
89
  } catch (error) {
90
90
  return {
91
- plugin: info.key,
91
+ plugin: binding.key,
92
92
  slug,
93
93
  journalTable,
94
94
  journalSchema,
95
- dbSecret: info.databaseSecret,
96
- dbUrl: info.databaseUrl.replace(/\/\/[^:]+:[^@]+@/, "//***:***@"),
97
- workspaceDir: info.workspaceDir,
95
+ dbSecret: binding.identity.secretName,
96
+ dbUrl: binding.url.replace(/\/\/[^:]+:[^@]+@/, "//***:***@"),
97
+ workspaceDir: binding.identity.workspaceDir,
98
98
  localMigrationCount: localMigrations.length,
99
99
  appliedHashCount: 0,
100
100
  expectedTables,
@@ -1 +1 @@
1
- {"version":3,"file":"db-doctor.mjs","names":[],"sources":["../../src/cli/db-doctor.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport { extractExpectedTables, getMigrationStorage, pluginMigrationSlug } from \"../db\";\nimport type { PluginDbInfo } from \"./db-studio\";\n\nexport interface DoctorReport {\n plugin: string;\n slug: string;\n journalTable: string;\n journalSchema: string;\n dbSecret: string;\n dbUrl: string;\n workspaceDir: string | undefined;\n localMigrationCount: number;\n appliedHashCount: number;\n expectedTables: string[];\n missingTables: string[];\n migrationHashes: string[];\n diagnosis: string;\n error?: string;\n}\n\nfunction hashFile(raw: string): string {\n return createHash(\"sha256\").update(raw).digest(\"hex\");\n}\n\ninterface LocalMigration {\n tag: string;\n hash: string;\n sql: string[];\n}\n\nfunction readLocalMigrations(workspaceDir: string): LocalMigration[] {\n const migrationsDir = resolve(workspaceDir, \"src/db/migrations\");\n const metaDir = join(migrationsDir, \"meta\");\n const journalPath = join(metaDir, \"_journal.json\");\n if (!existsSync(journalPath)) return [];\n\n const journal = JSON.parse(readFileSync(journalPath, \"utf8\")) as {\n entries: { idx: number; tag: string }[];\n };\n\n return journal.entries.map((entry) => {\n const sqlPath = join(migrationsDir, `${entry.tag}.sql`);\n if (!existsSync(sqlPath)) {\n return { tag: entry.tag, hash: \"\", sql: [] };\n }\n const raw = readFileSync(sqlPath, \"utf8\");\n const sql = raw.split(\"--> statement-breakpoint\").map((s) => s.trim());\n return { tag: entry.tag, hash: hashFile(raw), sql };\n });\n}\n\nexport async function diagnosePlugin(info: PluginDbInfo): Promise<DoctorReport> {\n const { Pool } = await import(\"pg\");\n\n const slug = pluginMigrationSlug(info.key);\n const storage = getMigrationStorage(slug);\n const journalTable = storage.table;\n const journalSchema = storage.schema;\n const journalRef = `\"${journalSchema}\".\"${journalTable}\"`;\n\n const localMigrations = info.workspaceDir ? readLocalMigrations(info.workspaceDir) : [];\n\n const expectedTables = extractExpectedTables(localMigrations);\n const localHashes = localMigrations.map((m) => m.hash).filter(Boolean);\n const migrationHashes = localHashes;\n\n const pool = new Pool({\n connectionString: info.databaseUrl,\n ssl:\n info.databaseUrl.includes(\"localhost\") || info.databaseUrl.includes(\"127.0.0.1\")\n ? false\n : { rejectUnauthorized: false },\n max: 1,\n connectionTimeoutMillis: 10_000,\n });\n\n try {\n const journalExists = await pool.query(`\n SELECT EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = '${journalSchema}' AND table_name = '${journalTable}'\n ) AS exists\n `);\n\n let appliedHashCount = 0;\n if (journalExists.rows[0]?.exists) {\n const result = await pool.query(`SELECT hash FROM ${journalRef}`);\n appliedHashCount = result.rows.length;\n }\n\n let missingTables: string[] = [];\n if (expectedTables.length > 0) {\n const tableResult = await pool.query(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = 'public'\n AND table_name = ANY($1)\n `,\n [expectedTables],\n );\n const existing = new Set(tableResult.rows.map((r: any) => r.table_name));\n missingTables = expectedTables.filter((t) => !existing.has(t));\n }\n\n let diagnosis: string;\n if (localMigrations.length === 0) {\n diagnosis = \"no-local-migrations\";\n } else if (appliedHashCount === 0 && missingTables.length === 0 && localHashes.length > 0) {\n // Journal is empty but all expected public tables exist.\n diagnosis = \"untracked-existing-schema\";\n } else if (appliedHashCount === 0 && localHashes.length > 0) {\n diagnosis = \"unapplied\";\n } else if (missingTables.length === 0) {\n diagnosis = \"healthy\";\n } else if (missingTables.length === expectedTables.length) {\n diagnosis = \"drift-safe-repair\";\n } else {\n diagnosis = \"drift-manual\";\n }\n\n const masked = info.databaseUrl.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\");\n\n return {\n plugin: info.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: info.databaseSecret,\n dbUrl: masked,\n workspaceDir: info.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount,\n expectedTables,\n missingTables,\n migrationHashes,\n diagnosis,\n };\n } catch (error) {\n return {\n plugin: info.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: info.databaseSecret,\n dbUrl: info.databaseUrl.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\"),\n workspaceDir: info.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount: 0,\n expectedTables,\n missingTables: [],\n migrationHashes: [],\n diagnosis: \"error\",\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n await pool.end().catch(() => {});\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"db-doctor.mjs","names":[],"sources":["../../src/cli/db-doctor.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { DatabaseBinding } from \"../db\";\nimport { extractExpectedTables } from \"../db\";\n\nexport interface DoctorReport {\n plugin: string;\n slug: string;\n journalTable: string;\n journalSchema: string;\n dbSecret: string;\n dbUrl: string;\n workspaceDir: string | undefined;\n localMigrationCount: number;\n appliedHashCount: number;\n expectedTables: string[];\n missingTables: string[];\n migrationHashes: string[];\n diagnosis: string;\n error?: string;\n}\n\nfunction hashFile(raw: string): string {\n return createHash(\"sha256\").update(raw).digest(\"hex\");\n}\n\ninterface LocalMigration {\n tag: string;\n hash: string;\n sql: string[];\n}\n\nfunction readLocalMigrations(workspaceDir: string): LocalMigration[] {\n const migrationsDir = resolve(workspaceDir, \"src/db/migrations\");\n const metaDir = join(migrationsDir, \"meta\");\n const journalPath = join(metaDir, \"_journal.json\");\n if (!existsSync(journalPath)) return [];\n\n const journal = JSON.parse(readFileSync(journalPath, \"utf8\")) as {\n entries: { idx: number; tag: string }[];\n };\n\n return journal.entries.map((entry) => {\n const sqlPath = join(migrationsDir, `${entry.tag}.sql`);\n if (!existsSync(sqlPath)) {\n return { tag: entry.tag, hash: \"\", sql: [] };\n }\n const raw = readFileSync(sqlPath, \"utf8\");\n const sql = raw.split(\"--> statement-breakpoint\").map((s) => s.trim());\n return { tag: entry.tag, hash: hashFile(raw), sql };\n });\n}\n\nexport async function diagnosePlugin(binding: DatabaseBinding): Promise<DoctorReport> {\n const { Pool } = await import(\"pg\");\n\n const slug = binding.identity.slug;\n const journalTable = binding.identity.journal.table;\n const journalSchema = binding.identity.journal.schema;\n const journalRef = `\"${journalSchema}\".\"${journalTable}\"`;\n\n const localMigrations = binding.identity.workspaceDir\n ? readLocalMigrations(binding.identity.workspaceDir)\n : [];\n\n const expectedTables = extractExpectedTables(localMigrations);\n const localHashes = localMigrations.map((m) => m.hash).filter(Boolean);\n const migrationHashes = localHashes;\n\n const pool = new Pool({\n connectionString: binding.url,\n ssl:\n binding.url.includes(\"localhost\") || binding.url.includes(\"127.0.0.1\")\n ? false\n : { rejectUnauthorized: false },\n max: 1,\n connectionTimeoutMillis: 10_000,\n });\n\n try {\n const journalExists = await pool.query(`\n SELECT EXISTS (\n SELECT 1 FROM information_schema.tables\n WHERE table_schema = '${journalSchema}' AND table_name = '${journalTable}'\n ) AS exists\n `);\n\n let appliedHashCount = 0;\n if (journalExists.rows[0]?.exists) {\n const result = await pool.query(`SELECT hash FROM ${journalRef}`);\n appliedHashCount = result.rows.length;\n }\n\n let missingTables: string[] = [];\n if (expectedTables.length > 0) {\n const tableResult = await pool.query(\n `\n SELECT table_name FROM information_schema.tables\n WHERE table_schema = 'public'\n AND table_name = ANY($1)\n `,\n [expectedTables],\n );\n const existing = new Set(tableResult.rows.map((r: any) => r.table_name));\n missingTables = expectedTables.filter((t) => !existing.has(t));\n }\n\n let diagnosis: string;\n if (localMigrations.length === 0) {\n diagnosis = \"no-local-migrations\";\n } else if (appliedHashCount === 0 && missingTables.length === 0 && localHashes.length > 0) {\n // Journal is empty but all expected public tables exist.\n diagnosis = \"untracked-existing-schema\";\n } else if (appliedHashCount === 0 && localHashes.length > 0) {\n diagnosis = \"unapplied\";\n } else if (missingTables.length === 0) {\n diagnosis = \"healthy\";\n } else if (missingTables.length === expectedTables.length) {\n diagnosis = \"drift-safe-repair\";\n } else {\n diagnosis = \"drift-manual\";\n }\n\n const masked = binding.url.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\");\n\n return {\n plugin: binding.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: binding.identity.secretName,\n dbUrl: masked,\n workspaceDir: binding.identity.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount,\n expectedTables,\n missingTables,\n migrationHashes,\n diagnosis,\n };\n } catch (error) {\n return {\n plugin: binding.key,\n slug,\n journalTable,\n journalSchema,\n dbSecret: binding.identity.secretName,\n dbUrl: binding.url.replace(/\\/\\/[^:]+:[^@]+@/, \"//***:***@\"),\n workspaceDir: binding.identity.workspaceDir,\n localMigrationCount: localMigrations.length,\n appliedHashCount: 0,\n expectedTables,\n missingTables: [],\n migrationHashes: [],\n diagnosis: \"error\",\n error: error instanceof Error ? error.message : String(error),\n };\n } finally {\n await pool.end().catch(() => {});\n }\n}\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  const require_db_doctor = require('./db-doctor.cjs');
2
2
  let node_fs = require("node:fs");
3
3
  let node_path = require("node:path");
4
- let node_child_process = require("node:child_process");
4
+ let effect = require("effect");
5
5
 
6
6
  //#region src/cli/db-repair.ts
7
- async function repairPlugin(info, mode) {
8
- const diagnosis = await require_db_doctor.diagnosePlugin(info);
7
+ async function repairPlugin(binding, mode, drizzleKit) {
8
+ const diagnosis = await require_db_doctor.diagnosePlugin(binding);
9
9
  if (diagnosis.diagnosis === "error") return {
10
10
  status: "refused",
11
11
  diagnosis,
@@ -51,17 +51,17 @@ async function repairPlugin(info, mode) {
51
51
  const { Pool } = await import("pg");
52
52
  const journalRef = `"${diagnosis.journalSchema}"."${diagnosis.journalTable}"`;
53
53
  const pool = new Pool({
54
- connectionString: info.databaseUrl,
55
- ssl: info.databaseUrl.includes("localhost") || info.databaseUrl.includes("127.0.0.1") ? false : { rejectUnauthorized: false },
54
+ connectionString: binding.url,
55
+ ssl: binding.url.includes("localhost") || binding.url.includes("127.0.0.1") ? false : { rejectUnauthorized: false },
56
56
  max: 1,
57
57
  connectionTimeoutMillis: 1e4
58
58
  });
59
59
  try {
60
60
  await pool.query(`DROP TABLE IF EXISTS ${journalRef}`);
61
- if (info.workspaceDir) {
62
- const configPath = (0, node_path.join)(info.workspaceDir, "drizzle.config.ts");
61
+ if (binding.identity.workspaceDir) {
62
+ const configPath = (0, node_path.join)(binding.identity.workspaceDir, "drizzle.config.ts");
63
63
  if ((0, node_fs.existsSync)(configPath)) try {
64
- await spawnDrizzleMigrate(info.workspaceDir, configPath);
64
+ await effect.Effect.runPromise(drizzleKit.migrate(binding));
65
65
  return {
66
66
  status: "repaired",
67
67
  diagnosis,
@@ -71,7 +71,7 @@ async function repairPlugin(info, mode) {
71
71
  return {
72
72
  status: "repaired",
73
73
  diagnosis,
74
- message: `Migration history reset for ${diagnosis.plugin}. Automatic reapply failed: ${error instanceof Error ? error.message : String(error)}. Run \`bun run --cwd ${info.workspaceDir} db:migrate\` manually.`
74
+ message: `Migration history reset for ${diagnosis.plugin}. Automatic reapply failed: ${error instanceof Error ? error.message : String(error)}. Run \`pnpm --dir ${binding.identity.workspaceDir} run db:migrate\` manually.`
75
75
  };
76
76
  }
77
77
  }
@@ -90,29 +90,6 @@ async function repairPlugin(info, mode) {
90
90
  message: `Migration history reset for ${diagnosis.plugin}. No local drizzle.config.ts found — start the dev server to reapply migrations.`
91
91
  };
92
92
  }
93
- function spawnDrizzleMigrate(cwd, configPath) {
94
- return new Promise((resolvePromise, reject) => {
95
- const child = (0, node_child_process.spawn)("npx", [
96
- "drizzle-kit",
97
- "migrate",
98
- "--config",
99
- configPath
100
- ], {
101
- cwd,
102
- stdio: "pipe",
103
- shell: true
104
- });
105
- let stderr = "";
106
- child.stderr?.on("data", (data) => {
107
- stderr += data.toString();
108
- });
109
- child.on("error", (err) => reject(err));
110
- child.on("exit", (code) => {
111
- if (code === 0) resolvePromise();
112
- else reject(/* @__PURE__ */ new Error(`drizzle-kit migrate exited with code ${code}: ${stderr}`));
113
- });
114
- });
115
- }
116
93
 
117
94
  //#endregion
118
95
  exports.repairPlugin = repairPlugin;