@supatype/cli 0.1.6 → 0.1.9

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 (477) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +152 -102
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/LICENSE +202 -0
  5. package/deno.d.ts +52 -0
  6. package/dist/app/framework.js +1 -1
  7. package/dist/app/framework.js.map +1 -1
  8. package/dist/augmentation-generator.d.ts +22 -0
  9. package/dist/augmentation-generator.d.ts.map +1 -1
  10. package/dist/augmentation-generator.js +19 -5
  11. package/dist/augmentation-generator.js.map +1 -1
  12. package/dist/binary-cache.d.ts +42 -6
  13. package/dist/binary-cache.d.ts.map +1 -1
  14. package/dist/binary-cache.js +76 -44
  15. package/dist/binary-cache.js.map +1 -1
  16. package/dist/cache-clean.d.ts +15 -0
  17. package/dist/cache-clean.d.ts.map +1 -0
  18. package/dist/cache-clean.js +76 -0
  19. package/dist/cache-clean.js.map +1 -0
  20. package/dist/cache-pins.d.ts +51 -0
  21. package/dist/cache-pins.d.ts.map +1 -0
  22. package/dist/cache-pins.js +184 -0
  23. package/dist/cache-pins.js.map +1 -0
  24. package/dist/cli-artifacts.d.ts +32 -0
  25. package/dist/cli-artifacts.d.ts.map +1 -0
  26. package/dist/cli-artifacts.js +49 -0
  27. package/dist/cli-artifacts.js.map +1 -0
  28. package/dist/cli-install-method.d.ts +27 -0
  29. package/dist/cli-install-method.d.ts.map +1 -0
  30. package/dist/cli-install-method.js +78 -0
  31. package/dist/cli-install-method.js.map +1 -0
  32. package/dist/cli-package-version.d.ts +1 -1
  33. package/dist/cli-package-version.d.ts.map +1 -1
  34. package/dist/cli-package-version.js +6 -1
  35. package/dist/cli-package-version.js.map +1 -1
  36. package/dist/cli-standalone.d.ts +13 -4
  37. package/dist/cli-standalone.d.ts.map +1 -1
  38. package/dist/cli-standalone.js +86 -31
  39. package/dist/cli-standalone.js.map +1 -1
  40. package/dist/cli-version-embedded.d.ts +10 -0
  41. package/dist/cli-version-embedded.d.ts.map +1 -0
  42. package/dist/cli-version-embedded.js +13 -0
  43. package/dist/cli-version-embedded.js.map +1 -0
  44. package/dist/cli.d.ts.map +1 -1
  45. package/dist/cli.js +7 -1
  46. package/dist/cli.js.map +1 -1
  47. package/dist/cloud-credentials.d.ts +34 -0
  48. package/dist/cloud-credentials.d.ts.map +1 -0
  49. package/dist/cloud-credentials.js +139 -0
  50. package/dist/cloud-credentials.js.map +1 -0
  51. package/dist/commands/add.js +1 -1
  52. package/dist/commands/add.js.map +1 -1
  53. package/dist/commands/admin.d.ts +11 -0
  54. package/dist/commands/admin.d.ts.map +1 -1
  55. package/dist/commands/admin.js +123 -21
  56. package/dist/commands/admin.js.map +1 -1
  57. package/dist/commands/adopt.js +1 -1
  58. package/dist/commands/adopt.js.map +1 -1
  59. package/dist/commands/app.js +2 -2
  60. package/dist/commands/app.js.map +1 -1
  61. package/dist/commands/cache.d.ts +1 -1
  62. package/dist/commands/cache.d.ts.map +1 -1
  63. package/dist/commands/cache.js +69 -73
  64. package/dist/commands/cache.js.map +1 -1
  65. package/dist/commands/cloud.d.ts.map +1 -1
  66. package/dist/commands/cloud.js +32 -8
  67. package/dist/commands/cloud.js.map +1 -1
  68. package/dist/commands/db.d.ts +3 -2
  69. package/dist/commands/db.d.ts.map +1 -1
  70. package/dist/commands/db.js +149 -3
  71. package/dist/commands/db.js.map +1 -1
  72. package/dist/commands/deploy.d.ts +9 -9
  73. package/dist/commands/deploy.js +12 -12
  74. package/dist/commands/deploy.js.map +1 -1
  75. package/dist/commands/dev.d.ts +3 -3
  76. package/dist/commands/dev.d.ts.map +1 -1
  77. package/dist/commands/dev.js +63 -23
  78. package/dist/commands/dev.js.map +1 -1
  79. package/dist/commands/doctor.d.ts +28 -0
  80. package/dist/commands/doctor.d.ts.map +1 -1
  81. package/dist/commands/doctor.js +60 -3
  82. package/dist/commands/doctor.js.map +1 -1
  83. package/dist/commands/engine.d.ts +1 -1
  84. package/dist/commands/engine.js +1 -1
  85. package/dist/commands/functions.d.ts +7 -0
  86. package/dist/commands/functions.d.ts.map +1 -1
  87. package/dist/commands/functions.js +45 -11
  88. package/dist/commands/functions.js.map +1 -1
  89. package/dist/commands/generate.d.ts.map +1 -1
  90. package/dist/commands/generate.js +5 -1
  91. package/dist/commands/generate.js.map +1 -1
  92. package/dist/commands/hooks.d.ts +12 -0
  93. package/dist/commands/hooks.d.ts.map +1 -0
  94. package/dist/commands/hooks.js +118 -0
  95. package/dist/commands/hooks.js.map +1 -0
  96. package/dist/commands/init.d.ts.map +1 -1
  97. package/dist/commands/init.js +64 -30
  98. package/dist/commands/init.js.map +1 -1
  99. package/dist/commands/internal.d.ts +6 -0
  100. package/dist/commands/internal.d.ts.map +1 -0
  101. package/dist/commands/internal.js +22 -0
  102. package/dist/commands/internal.js.map +1 -0
  103. package/dist/commands/link-helpers.d.ts.map +1 -1
  104. package/dist/commands/link-helpers.js +8 -2
  105. package/dist/commands/link-helpers.js.map +1 -1
  106. package/dist/commands/login.d.ts +7 -0
  107. package/dist/commands/login.d.ts.map +1 -0
  108. package/dist/commands/login.js +110 -0
  109. package/dist/commands/login.js.map +1 -0
  110. package/dist/commands/logs.d.ts +1 -1
  111. package/dist/commands/migrate.js +5 -5
  112. package/dist/commands/migrate.js.map +1 -1
  113. package/dist/commands/pg.d.ts +1 -1
  114. package/dist/commands/pg.js +1 -1
  115. package/dist/commands/plugins.js +1 -1
  116. package/dist/commands/plugins.js.map +1 -1
  117. package/dist/commands/pull.js +2 -2
  118. package/dist/commands/pull.js.map +1 -1
  119. package/dist/commands/push.d.ts.map +1 -1
  120. package/dist/commands/push.js +110 -7
  121. package/dist/commands/push.js.map +1 -1
  122. package/dist/commands/self-host.d.ts +1 -1
  123. package/dist/commands/self-host.js +1 -1
  124. package/dist/commands/self-update.d.ts +3 -2
  125. package/dist/commands/self-update.d.ts.map +1 -1
  126. package/dist/commands/self-update.js +31 -16
  127. package/dist/commands/self-update.js.map +1 -1
  128. package/dist/commands/status.d.ts +1 -1
  129. package/dist/commands/update.d.ts +1 -1
  130. package/dist/commands/update.js +1 -1
  131. package/dist/config.d.ts +1 -1
  132. package/dist/config.d.ts.map +1 -1
  133. package/dist/config.js +19 -4
  134. package/dist/config.js.map +1 -1
  135. package/dist/db-preflight.d.ts +78 -0
  136. package/dist/db-preflight.d.ts.map +1 -0
  137. package/dist/db-preflight.js +452 -0
  138. package/dist/db-preflight.js.map +1 -0
  139. package/dist/dev-compose.d.ts +4 -4
  140. package/dist/dev-compose.d.ts.map +1 -1
  141. package/dist/dev-compose.js +143 -88
  142. package/dist/dev-compose.js.map +1 -1
  143. package/dist/dev-log-filter.d.ts +1 -1
  144. package/dist/dev-log-filter.d.ts.map +1 -1
  145. package/dist/dev-log-filter.js +1 -1
  146. package/dist/dev-log-filter.js.map +1 -1
  147. package/dist/dev-ports.d.ts +2 -2
  148. package/dist/dev-ports.d.ts.map +1 -1
  149. package/dist/dev-ports.js +2 -2
  150. package/dist/dev-ports.js.map +1 -1
  151. package/dist/dev-session.d.ts +5 -5
  152. package/dist/dev-session.d.ts.map +1 -1
  153. package/dist/dev-session.js +6 -6
  154. package/dist/dev-session.js.map +1 -1
  155. package/dist/dev-shutdown.d.ts +5 -5
  156. package/dist/dev-shutdown.d.ts.map +1 -1
  157. package/dist/dev-shutdown.js +7 -7
  158. package/dist/dev-shutdown.js.map +1 -1
  159. package/dist/dev-task-colors.d.ts +1 -1
  160. package/dist/dev-task-colors.d.ts.map +1 -1
  161. package/dist/dev-task-colors.js +1 -1
  162. package/dist/dev-task-colors.js.map +1 -1
  163. package/dist/docker-postgres.d.ts +5 -5
  164. package/dist/docker-postgres.d.ts.map +1 -1
  165. package/dist/docker-postgres.js +5 -5
  166. package/dist/docker-postgres.js.map +1 -1
  167. package/dist/docker-runtime.d.ts +2 -2
  168. package/dist/docker-runtime.d.ts.map +1 -1
  169. package/dist/docker-runtime.js +5 -5
  170. package/dist/docker-runtime.js.map +1 -1
  171. package/dist/engine-client.d.ts +1 -1
  172. package/dist/engine-client.js +3 -3
  173. package/dist/engine-client.js.map +1 -1
  174. package/dist/engine-push-output.js +1 -1
  175. package/dist/engine-push-output.js.map +1 -1
  176. package/dist/ensure-binary.d.ts.map +1 -1
  177. package/dist/ensure-binary.js +17 -0
  178. package/dist/ensure-binary.js.map +1 -1
  179. package/dist/ensure-component-binaries.js +1 -1
  180. package/dist/ensure-component-binaries.js.map +1 -1
  181. package/dist/env-file.d.ts +40 -2
  182. package/dist/env-file.d.ts.map +1 -1
  183. package/dist/env-file.js +132 -11
  184. package/dist/env-file.js.map +1 -1
  185. package/dist/field-masking-tier.d.ts +50 -0
  186. package/dist/field-masking-tier.d.ts.map +1 -0
  187. package/dist/field-masking-tier.js +91 -0
  188. package/dist/field-masking-tier.js.map +1 -0
  189. package/dist/functions-deno-types.d.ts +24 -0
  190. package/dist/functions-deno-types.d.ts.map +1 -0
  191. package/dist/functions-deno-types.js +155 -0
  192. package/dist/functions-deno-types.js.map +1 -0
  193. package/dist/functions-router-gen.js +1 -1
  194. package/dist/gitignore.d.ts +2 -2
  195. package/dist/gitignore.d.ts.map +1 -1
  196. package/dist/gitignore.js +3 -3
  197. package/dist/gitignore.js.map +1 -1
  198. package/dist/hook-upload.d.ts +30 -0
  199. package/dist/hook-upload.d.ts.map +1 -0
  200. package/dist/hook-upload.js +86 -0
  201. package/dist/hook-upload.js.map +1 -0
  202. package/dist/hooks-generator.d.ts +8 -0
  203. package/dist/hooks-generator.d.ts.map +1 -0
  204. package/dist/hooks-generator.js +332 -0
  205. package/dist/hooks-generator.js.map +1 -0
  206. package/dist/index.d.ts +1 -1
  207. package/dist/index.js +1 -1
  208. package/dist/init-project-detect.d.ts +1 -1
  209. package/dist/init-project-detect.d.ts.map +1 -1
  210. package/dist/init-project-detect.js +1 -1
  211. package/dist/init-project-detect.js.map +1 -1
  212. package/dist/link.d.ts +4 -0
  213. package/dist/link.d.ts.map +1 -1
  214. package/dist/link.js +2 -0
  215. package/dist/link.js.map +1 -1
  216. package/dist/local-secrets.d.ts +71 -0
  217. package/dist/local-secrets.d.ts.map +1 -0
  218. package/dist/local-secrets.js +100 -0
  219. package/dist/local-secrets.js.map +1 -0
  220. package/dist/main.d.ts +2 -0
  221. package/dist/main.d.ts.map +1 -0
  222. package/dist/main.js +20 -0
  223. package/dist/main.js.map +1 -0
  224. package/dist/model-hooks.d.ts +73 -0
  225. package/dist/model-hooks.d.ts.map +1 -0
  226. package/dist/model-hooks.js +211 -0
  227. package/dist/model-hooks.js.map +1 -0
  228. package/dist/pgbouncer-userlist.d.ts +1 -1
  229. package/dist/pgbouncer-userlist.d.ts.map +1 -1
  230. package/dist/pgbouncer-userlist.js +2 -2
  231. package/dist/pgbouncer-userlist.js.map +1 -1
  232. package/dist/postgres-ctl.d.ts +12 -1
  233. package/dist/postgres-ctl.d.ts.map +1 -1
  234. package/dist/postgres-ctl.js +28 -5
  235. package/dist/postgres-ctl.js.map +1 -1
  236. package/dist/process-manager.d.ts +2 -2
  237. package/dist/process-manager.d.ts.map +1 -1
  238. package/dist/process-manager.js +4 -4
  239. package/dist/process-manager.js.map +1 -1
  240. package/dist/project-config.d.ts +122 -2
  241. package/dist/project-config.d.ts.map +1 -1
  242. package/dist/project-config.js +150 -1
  243. package/dist/project-config.js.map +1 -1
  244. package/dist/pull-utils.d.ts +2 -2
  245. package/dist/pull-utils.d.ts.map +1 -1
  246. package/dist/pull-utils.js +4 -4
  247. package/dist/pull-utils.js.map +1 -1
  248. package/dist/realtime-launch.js +1 -1
  249. package/dist/realtime-launch.js.map +1 -1
  250. package/dist/release-pins.d.ts +1 -1
  251. package/dist/release-pins.js +2 -2
  252. package/dist/release-pins.js.map +1 -1
  253. package/dist/resolve-api-url.js +1 -1
  254. package/dist/resolve-api-url.js.map +1 -1
  255. package/dist/resolve-target.d.ts +4 -0
  256. package/dist/resolve-target.d.ts.map +1 -1
  257. package/dist/resolve-target.js +69 -73
  258. package/dist/resolve-target.js.map +1 -1
  259. package/dist/rest-cache-admin.js +2 -2
  260. package/dist/rest-cache-admin.js.map +1 -1
  261. package/dist/runtime-routes.d.ts +1 -1
  262. package/dist/runtime-routes.js +1 -1
  263. package/dist/schema-ast-v2.d.ts +5 -4
  264. package/dist/schema-ast-v2.d.ts.map +1 -1
  265. package/dist/schema-ast-v2.js +5 -3
  266. package/dist/schema-ast-v2.js.map +1 -1
  267. package/dist/schema-push-lock.d.ts.map +1 -1
  268. package/dist/schema-push-lock.js +43 -16
  269. package/dist/schema-push-lock.js.map +1 -1
  270. package/dist/scripts/postinstall.d.ts +1 -1
  271. package/dist/scripts/postinstall.js +1 -1
  272. package/dist/self-host-compose.d.ts +26 -2
  273. package/dist/self-host-compose.d.ts.map +1 -1
  274. package/dist/self-host-compose.js +305 -73
  275. package/dist/self-host-compose.js.map +1 -1
  276. package/dist/service-role-check.d.ts +21 -0
  277. package/dist/service-role-check.d.ts.map +1 -0
  278. package/dist/service-role-check.js +85 -0
  279. package/dist/service-role-check.js.map +1 -0
  280. package/dist/storage-provision.d.ts +1 -1
  281. package/dist/storage-provision.js +3 -3
  282. package/dist/storage-provision.js.map +1 -1
  283. package/dist/studio-dev-server.d.ts +1 -1
  284. package/dist/studio-dev-server.d.ts.map +1 -1
  285. package/dist/systemd.d.ts +1 -1
  286. package/dist/systemd.js +1 -1
  287. package/dist/target-client.d.ts +17 -0
  288. package/dist/target-client.d.ts.map +1 -1
  289. package/dist/target-client.js +69 -17
  290. package/dist/target-client.js.map +1 -1
  291. package/dist/tsx-runner.js +1 -1
  292. package/dist/tsx-runner.js.map +1 -1
  293. package/dist/type-extractor.d.ts.map +1 -1
  294. package/dist/type-extractor.js +738 -34
  295. package/dist/type-extractor.js.map +1 -1
  296. package/dist/type-resolver.js +1 -1
  297. package/dist/type-resolver.js.map +1 -1
  298. package/dist/ui/brand.d.ts +1 -1
  299. package/dist/ui/brand.js +1 -1
  300. package/dist/ui/components/LogoWordmark.d.ts +1 -1
  301. package/dist/ui/components/LogoWordmark.d.ts.map +1 -1
  302. package/dist/ui/components/LogoWordmark.js +1 -1
  303. package/dist/ui/components/LogoWordmark.js.map +1 -1
  304. package/dist/ui/components/SelectField.js +1 -1
  305. package/dist/ui/components/SelectField.js.map +1 -1
  306. package/dist/ui/confirm.d.ts +1 -1
  307. package/dist/ui/confirm.js +1 -1
  308. package/dist/ui/fatal.d.ts +1 -1
  309. package/dist/ui/fatal.d.ts.map +1 -1
  310. package/dist/ui/fatal.js +1 -1
  311. package/dist/ui/fatal.js.map +1 -1
  312. package/dist/ui/flows/prompt-fields.js +1 -1
  313. package/dist/ui/flows/prompt-fields.js.map +1 -1
  314. package/dist/ui/interactive.d.ts +1 -1
  315. package/dist/ui/interactive.d.ts.map +1 -1
  316. package/dist/ui/interactive.js +1 -1
  317. package/dist/ui/interactive.js.map +1 -1
  318. package/dist/ui/progress.d.ts +1 -1
  319. package/dist/ui/progress.js +1 -1
  320. package/dist/ui/runtime/command-chrome.js +2 -2
  321. package/dist/ui/runtime/command-chrome.js.map +1 -1
  322. package/dist/ui/runtime/run-clack-flow.js +1 -1
  323. package/dist/ui/runtime/run-clack-flow.js.map +1 -1
  324. package/dist/ui/runtime/stdin-after-ink.d.ts.map +1 -1
  325. package/dist/ui/runtime/stdin-after-ink.js +4 -2
  326. package/dist/ui/runtime/stdin-after-ink.js.map +1 -1
  327. package/dist/ui/theme.d.ts +1 -1
  328. package/dist/ui/theme.js +1 -1
  329. package/dist/valkey-sidecar.d.ts +1 -1
  330. package/dist/valkey-sidecar.d.ts.map +1 -1
  331. package/dist/valkey-sidecar.js +2 -2
  332. package/dist/valkey-sidecar.js.map +1 -1
  333. package/package.json +6 -2
  334. package/scripts/build-release-artifacts.sh +112 -0
  335. package/scripts/generate-homebrew-formula.mjs +123 -0
  336. package/scripts/mirror-deno-release.sh +1 -1
  337. package/src/TYPE-RESOLUTION.md +31 -31
  338. package/src/app/framework.ts +1 -1
  339. package/src/augmentation-generator.ts +19 -6
  340. package/src/binary-cache.ts +94 -47
  341. package/src/cache-clean.ts +81 -0
  342. package/src/cache-pins.ts +243 -0
  343. package/src/cli-artifacts.ts +65 -0
  344. package/src/cli-install-method.ts +87 -0
  345. package/src/cli-package-version.ts +5 -1
  346. package/src/cli-standalone.ts +116 -34
  347. package/src/cli-version-embedded.ts +12 -0
  348. package/src/cli.ts +7 -1
  349. package/src/cloud-credentials.ts +183 -0
  350. package/src/commands/add.ts +1 -1
  351. package/src/commands/admin.ts +142 -27
  352. package/src/commands/adopt.ts +1 -1
  353. package/src/commands/app.ts +2 -2
  354. package/src/commands/cache.ts +92 -77
  355. package/src/commands/cloud.ts +32 -8
  356. package/src/commands/db.ts +164 -3
  357. package/src/commands/deploy.ts +12 -12
  358. package/src/commands/dev.ts +72 -23
  359. package/src/commands/doctor.ts +69 -3
  360. package/src/commands/engine.ts +1 -1
  361. package/src/commands/functions.ts +47 -10
  362. package/src/commands/generate.ts +5 -1
  363. package/src/commands/hooks.ts +138 -0
  364. package/src/commands/init.ts +65 -31
  365. package/src/commands/internal.ts +23 -0
  366. package/src/commands/link-helpers.ts +9 -2
  367. package/src/commands/login.ts +127 -0
  368. package/src/commands/logs.ts +1 -1
  369. package/src/commands/migrate.ts +5 -5
  370. package/src/commands/pg.ts +1 -1
  371. package/src/commands/plugins.ts +1 -1
  372. package/src/commands/pull.ts +2 -2
  373. package/src/commands/push.ts +124 -7
  374. package/src/commands/self-host.ts +1 -1
  375. package/src/commands/self-update.ts +41 -19
  376. package/src/commands/status.ts +1 -1
  377. package/src/commands/update.ts +1 -1
  378. package/src/config.ts +23 -4
  379. package/src/db-preflight.ts +575 -0
  380. package/src/dev-compose.ts +158 -89
  381. package/src/dev-log-filter.ts +1 -1
  382. package/src/dev-ports.ts +3 -3
  383. package/src/dev-session.ts +6 -6
  384. package/src/dev-shutdown.ts +8 -8
  385. package/src/dev-task-colors.ts +1 -1
  386. package/src/docker-postgres.ts +6 -6
  387. package/src/docker-runtime.ts +5 -5
  388. package/src/engine-client.ts +3 -3
  389. package/src/engine-push-output.ts +1 -1
  390. package/src/ensure-binary.ts +20 -0
  391. package/src/ensure-component-binaries.ts +1 -1
  392. package/src/env-file.ts +157 -11
  393. package/src/field-masking-tier.ts +107 -0
  394. package/src/functions-deno-types.ts +188 -0
  395. package/src/functions-router-gen.ts +1 -1
  396. package/src/gitignore.ts +3 -3
  397. package/src/hook-upload.ts +107 -0
  398. package/src/hooks-generator.ts +352 -0
  399. package/src/index.ts +1 -1
  400. package/src/init-project-detect.ts +1 -1
  401. package/src/link.ts +7 -0
  402. package/src/local-secrets.ts +104 -0
  403. package/src/main.ts +20 -0
  404. package/src/model-hooks.ts +260 -0
  405. package/src/pgbouncer-userlist.ts +2 -2
  406. package/src/postgres-ctl.ts +32 -5
  407. package/src/process-manager.ts +4 -4
  408. package/src/project-config.ts +237 -3
  409. package/src/pull-utils.ts +4 -4
  410. package/src/realtime-launch.ts +1 -1
  411. package/src/release-pins.ts +2 -2
  412. package/src/resolve-api-url.ts +1 -1
  413. package/src/resolve-target.ts +113 -68
  414. package/src/rest-cache-admin.ts +2 -2
  415. package/src/runtime-routes.ts +2 -2
  416. package/src/schema-ast-v2.ts +8 -5
  417. package/src/schema-push-lock.ts +56 -17
  418. package/src/scripts/postinstall.ts +1 -1
  419. package/src/self-host-compose.ts +348 -72
  420. package/src/service-role-check.ts +111 -0
  421. package/src/storage-provision.ts +3 -3
  422. package/src/studio-dev-server.ts +1 -1
  423. package/src/systemd.ts +1 -1
  424. package/src/target-client.ts +105 -18
  425. package/src/tsx-runner.ts +1 -1
  426. package/src/type-extractor.ts +885 -30
  427. package/src/type-resolver.ts +1 -1
  428. package/src/ui/README.md +1 -1
  429. package/src/ui/brand.ts +1 -1
  430. package/src/ui/components/LogoWordmark.tsx +1 -1
  431. package/src/ui/components/SelectField.tsx +1 -1
  432. package/src/ui/confirm.ts +1 -1
  433. package/src/ui/fatal.ts +1 -1
  434. package/src/ui/flows/prompt-fields.tsx +1 -1
  435. package/src/ui/interactive.ts +1 -1
  436. package/src/ui/progress.ts +1 -1
  437. package/src/ui/runtime/command-chrome.ts +2 -2
  438. package/src/ui/runtime/run-clack-flow.tsx +1 -1
  439. package/src/ui/runtime/stdin-after-ink.ts +4 -2
  440. package/src/ui/theme.ts +1 -1
  441. package/src/valkey-sidecar.ts +2 -2
  442. package/tests/access-composition.test.ts +667 -0
  443. package/tests/admin-studio-membership.test.ts +121 -0
  444. package/tests/api-schemas.test.ts +83 -0
  445. package/tests/archive-name-alias.test.ts +42 -0
  446. package/tests/augmentation-generator.test.ts +28 -0
  447. package/tests/cache-clean.test.ts +206 -0
  448. package/tests/cli-help.test.ts +11 -2
  449. package/tests/cli-install-method.test.ts +66 -0
  450. package/tests/command-chrome-coverage.test.ts +31 -26
  451. package/tests/command-chrome-wrap.test.ts +1 -0
  452. package/tests/db-preflight.test.ts +72 -0
  453. package/tests/doctor-render.test.ts +62 -0
  454. package/tests/doctor-service-role.test.ts +55 -0
  455. package/tests/engine-push-output.test.ts +1 -1
  456. package/tests/env-file.test.ts +121 -0
  457. package/tests/external-database-compose.test.ts +184 -0
  458. package/tests/external-database-config.test.ts +154 -0
  459. package/tests/field-masking-tier.test.ts +184 -0
  460. package/tests/functions-deno-types.test.ts +197 -0
  461. package/tests/homebrew-formula.test.ts +100 -0
  462. package/tests/hook-upload.test.ts +125 -0
  463. package/tests/hooks-generator.test.ts +212 -0
  464. package/tests/init.test.ts +5 -2
  465. package/tests/keys.test.ts +8 -2
  466. package/tests/local-secrets.test.ts +92 -0
  467. package/tests/model-hooks.test.ts +322 -0
  468. package/tests/runtime-contract.test.ts +113 -1
  469. package/tests/service-role-check.test.ts +109 -0
  470. package/tests/service-role-routes.test.ts +51 -0
  471. package/tests/storage-provision.test.ts +1 -1
  472. package/tests/target-client-refresh.test.ts +94 -0
  473. package/tests/type-extractor.test.ts +187 -0
  474. package/tsconfig.tsbuildinfo +1 -1
  475. package/vitest.config.ts +7 -1
  476. package/scripts/build-release-bundle.mjs +0 -27
  477. package/tests/engine-distribution.test.ts +0 -418
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Pin-aware cache eviction: collect `versions.*` pins across local projects (C13).
3
+ */
4
+
5
+ import { existsSync, readdirSync, rmSync, statSync } from "node:fs"
6
+ import { join, resolve } from "node:path"
7
+ import { BINARY_COMPONENTS, type Component } from "./components.js"
8
+ import { cachePath, cacheRoot, pinnedVersion, VERSION_PIN_LOCAL } from "./binary-cache.js"
9
+ import { loadConfig } from "./config.js"
10
+ import type { SupatypeProjectConfig } from "./project-config.js"
11
+
12
+ const CONFIG_FILENAMES = ["supatype.config.ts", "supatype.config.js", "supatype.config.mjs"] as const
13
+
14
+ export interface PinSource {
15
+ component: Component
16
+ version: string
17
+ projectDir: string
18
+ projectName: string
19
+ }
20
+
21
+ export interface CleanCacheEntry {
22
+ component: Component
23
+ version: string
24
+ bytes: number
25
+ }
26
+
27
+ export interface CleanCacheResult {
28
+ removed: CleanCacheEntry[]
29
+ skipped: Array<CleanCacheEntry & { reason: string }>
30
+ warned: string[]
31
+ }
32
+
33
+ /** Union pinned semver versions from one or more loaded configs. */
34
+ export function pinnedVersionsFromConfigs(
35
+ entries: Array<{ projectDir: string; config: SupatypeProjectConfig }>,
36
+ ): { protectedVersions: Map<Component, Set<string>>; sources: PinSource[] } {
37
+ const protectedVersions = new Map<Component, Set<string>>()
38
+ const sources: PinSource[] = []
39
+
40
+ for (const { projectDir, config } of entries) {
41
+ const projectName = config.project?.name?.trim() || projectDir
42
+ for (const component of BINARY_COMPONENTS) {
43
+ const version = pinnedVersion(component, config)
44
+ if (!version || version === VERSION_PIN_LOCAL) continue
45
+ let set = protectedVersions.get(component)
46
+ if (!set) {
47
+ set = new Set<string>()
48
+ protectedVersions.set(component, set)
49
+ }
50
+ set.add(version)
51
+ sources.push({ component, version, projectDir, projectName })
52
+ }
53
+ }
54
+
55
+ return { protectedVersions, sources }
56
+ }
57
+
58
+ function hasSupatypeConfig(dir: string): boolean {
59
+ return CONFIG_FILENAMES.some((name) => existsSync(join(dir, name)))
60
+ }
61
+
62
+ /** Walk `root` up to `maxDepth` looking for directories that contain a Supatype config file. */
63
+ export function findSupatypeProjectDirs(root: string, maxDepth = 4): string[] {
64
+ const absRoot = resolve(root)
65
+ if (!existsSync(absRoot)) return []
66
+
67
+ const found: string[] = []
68
+ const queue: Array<{ dir: string; depth: number }> = [{ dir: absRoot, depth: 0 }]
69
+
70
+ while (queue.length > 0) {
71
+ const item = queue.shift()
72
+ if (!item) break
73
+ const { dir, depth } = item
74
+
75
+ if (hasSupatypeConfig(dir)) {
76
+ found.push(dir)
77
+ continue
78
+ }
79
+
80
+ if (depth >= maxDepth) continue
81
+
82
+ let entries
83
+ try {
84
+ entries = readdirSync(dir, { withFileTypes: true })
85
+ } catch {
86
+ continue
87
+ }
88
+
89
+ for (const entry of entries) {
90
+ if (!entry.isDirectory()) continue
91
+ if (entry.name === "node_modules" || entry.name === ".git" || entry.name === ".supatype") continue
92
+ queue.push({ dir: join(dir, entry.name), depth: depth + 1 })
93
+ }
94
+ }
95
+
96
+ return found
97
+ }
98
+
99
+ /** Resolve project directories whose `versions` pins should protect cache entries. */
100
+ export function resolveCacheProjectDirs(cwd: string, extraProjects: string[]): string[] {
101
+ const dirs = new Set<string>()
102
+
103
+ for (const raw of extraProjects) {
104
+ const abs = resolve(raw)
105
+ if (hasSupatypeConfig(abs)) dirs.add(abs)
106
+ }
107
+
108
+ if (hasSupatypeConfig(cwd)) dirs.add(resolve(cwd))
109
+
110
+ const envRoots = process.env.SUPATYPE_CACHE_PROJECT_ROOTS?.trim()
111
+ if (envRoots) {
112
+ for (const segment of envRoots.split(",")) {
113
+ const root = segment.trim()
114
+ if (!root) continue
115
+ for (const dir of findSupatypeProjectDirs(root)) {
116
+ dirs.add(dir)
117
+ }
118
+ }
119
+ }
120
+
121
+ return [...dirs]
122
+ }
123
+
124
+ export function loadPinnedVersionsForProjects(
125
+ projectDirs: string[],
126
+ ): { protectedVersions: Map<Component, Set<string>>; sources: PinSource[]; loadWarnings: string[] } {
127
+ const configs: Array<{ projectDir: string; config: SupatypeProjectConfig }> = []
128
+ const loadWarnings: string[] = []
129
+
130
+ for (const projectDir of projectDirs) {
131
+ try {
132
+ configs.push({ projectDir, config: loadConfig(projectDir) })
133
+ } catch (err) {
134
+ const message = err instanceof Error ? err.message : String(err)
135
+ loadWarnings.push(`${projectDir}: ${message}`)
136
+ }
137
+ }
138
+
139
+ const { protectedVersions, sources } = pinnedVersionsFromConfigs(configs)
140
+ return { protectedVersions, sources, loadWarnings }
141
+ }
142
+
143
+ export function listCachedVersions(component: Component): string[] {
144
+ const compDir = join(cacheRoot(), component)
145
+ if (!existsSync(compDir)) return []
146
+ return readdirSync(compDir).filter((name) => {
147
+ try {
148
+ return statSync(join(compDir, name)).isDirectory()
149
+ } catch {
150
+ return false
151
+ }
152
+ })
153
+ }
154
+
155
+ function pinReason(
156
+ component: Component,
157
+ version: string,
158
+ sources: PinSource[],
159
+ ): string | undefined {
160
+ const matches = sources.filter((s) => s.component === component && s.version === version)
161
+ if (matches.length === 0) return undefined
162
+ const names = [...new Set(matches.map((m) => m.projectName))]
163
+ return `pinned by ${names.join(", ")}`
164
+ }
165
+
166
+ function dirSize(dir: string): number {
167
+ let total = 0
168
+ try {
169
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
170
+ const full = join(dir, entry.name)
171
+ if (entry.isDirectory()) {
172
+ total += dirSize(full)
173
+ } else {
174
+ total += statSync(full).size
175
+ }
176
+ }
177
+ } catch {
178
+ // skip unreadable
179
+ }
180
+ return total
181
+ }
182
+
183
+ export interface CleanCachedBinariesOptions {
184
+ components: Component[]
185
+ version?: string
186
+ force?: boolean
187
+ dryRun?: boolean
188
+ projectDirs: string[]
189
+ }
190
+
191
+ export function cleanCachedBinaries(options: CleanCachedBinariesOptions): CleanCacheResult {
192
+ const { protectedVersions, sources, loadWarnings } = loadPinnedVersionsForProjects(options.projectDirs)
193
+ const result: CleanCacheResult = { removed: [], skipped: [], warned: [...loadWarnings] }
194
+
195
+ const force = options.force === true
196
+ const dryRun = options.dryRun === true
197
+ const explicitVersion = options.version?.trim()
198
+
199
+ for (const component of options.components) {
200
+ const versions = explicitVersion ? [explicitVersion] : listCachedVersions(component)
201
+
202
+ for (const version of versions) {
203
+ const vDir = cachePath(component, version)
204
+ if (!existsSync(vDir)) {
205
+ if (explicitVersion) continue
206
+ continue
207
+ }
208
+
209
+ const bytes = dirSize(vDir)
210
+ const entry: CleanCacheEntry = { component, version, bytes }
211
+ const pinned = protectedVersions.get(component)?.has(version) ?? false
212
+
213
+ if (!force && !explicitVersion && pinned) {
214
+ const reason = pinReason(component, version, sources) ?? "pinned"
215
+ result.skipped.push({ ...entry, reason })
216
+ continue
217
+ }
218
+
219
+ if (!force && explicitVersion && pinned) {
220
+ const reason = pinReason(component, version, sources) ?? "pinned"
221
+ result.warned.push(
222
+ `${component}@${version} is ${reason}: removing anyway (explicit version)`,
223
+ )
224
+ }
225
+
226
+ if (!dryRun) {
227
+ rmSync(vDir, { recursive: true, force: true })
228
+ }
229
+ result.removed.push(entry)
230
+ }
231
+ }
232
+
233
+ return result
234
+ }
235
+
236
+ export function isVersionPinned(
237
+ component: Component,
238
+ version: string,
239
+ projectDirs: string[],
240
+ ): boolean {
241
+ const { protectedVersions } = loadPinnedVersionsForProjects(projectDirs)
242
+ return protectedVersions.get(component)?.has(version) ?? false
243
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Names and locations of the published standalone CLI artefacts.
3
+ *
4
+ * One place, because this layout had drifted into five: the release workflow, install.sh,
5
+ * this module's caller, the Homebrew generator and a now-deleted second installer all
6
+ * described it independently, and `supatype self-update` was asking for bare executables the
7
+ * publisher had stopped writing. `scripts/install.sh` cannot import this (it runs before any
8
+ * CLI exists on the machine), so the shell keeps its own copy; what holds the two together is
9
+ * the round-trip test in tests/integration/scripts/cli-artifact-roundtrip.sh, not this file.
10
+ */
11
+
12
+ import { existsSync, readdirSync } from "node:fs"
13
+ import { currentPlatform, type PlatformId } from "./binary-cache.js"
14
+
15
+ /**
16
+ * Which C library the running system provides. Only meaningful on Linux: Bun links
17
+ * libstdc++ and libgcc dynamically, so a glibc build cannot start on Alpine, and installing a
18
+ * glibc binary over a working musl one is how a self-update would brick an Alpine install.
19
+ */
20
+ export type LibcId = "glibc" | "musl"
21
+
22
+ /** Detects musl by its dynamic loader, the same signal scripts/install.sh uses. */
23
+ export function currentLibc(platform: PlatformId = currentPlatform()): LibcId {
24
+ if (platform.os !== "linux") return "glibc"
25
+ if (!existsSync("/lib")) return "glibc"
26
+ try {
27
+ const musl = readdirSync("/lib").some((f) => f.startsWith("ld-musl-") && f.endsWith(".so.1"))
28
+ return musl ? "musl" : "glibc"
29
+ } catch {
30
+ return "glibc"
31
+ }
32
+ }
33
+
34
+ /**
35
+ * The archive published for a platform. Windows gets a zip because that is what Windows
36
+ * users can open without extra tools; everything else is a tarball. Both hold a single
37
+ * executable called `supatype` (`supatype.exe` on Windows), whatever the archive is named.
38
+ */
39
+ export function cliArchiveName(
40
+ platform: PlatformId = currentPlatform(),
41
+ libc: LibcId = currentLibc(platform),
42
+ ): string {
43
+ const suffix = platform.os === "linux" && libc === "musl" ? "-musl" : ""
44
+ const ext = platform.os === "windows" ? "zip" : "tar.gz"
45
+ return `supatype-cli-${platform.os}-${platform.arch}${suffix}.${ext}`
46
+ }
47
+
48
+ /** The executable inside the archive. */
49
+ export function cliExecutableName(platform: PlatformId = currentPlatform()): string {
50
+ return platform.os === "windows" ? "supatype.exe" : "supatype"
51
+ }
52
+
53
+ /** CDN path of a version's archive, relative to the CDN root. */
54
+ export function cliArchivePath(
55
+ version: string,
56
+ platform: PlatformId = currentPlatform(),
57
+ libc: LibcId = currentLibc(platform),
58
+ ): string {
59
+ return `/cli/v${version}/${cliArchiveName(platform, libc)}`
60
+ }
61
+
62
+ /** CDN path of the checksums file covering every archive in a version. */
63
+ export function cliChecksumsPath(version: string): string {
64
+ return `/cli/v${version}/checksums.sha256`
65
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Detect how the supatype CLI was installed (npm, Homebrew, standalone CDN).
3
+ */
4
+
5
+ export type CliInstallMethod = "npm" | "homebrew" | "standalone"
6
+
7
+ function normalizePath(path: string): string {
8
+ return path.replace(/\\/g, "/")
9
+ }
10
+
11
+ /**
12
+ * Inside a Bun-compiled binary, argv[1] is a path in the embedded filesystem, not on disk:
13
+ * `/$bunfs/root/supatype` on Linux and macOS, `B:/~BUN/root/supatype.exe` on Windows. No
14
+ * filesystem call can touch either, which is why self-update failed with
15
+ * `ENOENT: copyfile '/$bunfs/root/supatype'` and could never have replaced itself.
16
+ */
17
+ const EMBEDDED_FS_PATH = /(^|\/)(\$bunfs|~BUN)\//i
18
+
19
+ /**
20
+ * The executable on disk.
21
+ *
22
+ * process.execPath is the compiled binary when running one, and the Node binary otherwise, so
23
+ * it is only correct to prefer it when argv[1] is an embedded path. Under Node the script path
24
+ * is what identifies the install.
25
+ */
26
+ export function runningBinaryPath(): string {
27
+ const main = normalizePath(process.argv[1] ?? "")
28
+ return EMBEDDED_FS_PATH.test(main) ? process.execPath : (process.argv[1] ?? "")
29
+ }
30
+
31
+ /** The running binary sits in an npm or workspace layout. */
32
+ function hasNpmInstallPath(): boolean {
33
+ const main = normalizePath(runningBinaryPath())
34
+ return (
35
+ main.includes("node_modules") ||
36
+ main.includes("/dist/cli") ||
37
+ main.includes("/bin/supatype.js")
38
+ )
39
+ }
40
+
41
+ /** Launched through an npm/pnpm/yarn script, whatever the binary's own layout. */
42
+ function ranUnderPackageManager(): boolean {
43
+ return Boolean(process.env["npm_execpath"]) || Boolean(process.env["npm_lifecycle_event"])
44
+ }
45
+
46
+ /** npm global, project dependency, or monorepo workspace build. */
47
+ export function looksLikeNpmOrWorkspaceCLI(): boolean {
48
+ return hasNpmInstallPath() || ranUnderPackageManager()
49
+ }
50
+
51
+ /** Homebrew / Linuxbrew Cellar layout. */
52
+ export function looksLikeHomebrewCLI(): boolean {
53
+ const main = normalizePath(runningBinaryPath())
54
+ if (!main) return false
55
+
56
+ if (/(?:^|\/)Cellar\/supatype\//.test(main)) return true
57
+
58
+ const cellar = process.env["HOMEBREW_CELLAR"]
59
+ if (cellar && normalizePath(main).startsWith(normalizePath(cellar) + "/") && main.includes("/supatype/")) {
60
+ return true
61
+ }
62
+
63
+ return false
64
+ }
65
+
66
+ /**
67
+ * Which installer owns the running binary. This decides what `self-update`
68
+ * tells the user to run, so it has to describe the binary on disk.
69
+ *
70
+ * Path shape wins over `npm_*` in the environment: those are set whenever the
71
+ * CLI is invoked from a package script, which says nothing about how the binary
72
+ * got there. Trusting them meant a Homebrew or curl install called from an npm
73
+ * script was told to update itself with npm.
74
+ */
75
+ export function detectCliInstallMethod(): CliInstallMethod {
76
+ if (hasNpmInstallPath()) return "npm"
77
+ if (looksLikeHomebrewCLI()) return "homebrew"
78
+ if (isStandalonePath()) return "standalone"
79
+ if (ranUnderPackageManager()) return "npm"
80
+ return "standalone"
81
+ }
82
+
83
+ /** The `curl | sh` installer's default target. */
84
+ function isStandalonePath(): boolean {
85
+ const main = normalizePath(runningBinaryPath())
86
+ return main.includes("/.supatype/bin/")
87
+ }
@@ -1,11 +1,15 @@
1
1
  import { readFileSync } from "node:fs"
2
2
  import { dirname, join } from "node:path"
3
3
  import { fileURLToPath } from "node:url"
4
+ import { EMBEDDED_CLI_VERSION } from "./cli-version-embedded.js"
4
5
 
5
6
  const CLI_PACKAGE_JSON = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json")
6
7
 
7
- /** Installed @supatype/cli version from package.json (used by --version and init scaffolding). */
8
+ /** Installed @supatype/cli version (used by --version and init scaffolding). */
8
9
  export function cliPackageVersion(): string {
10
+ // Set in published builds; the package.json read below only works when one is on disk,
11
+ // which is true for the npm package and false inside the standalone binary.
12
+ if (EMBEDDED_CLI_VERSION !== "") return EMBEDDED_CLI_VERSION
9
13
  try {
10
14
  const pkg = JSON.parse(readFileSync(CLI_PACKAGE_JSON, "utf8")) as { version?: string }
11
15
  return pkg.version ?? "0.0.0"
@@ -1,23 +1,45 @@
1
1
  /**
2
- * Standalone CLI binary CDN download (self-update + curl|sh installers).
2
+ * Standalone CLI archive download, used by `supatype self-update`.
3
+ *
4
+ * The artefact is a per-platform archive holding one executable, not a bare executable, and it
5
+ * is verified against the release's checksums.sha256 before anything is replaced. Previously
6
+ * this path checked only that the download was over 64 bytes and did not begin like HTML or
7
+ * JSON, which made the CLI stricter about a postgres archive than about overwriting itself.
3
8
  */
4
9
 
5
- import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs"
6
- import { homedir } from "node:os"
10
+ import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"
11
+ import { createHash } from "node:crypto"
12
+ import { homedir, tmpdir } from "node:os"
7
13
  import { join } from "node:path"
8
- import { currentPlatform, type PlatformId } from "./binary-cache.js"
14
+ import { spawnSync } from "node:child_process"
15
+ import { currentPlatform, fetchChecksums, type PlatformId } from "./binary-cache.js"
16
+ import {
17
+ cliArchiveName,
18
+ cliArchivePath,
19
+ cliChecksumsPath,
20
+ cliExecutableName,
21
+ currentLibc,
22
+ type LibcId,
23
+ } from "./cli-artifacts.js"
9
24
 
10
- const CDN_BASE = "https://releases.supatype.com"
11
-
12
- export function cliCdnPath(version: string, platform: PlatformId): string {
13
- const win = platform.os === "windows"
14
- return `/cli/v${version}/supatype-cli-${platform.os}-${platform.arch}${win ? ".exe" : ""}`
15
- }
25
+ /**
26
+ * Overridable for the same reason scripts/install.sh takes SUPATYPE_CDN: with the host fixed,
27
+ * nothing can exercise this path except a real release, which is how it came to request bare
28
+ * executables the publisher had stopped writing. SUPATYPE_CDN_BASE is the CDN root, where
29
+ * install.sh's SUPATYPE_CDN is the root plus /cli.
30
+ *
31
+ * binary-cache.ts hardcodes the same host for component downloads and could use the same
32
+ * treatment, which is left alone here as it is not part of this change.
33
+ */
34
+ const CDN_BASE = process.env["SUPATYPE_CDN_BASE"]?.replace(/\/$/, "")
35
+ || "https://releases.supatype.com"
16
36
 
17
- export function cliCachePath(version: string, platform: PlatformId = currentPlatform()): string {
18
- const win = platform.os === "windows"
19
- const name = `supatype-cli-${platform.os}-${platform.arch}${win ? ".exe" : ""}`
20
- return join(homedir(), ".supatype", "cache", "cli", version, name)
37
+ /** Where a downloaded release is unpacked, so a repeated update does not refetch it. */
38
+ export function cliCachePath(
39
+ version: string,
40
+ platform: PlatformId = currentPlatform(),
41
+ ): string {
42
+ return join(homedir(), ".supatype", "cache", "cli", version, cliExecutableName(platform))
21
43
  }
22
44
 
23
45
  export async function fetchStandaloneCliLatestVersion(): Promise<string> {
@@ -32,31 +54,91 @@ export async function fetchStandaloneCliLatestVersion(): Promise<string> {
32
54
  return data.version.trim()
33
55
  }
34
56
 
35
- /** Download the standalone CLI binary for the current platform. */
36
- export async function downloadStandaloneCli(version?: string): Promise<string> {
37
- const platform = currentPlatform()
38
- const resolved = version ?? await fetchStandaloneCliLatestVersion()
39
- const dest = cliCachePath(resolved, platform)
40
- if (existsSync(dest)) return dest
41
-
42
- const url = `${CDN_BASE}${cliCdnPath(resolved, platform)}`
57
+ async function fetchBytes(url: string, what: string): Promise<Buffer> {
43
58
  const resp = await fetch(url)
44
59
  if (!resp.ok) {
45
- throw new Error(`Failed to download CLI from ${url}: HTTP ${resp.status}`)
60
+ throw new Error(`Failed to download ${what} from ${url}: HTTP ${resp.status}`)
46
61
  }
47
- const buf = Buffer.from(await resp.arrayBuffer())
48
- if (buf.length < 64) {
49
- throw new Error("Downloaded CLI artifact is too small")
62
+ return Buffer.from(await resp.arrayBuffer())
63
+ }
64
+
65
+ /**
66
+ * Unpack the single executable from an archive.
67
+ *
68
+ * PowerShell on Windows, because Git Bash's tar is usually first on PATH there and chokes on
69
+ * drive-letter paths. The same split exists in commands/dev.ts for component archives.
70
+ */
71
+ function unpackExecutable(archivePath: string, destDir: string, platform: PlatformId): string {
72
+ mkdirSync(destDir, { recursive: true })
73
+ const result = platform.os === "windows"
74
+ ? spawnSync(
75
+ "powershell.exe",
76
+ [
77
+ "-NoProfile",
78
+ "-Command",
79
+ `Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`,
80
+ ],
81
+ { stdio: "pipe" },
82
+ )
83
+ : spawnSync("tar", ["-xzf", archivePath, "-C", destDir], { stdio: "pipe" })
84
+
85
+ if (result.status !== 0) {
86
+ throw new Error(
87
+ `Failed to unpack ${archivePath}: ${result.stderr?.toString().trim() || "unknown error"}`,
88
+ )
50
89
  }
51
- const head = buf.subarray(0, 5).toString("utf8").toLowerCase()
52
- if (head.startsWith("<!doc") || head.startsWith("{")) {
53
- throw new Error("Downloaded CLI artifact looks like an error page, not a binary")
90
+
91
+ const exe = join(destDir, cliExecutableName(platform))
92
+ if (!existsSync(exe)) {
93
+ throw new Error(
94
+ `${cliArchiveName(platform)} did not contain ${cliExecutableName(platform)}.`,
95
+ )
96
+ }
97
+ return exe
98
+ }
99
+
100
+ /**
101
+ * Download and verify the standalone CLI for this machine, returning the path to the
102
+ * executable. Nothing is written to the cache until the checksum matches.
103
+ */
104
+ export async function downloadStandaloneCli(
105
+ version?: string,
106
+ platform: PlatformId = currentPlatform(),
107
+ libc: LibcId = currentLibc(platform),
108
+ ): Promise<string> {
109
+ const resolved = version ?? await fetchStandaloneCliLatestVersion()
110
+ const dest = cliCachePath(resolved, platform)
111
+ if (existsSync(dest)) return dest
112
+
113
+ const name = cliArchiveName(platform, libc)
114
+ const archive = await fetchBytes(`${CDN_BASE}${cliArchivePath(resolved, platform, libc)}`, name)
115
+
116
+ // The manifest is verified before it is trusted, and only then is the archive compared
117
+ // against it. A checksum alone would prove the download was intact, not that it came from
118
+ // us, and the signature is what makes replacing our own executable no weaker than fetching
119
+ // a postgres archive. fetchChecksums treats the .minisig as mandatory and fails closed
120
+ // without a public key, which is the same rule component downloads follow.
121
+ const checksumsUrl = `${CDN_BASE}${cliChecksumsPath(resolved)}`
122
+ const expected = await fetchChecksums(checksumsUrl, `${checksumsUrl}.minisig`, name)
123
+ const actual = createHash("sha256").update(archive).digest("hex")
124
+ if (actual !== expected.checksum) {
125
+ throw new Error(
126
+ `Checksum mismatch for ${name}.\n expected: ${expected.checksum}\n actual: ${actual}`,
127
+ )
54
128
  }
55
129
 
56
- mkdirSync(join(dest, ".."), { recursive: true })
57
- writeFileSync(dest, buf)
58
- if (platform.os !== "windows") {
59
- chmodSync(dest, 0o755)
130
+ const staging = join(tmpdir(), `supatype-cli-${resolved}-${process.pid}`)
131
+ try {
132
+ mkdirSync(staging, { recursive: true })
133
+ const archivePath = join(staging, name)
134
+ writeFileSync(archivePath, archive)
135
+ const unpacked = unpackExecutable(archivePath, staging, platform)
136
+
137
+ mkdirSync(join(dest, ".."), { recursive: true })
138
+ writeFileSync(dest, readFileSync(unpacked))
139
+ if (platform.os !== "windows") chmodSync(dest, 0o755)
140
+ return dest
141
+ } finally {
142
+ rmSync(staging, { recursive: true, force: true })
60
143
  }
61
- return dest
62
144
  }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * CLI version, baked in at publish by scripts/set-version.mjs.
3
+ *
4
+ * The standalone binary cannot read its own package.json: pkg carries only files it can
5
+ * find by static analysis, and that path is assembled at runtime, so `--version` inside a
6
+ * published binary would answer 0.0.0 without this. Empty in a source checkout, where
7
+ * cliPackageVersion() falls back to reading package.json.
8
+ */
9
+ // Annotated `string`, not left to inference: once a release stamps a value here, the
10
+ // inferred literal type makes the `!== ""` test in cliPackageVersion() a compile error
11
+ // (TS2367, no overlap), so the build would only fail during a release.
12
+ export const EMBEDDED_CLI_VERSION: string = "0.1.9"
package/src/cli.ts CHANGED
@@ -18,6 +18,7 @@ import { registerApp } from "./commands/app.js"
18
18
  import { registerAdd } from "./commands/add.js"
19
19
  import { registerSelfHost } from "./commands/self-host.js"
20
20
  import { registerCloud } from "./commands/cloud.js"
21
+ import { registerLogin } from "./commands/login.js"
21
22
  import { registerEngine } from "./commands/engine.js"
22
23
  import { registerDb } from "./commands/db.js"
23
24
  import { registerDeploy } from "./commands/deploy.js"
@@ -25,10 +26,12 @@ import { registerStatus } from "./commands/status.js"
25
26
  import { registerLogs } from "./commands/logs.js"
26
27
  import { registerAdmin } from "./commands/admin.js"
27
28
  import { registerFunctions } from "./commands/functions.js"
29
+ import { registerHooks } from "./commands/hooks.js"
28
30
  import { registerPlugins } from "./commands/plugins.js"
29
31
  import { registerTypes } from "./commands/types.js"
30
32
  import { registerMigrateFromV1 } from "./commands/migrate-from-v1.js"
31
33
  import { registerSelfUpdate } from "./commands/self-update.js"
34
+ import { registerInternalCommands } from "./commands/internal.js"
32
35
  import { cliPackageVersion } from "./cli-package-version.js"
33
36
  import { reportCliFatal } from "./ui/fatal.js"
34
37
  import { wrapProgramActionsWithChrome } from "./ui/runtime/command-chrome.js"
@@ -36,13 +39,14 @@ import { wrapProgramActionsWithChrome } from "./ui/runtime/command-chrome.js"
36
39
  export async function run(): Promise<void> {
37
40
  const program = new Command()
38
41
  .name("supatype")
39
- .description("Supatype type-first platform for PostgreSQL")
42
+ .description("Supatype: type-first platform for PostgreSQL")
40
43
  .version(cliPackageVersion())
41
44
 
42
45
  registerInit(program)
43
46
  registerDev(program)
44
47
  registerCache(program)
45
48
  registerSelfUpdate(program)
49
+ registerInternalCommands(program)
46
50
  registerUpdate(program)
47
51
  registerPg(program)
48
52
  registerPush(program)
@@ -58,6 +62,7 @@ export async function run(): Promise<void> {
58
62
  registerApp(program)
59
63
  registerAdd(program)
60
64
  registerSelfHost(program)
65
+ registerLogin(program)
61
66
  registerCloud(program)
62
67
  registerEngine(program)
63
68
  registerDb(program)
@@ -66,6 +71,7 @@ export async function run(): Promise<void> {
66
71
  registerLogs(program)
67
72
  registerAdmin(program)
68
73
  registerFunctions(program)
74
+ registerHooks(program)
69
75
  registerPlugins(program)
70
76
  registerTypes(program)
71
77
  registerMigrateFromV1(program)