@supatype/cli 0.1.7 → 0.1.10

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 (414) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +125 -122
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/LICENSE +202 -0
  5. package/deno.d.ts +1 -1
  6. package/dist/app/framework.js +1 -1
  7. package/dist/app/framework.js.map +1 -1
  8. package/dist/augmentation-generator.d.ts +1 -1
  9. package/dist/augmentation-generator.js +3 -3
  10. package/dist/augmentation-generator.js.map +1 -1
  11. package/dist/binary-cache.d.ts +30 -8
  12. package/dist/binary-cache.d.ts.map +1 -1
  13. package/dist/binary-cache.js +47 -35
  14. package/dist/binary-cache.js.map +1 -1
  15. package/dist/cache-pins.d.ts +1 -1
  16. package/dist/cache-pins.js +2 -2
  17. package/dist/cache-pins.js.map +1 -1
  18. package/dist/cli-artifacts.d.ts +32 -0
  19. package/dist/cli-artifacts.d.ts.map +1 -0
  20. package/dist/cli-artifacts.js +49 -0
  21. package/dist/cli-artifacts.js.map +1 -0
  22. package/dist/cli-install-method.d.ts +17 -1
  23. package/dist/cli-install-method.d.ts.map +1 -1
  24. package/dist/cli-install-method.js +32 -4
  25. package/dist/cli-install-method.js.map +1 -1
  26. package/dist/cli-package-version.d.ts +1 -1
  27. package/dist/cli-package-version.d.ts.map +1 -1
  28. package/dist/cli-package-version.js +6 -1
  29. package/dist/cli-package-version.js.map +1 -1
  30. package/dist/cli-standalone.d.ts +13 -4
  31. package/dist/cli-standalone.d.ts.map +1 -1
  32. package/dist/cli-standalone.js +86 -31
  33. package/dist/cli-standalone.js.map +1 -1
  34. package/dist/cli-version-embedded.d.ts +10 -0
  35. package/dist/cli-version-embedded.d.ts.map +1 -0
  36. package/dist/cli-version-embedded.js +13 -0
  37. package/dist/cli-version-embedded.js.map +1 -0
  38. package/dist/cli.js +1 -1
  39. package/dist/cli.js.map +1 -1
  40. package/dist/commands/add.js +4 -3
  41. package/dist/commands/add.js.map +1 -1
  42. package/dist/commands/admin.js +6 -6
  43. package/dist/commands/admin.js.map +1 -1
  44. package/dist/commands/adopt.js +1 -1
  45. package/dist/commands/adopt.js.map +1 -1
  46. package/dist/commands/app.js +2 -2
  47. package/dist/commands/app.js.map +1 -1
  48. package/dist/commands/cache.d.ts +1 -1
  49. package/dist/commands/cache.js +3 -3
  50. package/dist/commands/cache.js.map +1 -1
  51. package/dist/commands/db.d.ts +3 -3
  52. package/dist/commands/db.d.ts.map +1 -1
  53. package/dist/commands/db.js +12 -11
  54. package/dist/commands/db.js.map +1 -1
  55. package/dist/commands/deploy.d.ts +9 -9
  56. package/dist/commands/deploy.js +12 -12
  57. package/dist/commands/deploy.js.map +1 -1
  58. package/dist/commands/dev.d.ts +3 -3
  59. package/dist/commands/dev.js +17 -17
  60. package/dist/commands/dev.js.map +1 -1
  61. package/dist/commands/doctor.d.ts +1 -1
  62. package/dist/commands/doctor.js +3 -3
  63. package/dist/commands/doctor.js.map +1 -1
  64. package/dist/commands/engine.d.ts +1 -1
  65. package/dist/commands/engine.js +1 -1
  66. package/dist/commands/functions.d.ts.map +1 -1
  67. package/dist/commands/functions.js +8 -7
  68. package/dist/commands/functions.js.map +1 -1
  69. package/dist/commands/hooks.d.ts +2 -2
  70. package/dist/commands/hooks.js +4 -4
  71. package/dist/commands/hooks.js.map +1 -1
  72. package/dist/commands/init.js +28 -28
  73. package/dist/commands/init.js.map +1 -1
  74. package/dist/commands/internal.d.ts.map +1 -1
  75. package/dist/commands/internal.js +37 -0
  76. package/dist/commands/internal.js.map +1 -1
  77. package/dist/commands/login.d.ts +1 -1
  78. package/dist/commands/login.js +1 -1
  79. package/dist/commands/login.js.map +1 -1
  80. package/dist/commands/logs.d.ts +1 -1
  81. package/dist/commands/migrate.js +5 -5
  82. package/dist/commands/migrate.js.map +1 -1
  83. package/dist/commands/pg.d.ts +1 -1
  84. package/dist/commands/pg.js +1 -1
  85. package/dist/commands/plugins.js +1 -1
  86. package/dist/commands/plugins.js.map +1 -1
  87. package/dist/commands/pull.js +2 -2
  88. package/dist/commands/pull.js.map +1 -1
  89. package/dist/commands/push.js +3 -3
  90. package/dist/commands/push.js.map +1 -1
  91. package/dist/commands/self-host.d.ts +1 -1
  92. package/dist/commands/self-host.js +1 -1
  93. package/dist/commands/self-update.d.ts +2 -8
  94. package/dist/commands/self-update.d.ts.map +1 -1
  95. package/dist/commands/self-update.js +20 -12
  96. package/dist/commands/self-update.js.map +1 -1
  97. package/dist/commands/status.d.ts +1 -1
  98. package/dist/commands/update.d.ts +1 -1
  99. package/dist/commands/update.js +1 -1
  100. package/dist/config.d.ts +23 -1
  101. package/dist/config.d.ts.map +1 -1
  102. package/dist/config.js +37 -18
  103. package/dist/config.js.map +1 -1
  104. package/dist/db-preflight.d.ts +4 -4
  105. package/dist/db-preflight.js +14 -14
  106. package/dist/db-preflight.js.map +1 -1
  107. package/dist/dev-compose.d.ts +3 -3
  108. package/dist/dev-compose.js +27 -27
  109. package/dist/dev-compose.js.map +1 -1
  110. package/dist/dev-log-filter.d.ts +1 -1
  111. package/dist/dev-log-filter.d.ts.map +1 -1
  112. package/dist/dev-log-filter.js +1 -1
  113. package/dist/dev-log-filter.js.map +1 -1
  114. package/dist/dev-ports.d.ts +2 -2
  115. package/dist/dev-ports.d.ts.map +1 -1
  116. package/dist/dev-ports.js +2 -2
  117. package/dist/dev-ports.js.map +1 -1
  118. package/dist/dev-session.d.ts +5 -5
  119. package/dist/dev-session.d.ts.map +1 -1
  120. package/dist/dev-session.js +6 -6
  121. package/dist/dev-session.js.map +1 -1
  122. package/dist/dev-shutdown.d.ts +5 -5
  123. package/dist/dev-shutdown.d.ts.map +1 -1
  124. package/dist/dev-shutdown.js +7 -7
  125. package/dist/dev-shutdown.js.map +1 -1
  126. package/dist/dev-task-colors.d.ts +1 -1
  127. package/dist/dev-task-colors.d.ts.map +1 -1
  128. package/dist/dev-task-colors.js +1 -1
  129. package/dist/dev-task-colors.js.map +1 -1
  130. package/dist/docker-postgres.d.ts +5 -5
  131. package/dist/docker-postgres.d.ts.map +1 -1
  132. package/dist/docker-postgres.js +5 -5
  133. package/dist/docker-postgres.js.map +1 -1
  134. package/dist/docker-runtime.d.ts +2 -2
  135. package/dist/docker-runtime.d.ts.map +1 -1
  136. package/dist/docker-runtime.js +5 -5
  137. package/dist/docker-runtime.js.map +1 -1
  138. package/dist/engine-client.d.ts +1 -1
  139. package/dist/engine-client.js +3 -3
  140. package/dist/engine-client.js.map +1 -1
  141. package/dist/engine-push-output.js +1 -1
  142. package/dist/engine-push-output.js.map +1 -1
  143. package/dist/ensure-binary.d.ts.map +1 -1
  144. package/dist/ensure-binary.js +17 -0
  145. package/dist/ensure-binary.js.map +1 -1
  146. package/dist/ensure-component-binaries.js +1 -1
  147. package/dist/ensure-component-binaries.js.map +1 -1
  148. package/dist/env-file.d.ts +2 -2
  149. package/dist/env-file.d.ts.map +1 -1
  150. package/dist/env-file.js +1 -1
  151. package/dist/env-file.js.map +1 -1
  152. package/dist/field-masking-tier.d.ts +5 -5
  153. package/dist/field-masking-tier.d.ts.map +1 -1
  154. package/dist/field-masking-tier.js +6 -6
  155. package/dist/field-masking-tier.js.map +1 -1
  156. package/dist/functions-deno-types.d.ts +1 -1
  157. package/dist/functions-deno-types.d.ts.map +1 -1
  158. package/dist/functions-deno-types.js +3 -3
  159. package/dist/functions-deno-types.js.map +1 -1
  160. package/dist/functions-router-gen.js +1 -1
  161. package/dist/gitignore.d.ts +2 -2
  162. package/dist/gitignore.d.ts.map +1 -1
  163. package/dist/gitignore.js +3 -3
  164. package/dist/gitignore.js.map +1 -1
  165. package/dist/hook-upload.d.ts +1 -1
  166. package/dist/hook-upload.js +3 -3
  167. package/dist/hooks-generator.d.ts +1 -1
  168. package/dist/hooks-generator.js +9 -9
  169. package/dist/index.d.ts +1 -1
  170. package/dist/index.js +1 -1
  171. package/dist/init-project-detect.d.ts +1 -1
  172. package/dist/init-project-detect.d.ts.map +1 -1
  173. package/dist/init-project-detect.js +1 -1
  174. package/dist/init-project-detect.js.map +1 -1
  175. package/dist/link.d.ts +1 -1
  176. package/dist/link.d.ts.map +1 -1
  177. package/dist/local-secrets.d.ts +5 -5
  178. package/dist/local-secrets.js +5 -5
  179. package/dist/main.d.ts +2 -0
  180. package/dist/main.d.ts.map +1 -0
  181. package/dist/main.js +20 -0
  182. package/dist/main.js.map +1 -0
  183. package/dist/model-hooks.d.ts +3 -3
  184. package/dist/model-hooks.js +4 -4
  185. package/dist/pgbouncer-userlist.d.ts +1 -1
  186. package/dist/pgbouncer-userlist.d.ts.map +1 -1
  187. package/dist/pgbouncer-userlist.js +2 -2
  188. package/dist/pgbouncer-userlist.js.map +1 -1
  189. package/dist/postgres-ctl.d.ts +1 -1
  190. package/dist/postgres-ctl.js +4 -4
  191. package/dist/postgres-ctl.js.map +1 -1
  192. package/dist/process-manager.d.ts +2 -2
  193. package/dist/process-manager.d.ts.map +1 -1
  194. package/dist/process-manager.js +4 -4
  195. package/dist/process-manager.js.map +1 -1
  196. package/dist/project-config.d.ts +12 -12
  197. package/dist/project-config.d.ts.map +1 -1
  198. package/dist/project-config.js +9 -9
  199. package/dist/project-config.js.map +1 -1
  200. package/dist/pull-utils.d.ts +2 -2
  201. package/dist/pull-utils.d.ts.map +1 -1
  202. package/dist/pull-utils.js +4 -4
  203. package/dist/pull-utils.js.map +1 -1
  204. package/dist/realtime-launch.js +1 -1
  205. package/dist/realtime-launch.js.map +1 -1
  206. package/dist/release-pins.d.ts +1 -1
  207. package/dist/release-pins.js +2 -2
  208. package/dist/release-pins.js.map +1 -1
  209. package/dist/resolve-api-url.d.ts.map +1 -1
  210. package/dist/resolve-api-url.js +4 -3
  211. package/dist/resolve-api-url.js.map +1 -1
  212. package/dist/resolve-target.d.ts +1 -1
  213. package/dist/resolve-target.d.ts.map +1 -1
  214. package/dist/rest-cache-admin.js +2 -2
  215. package/dist/rest-cache-admin.js.map +1 -1
  216. package/dist/runtime-routes.d.ts +1 -1
  217. package/dist/runtime-routes.js +1 -1
  218. package/dist/schema-ast-v2.d.ts +3 -3
  219. package/dist/schema-ast-v2.d.ts.map +1 -1
  220. package/dist/schema-ast-v2.js +2 -2
  221. package/dist/schema-ast-v2.js.map +1 -1
  222. package/dist/schema-push-lock.js +3 -3
  223. package/dist/schema-push-lock.js.map +1 -1
  224. package/dist/scripts/postinstall.d.ts +1 -1
  225. package/dist/scripts/postinstall.js +1 -1
  226. package/dist/self-host-compose.d.ts +5 -5
  227. package/dist/self-host-compose.d.ts.map +1 -1
  228. package/dist/self-host-compose.js +24 -24
  229. package/dist/self-host-compose.js.map +1 -1
  230. package/dist/service-role-check.js +3 -3
  231. package/dist/service-role-check.js.map +1 -1
  232. package/dist/storage-provision.d.ts +1 -1
  233. package/dist/storage-provision.js +3 -3
  234. package/dist/storage-provision.js.map +1 -1
  235. package/dist/studio-dev-server.d.ts +1 -1
  236. package/dist/studio-dev-server.d.ts.map +1 -1
  237. package/dist/systemd.d.ts +1 -1
  238. package/dist/systemd.js +1 -1
  239. package/dist/target-client.js +1 -1
  240. package/dist/target-client.js.map +1 -1
  241. package/dist/tsx-runner.d.ts +12 -0
  242. package/dist/tsx-runner.d.ts.map +1 -1
  243. package/dist/tsx-runner.js +36 -2
  244. package/dist/tsx-runner.js.map +1 -1
  245. package/dist/type-extractor.js +27 -27
  246. package/dist/type-extractor.js.map +1 -1
  247. package/dist/type-resolver.js +1 -1
  248. package/dist/type-resolver.js.map +1 -1
  249. package/dist/ui/brand.d.ts +1 -1
  250. package/dist/ui/brand.js +1 -1
  251. package/dist/ui/components/LogoWordmark.d.ts +1 -1
  252. package/dist/ui/components/LogoWordmark.d.ts.map +1 -1
  253. package/dist/ui/components/LogoWordmark.js +1 -1
  254. package/dist/ui/components/LogoWordmark.js.map +1 -1
  255. package/dist/ui/components/SelectField.js +1 -1
  256. package/dist/ui/components/SelectField.js.map +1 -1
  257. package/dist/ui/confirm.d.ts +1 -1
  258. package/dist/ui/confirm.js +1 -1
  259. package/dist/ui/fatal.d.ts +1 -1
  260. package/dist/ui/fatal.d.ts.map +1 -1
  261. package/dist/ui/fatal.js +1 -1
  262. package/dist/ui/fatal.js.map +1 -1
  263. package/dist/ui/flows/prompt-fields.js +1 -1
  264. package/dist/ui/flows/prompt-fields.js.map +1 -1
  265. package/dist/ui/interactive.d.ts +1 -1
  266. package/dist/ui/interactive.d.ts.map +1 -1
  267. package/dist/ui/interactive.js +1 -1
  268. package/dist/ui/interactive.js.map +1 -1
  269. package/dist/ui/progress.d.ts +1 -1
  270. package/dist/ui/progress.js +1 -1
  271. package/dist/ui/runtime/command-chrome.js +1 -1
  272. package/dist/ui/runtime/command-chrome.js.map +1 -1
  273. package/dist/ui/runtime/run-clack-flow.js +1 -1
  274. package/dist/ui/runtime/run-clack-flow.js.map +1 -1
  275. package/dist/ui/runtime/stdin-after-ink.js +1 -1
  276. package/dist/ui/runtime/stdin-after-ink.js.map +1 -1
  277. package/dist/ui/theme.d.ts +1 -1
  278. package/dist/ui/theme.js +1 -1
  279. package/dist/valkey-sidecar.d.ts +1 -1
  280. package/dist/valkey-sidecar.d.ts.map +1 -1
  281. package/dist/valkey-sidecar.js +2 -2
  282. package/dist/valkey-sidecar.js.map +1 -1
  283. package/package.json +3 -2
  284. package/scripts/build-release-artifacts.sh +112 -0
  285. package/scripts/generate-homebrew-formula.mjs +47 -45
  286. package/scripts/mirror-deno-release.sh +1 -1
  287. package/src/TYPE-RESOLUTION.md +31 -31
  288. package/src/app/framework.ts +1 -1
  289. package/src/augmentation-generator.ts +3 -3
  290. package/src/binary-cache.ts +51 -36
  291. package/src/cache-pins.ts +2 -2
  292. package/src/cli-artifacts.ts +65 -0
  293. package/src/cli-install-method.ts +35 -4
  294. package/src/cli-package-version.ts +5 -1
  295. package/src/cli-standalone.ts +116 -34
  296. package/src/cli-version-embedded.ts +12 -0
  297. package/src/cli.ts +1 -1
  298. package/src/commands/add.ts +4 -3
  299. package/src/commands/admin.ts +6 -6
  300. package/src/commands/adopt.ts +1 -1
  301. package/src/commands/app.ts +2 -2
  302. package/src/commands/cache.ts +3 -3
  303. package/src/commands/db.ts +12 -11
  304. package/src/commands/deploy.ts +12 -12
  305. package/src/commands/dev.ts +19 -19
  306. package/src/commands/doctor.ts +3 -3
  307. package/src/commands/engine.ts +1 -1
  308. package/src/commands/functions.ts +8 -7
  309. package/src/commands/hooks.ts +6 -6
  310. package/src/commands/init.ts +28 -28
  311. package/src/commands/internal.ts +37 -0
  312. package/src/commands/login.ts +2 -2
  313. package/src/commands/logs.ts +1 -1
  314. package/src/commands/migrate.ts +5 -5
  315. package/src/commands/pg.ts +1 -1
  316. package/src/commands/plugins.ts +1 -1
  317. package/src/commands/pull.ts +2 -2
  318. package/src/commands/push.ts +3 -3
  319. package/src/commands/self-host.ts +1 -1
  320. package/src/commands/self-update.ts +23 -73
  321. package/src/commands/status.ts +1 -1
  322. package/src/commands/update.ts +1 -1
  323. package/src/config.ts +39 -18
  324. package/src/db-preflight.ts +15 -15
  325. package/src/dev-compose.ts +27 -27
  326. package/src/dev-log-filter.ts +1 -1
  327. package/src/dev-ports.ts +3 -3
  328. package/src/dev-session.ts +6 -6
  329. package/src/dev-shutdown.ts +8 -8
  330. package/src/dev-task-colors.ts +1 -1
  331. package/src/docker-postgres.ts +6 -6
  332. package/src/docker-runtime.ts +5 -5
  333. package/src/engine-client.ts +3 -3
  334. package/src/engine-push-output.ts +1 -1
  335. package/src/ensure-binary.ts +20 -0
  336. package/src/ensure-component-binaries.ts +1 -1
  337. package/src/env-file.ts +2 -2
  338. package/src/field-masking-tier.ts +6 -6
  339. package/src/functions-deno-types.ts +3 -3
  340. package/src/functions-router-gen.ts +1 -1
  341. package/src/gitignore.ts +3 -3
  342. package/src/hook-upload.ts +3 -3
  343. package/src/hooks-generator.ts +9 -9
  344. package/src/index.ts +1 -1
  345. package/src/init-project-detect.ts +1 -1
  346. package/src/link.ts +1 -1
  347. package/src/local-secrets.ts +5 -5
  348. package/src/main.ts +20 -0
  349. package/src/model-hooks.ts +4 -4
  350. package/src/pgbouncer-userlist.ts +2 -2
  351. package/src/postgres-ctl.ts +4 -4
  352. package/src/process-manager.ts +4 -4
  353. package/src/project-config.ts +16 -16
  354. package/src/pull-utils.ts +4 -4
  355. package/src/realtime-launch.ts +1 -1
  356. package/src/release-pins.ts +2 -2
  357. package/src/resolve-api-url.ts +4 -3
  358. package/src/resolve-target.ts +1 -1
  359. package/src/rest-cache-admin.ts +2 -2
  360. package/src/runtime-routes.ts +2 -2
  361. package/src/schema-ast-v2.ts +4 -4
  362. package/src/schema-push-lock.ts +3 -3
  363. package/src/scripts/postinstall.ts +1 -1
  364. package/src/self-host-compose.ts +25 -25
  365. package/src/service-role-check.ts +3 -3
  366. package/src/storage-provision.ts +3 -3
  367. package/src/studio-dev-server.ts +1 -1
  368. package/src/systemd.ts +1 -1
  369. package/src/target-client.ts +1 -1
  370. package/src/tsx-runner.ts +41 -2
  371. package/src/type-extractor.ts +27 -27
  372. package/src/type-resolver.ts +1 -1
  373. package/src/ui/README.md +1 -1
  374. package/src/ui/brand.ts +1 -1
  375. package/src/ui/components/LogoWordmark.tsx +1 -1
  376. package/src/ui/components/SelectField.tsx +1 -1
  377. package/src/ui/confirm.ts +1 -1
  378. package/src/ui/fatal.ts +1 -1
  379. package/src/ui/flows/prompt-fields.tsx +1 -1
  380. package/src/ui/interactive.ts +1 -1
  381. package/src/ui/progress.ts +1 -1
  382. package/src/ui/runtime/command-chrome.ts +1 -1
  383. package/src/ui/runtime/run-clack-flow.tsx +1 -1
  384. package/src/ui/runtime/stdin-after-ink.ts +1 -1
  385. package/src/ui/theme.ts +1 -1
  386. package/src/valkey-sidecar.ts +2 -2
  387. package/tests/access-composition.test.ts +6 -6
  388. package/tests/admin-studio-membership.test.ts +1 -1
  389. package/tests/api-schemas.test.ts +1 -1
  390. package/tests/archive-name-alias.test.ts +1 -1
  391. package/tests/cli-help.test.ts +8 -2
  392. package/tests/config-load-failure.test.ts +44 -0
  393. package/tests/db-preflight.test.ts +1 -1
  394. package/tests/doctor-render.test.ts +3 -3
  395. package/tests/doctor-service-role.test.ts +2 -2
  396. package/tests/engine-push-output.test.ts +1 -1
  397. package/tests/env-file.test.ts +3 -3
  398. package/tests/external-database-compose.test.ts +5 -5
  399. package/tests/external-database-config.test.ts +2 -2
  400. package/tests/field-masking-tier.test.ts +1 -1
  401. package/tests/homebrew-formula.test.ts +68 -26
  402. package/tests/hook-upload.test.ts +1 -1
  403. package/tests/hooks-generator.test.ts +1 -1
  404. package/tests/init.test.ts +2 -2
  405. package/tests/keys.test.ts +8 -2
  406. package/tests/local-secrets.test.ts +3 -3
  407. package/tests/model-hooks.test.ts +6 -6
  408. package/tests/runtime-contract.test.ts +2 -2
  409. package/tests/service-role-check.test.ts +3 -3
  410. package/tests/storage-provision.test.ts +1 -1
  411. package/tests/type-extractor.test.ts +2 -2
  412. package/tsconfig.tsbuildinfo +1 -1
  413. package/vitest.config.ts +7 -1
  414. package/scripts/build-release-bundle.mjs +0 -27
@@ -130,7 +130,7 @@ export function composePullNeedsIgnoreFailures(
130
130
  /**
131
131
  * Schema-engine image for a one-off `docker compose run` when pushing schema.
132
132
  * Uses config pin when set; otherwise CDN engine semver (Docker Hub `:latest` can lag).
133
- * Does not touch `.env` server/postgres still use compose `:latest` defaults.
133
+ * Does not touch `.env`, server/postgres still use compose `:latest` defaults.
134
134
  */
135
135
  export async function schemaEngineImageForPush(
136
136
  config: SupatypeProjectConfig,
@@ -174,7 +174,7 @@ export function staticDirForCompose(config: SupatypeProjectConfig): string | und
174
174
  /**
175
175
  * Bind-mount source for `/project` in generated compose files.
176
176
  * Paths are resolved from `--project-directory` (always the project root in `runDockerCompose`),
177
- * not from the compose file directory use `.` not `../..`.
177
+ * not from the compose file directory, use `.` not `../..`.
178
178
  */
179
179
  function projectMountPath(_cwd: string): string {
180
180
  return "."
@@ -198,13 +198,13 @@ function kongMountPath(_cwd: string): string {
198
198
  *
199
199
  * One expression instead of six identical constructions of `@db:5432`. With an external database it
200
200
  * becomes `${DATABASE_URL:?…}`: the URL is the operator's, so there is nothing for the generator to
201
- * build and interpolating the value into the compose file would write a password into a generated
201
+ * build: and interpolating the value into the compose file would write a password into a generated
202
202
  * file. Compose resolves the variable from `.env` at up-time, the same place the config's
203
203
  * `process.env.DATABASE_URL` read it from.
204
204
  */
205
205
  function ownerDatabaseUrl(config: SupatypeProjectConfig, scheme = "postgresql"): string {
206
206
  if (usesExternalDatabase(config)) {
207
- return "${DATABASE_URL:?DATABASE_URL is missing from .env required by database.external}"
207
+ return "${DATABASE_URL:?DATABASE_URL is missing from .env, required by database.external}"
208
208
  }
209
209
  return (
210
210
  `${scheme}://\${POSTGRES_USER:-supatype_admin}:` +
@@ -217,7 +217,7 @@ function ownerDatabaseUrl(config: SupatypeProjectConfig, scheme = "postgresql"):
217
217
  * PostgREST's DSN, which connects as `authenticator` rather than the owner.
218
218
  *
219
219
  * For an external database the host, port, database and query string are taken from the operator's
220
- * URL and only the password stays a variable. The alternative a second full URL in `.env` is one
220
+ * URL and only the password stays a variable. The alternative, a second full URL in `.env`, is one
221
221
  * more thing to keep in step with the first, and two URLs that disagree about *which database* is a
222
222
  * split-brain nobody notices until the API is serving one and migrations are landing in the other.
223
223
  * A hostname is not the secret here; the password is, and it stays out of the generated file.
@@ -237,7 +237,7 @@ function postgrestDatabaseUrl(config: SupatypeProjectConfig): string {
237
237
  /** Host Vite dev server as seen from Kong inside Docker Compose. */
238
238
  export const COMPOSE_STUDIO_HOST_URL = "http://host.docker.internal:3002"
239
239
 
240
- /** Studio container always Docker Hub unless SUPATYPE_STUDIO_IMAGE is set in .env. */
240
+ /** Studio container: always Docker Hub unless SUPATYPE_STUDIO_IMAGE is set in .env. */
241
241
  function studioServiceBlock(): string {
242
242
  return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
243
243
  }
@@ -281,7 +281,7 @@ export interface SelfHostComposeOptions {
281
281
  /**
282
282
  * Which mechanism enforces per-column rules, when the caller knows.
283
283
  *
284
- * Only the call sites that have loaded the schema can say see `field-masking-tier.ts`. Left
284
+ * Only the call sites that have loaded the schema can say, see `field-masking-tier.ts`. Left
285
285
  * unset, the exposed schema list is today's, which is correct for every project without field
286
286
  * rules and for every project on `supatype/postgres`.
287
287
  */
@@ -385,7 +385,7 @@ ${external ? "" : " db-data:\n"} minio-data:
385
385
 
386
386
  // `depends_on` for the services that talk to Postgres. With an external database there is no
387
387
  // container to wait on, so the clause disappears entirely and each service retries on connect
388
- // instead which is also what covers a database that restarts *after* boot, something no
388
+ // instead: which is also what covers a database that restarts *after* boot, something no
389
389
  // healthcheck ever did.
390
390
  const dbDependencyClause = external
391
391
  ? ""
@@ -412,8 +412,8 @@ ${external ? "" : " db-data:\n"} minio-data:
412
412
  DATABASE_URL: "${ownerUrl}"
413
413
  JWT_SECRET: \${JWT_SECRET:?JWT_SECRET is missing from .env}
414
414
  SLOT_NAME: supatype_realtime
415
- # Matches the publication the supatype/postgres image creates. Read by nothing today
416
- # wal2json decodes from the slot and kept for a future pgoutput decoder.
415
+ # Matches the publication the supatype/postgres image creates. Read by nothing today,
416
+ # wal2json decodes from the slot, and kept for a future pgoutput decoder.
417
417
  PUBLICATION_NAME: supatype_realtime
418
418
  ${dbDependency}`
419
419
  : ` # No \`realtime\` service: database.external.realtime is false. Subscriptions are
@@ -443,7 +443,7 @@ ${dbPorts} volumes:
443
443
  - db-data:/var/lib/postgresql/data
444
444
  healthcheck:
445
445
  # -h 127.0.0.1 forces TCP. Without it \`pg_isready\` uses the Unix socket, which the
446
- # entrypoint's temporary init server is already listening on while TCP is still refused
446
+ # entrypoint's temporary init server is already listening on while TCP is still refused,
447
447
  # so the container reported healthy, \`depends_on: service_healthy\` released, and every
448
448
  # service that connects over the network died with ECONNREFUSED on first boot. PostgREST
449
449
  # survived only because it retries. Observed on a clean stack: server, storage and
@@ -466,7 +466,7 @@ ${dbServiceBlock} postgrest:
466
466
  expose:
467
467
  - "3000"
468
468
  environment:
469
- # Connects as \`authenticator\`, not \${POSTGRES_USER} which is a superuser, and a
469
+ # Connects as \`authenticator\`, not \${POSTGRES_USER}, which is a superuser, and a
470
470
  # superuser session may SET ROLE to any role in the cluster, so a request whose JWT
471
471
  # named one got it. \`authenticator\` is NOINHERIT with membership in only
472
472
  # anon/authenticated/service_role, so the same SET ROLE is refused.
@@ -476,7 +476,7 @@ ${dbServiceBlock} postgrest:
476
476
  PGRST_DB_URI: ${postgrestUrl}
477
477
  # Derived from schema.pg_schema (or schema.api_schemas). Hardcoding this is why choosing a
478
478
  # non-public pg_schema used to give a correct push and an API that answered PGRST106 for
479
- # everything the engine moved and PostgREST was never told.
479
+ # everything: the engine moved and PostgREST was never told.
480
480
  PGRST_DB_SCHEMA: "${apiSchemaList(config, options?.fieldMaskingTier)}"
481
481
  PGRST_DB_ANON_ROLE: anon
482
482
  PGRST_JWT_SECRET: \${JWT_SECRET:?JWT_SECRET is missing from .env}
@@ -511,12 +511,12 @@ ${dbDependency}
511
511
  # cloud, for isolation the route boundary already provides.
512
512
  SUPATYPE_HOOKS_ROOT: /project/hooks
513
513
  PORT: "8001"
514
- # In-compose loopback to Kong (not API_EXTERNAL_URL / localhost unreachable from this container).
514
+ # In-compose loopback to Kong (not API_EXTERNAL_URL / localhost, unreachable from this container).
515
515
  SUPATYPE_URL: http://kong:8000
516
516
  SUPATYPE_INTERNAL_URL: http://kong:8000
517
517
  SUPATYPE_ANON_KEY: \${ANON_KEY:-}
518
- # Present so the worker can hand it to hooks which are procedural and unreachable from
519
- # outside and to the public functions named below. Withheld from every other handler before
518
+ # Present so the worker can hand it to hooks, which are procedural and unreachable from
519
+ # outside: and to the public functions named below. Withheld from every other handler before
520
520
  # any of them is imported: a function is a public endpoint, and an ambient admin credential made
521
521
  # each one able to read past every access rule in the schema.
522
522
  SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
@@ -629,7 +629,7 @@ ${kongDependsOn}${kongValkeyDepends}
629
629
  ${volumesBlock}`
630
630
  }
631
631
 
632
- /** In-compose worker address matches the `functions-worker` service this file always generates. */
632
+ /** In-compose worker address: matches the `functions-worker` service this file always generates. */
633
633
  const COMPOSE_FUNCTIONS_WORKER_URL = "http://functions-worker:8001"
634
634
 
635
635
  function ensureComposeManifest(cwd: string, config: SupatypeProjectConfig): void {
@@ -653,7 +653,7 @@ function ensureComposeManifest(cwd: string, config: SupatypeProjectConfig): void
653
653
  ...(realtimeEnabled(config) && { realtime_url: "http://realtime:4000" }),
654
654
  // True because this file *always* generates a `functions-worker` service and hands the server
655
655
  // `SUPATYPE_FUNCTIONS_WORKER_URL`. It said false, so the server answered 404 for every function
656
- // in a stack that was running a worker for them provisioned, then switched off.
656
+ // in a stack that was running a worker for them, provisioned, then switched off.
657
657
  functions_enabled: true,
658
658
  functions_worker_url: COMPOSE_FUNCTIONS_WORKER_URL,
659
659
  }
@@ -664,8 +664,8 @@ function ensureComposeManifest(cwd: string, config: SupatypeProjectConfig): void
664
664
  * Turn functions on in a manifest written by an older CLI, leaving every other key alone.
665
665
  *
666
666
  * Without this, only new projects get working functions: a stack generated before the flag was
667
- * corrected keeps `functions_enabled: false` on disk, and regenerating the compose file the
668
- * obvious thing to try does not fix it.
667
+ * corrected keeps `functions_enabled: false` on disk, and regenerating the compose file, the
668
+ * obvious thing to try, does not fix it.
669
669
  */
670
670
  function repairComposeFunctionsFlag(manifestPath: string): void {
671
671
  let parsed: Record<string, unknown>
@@ -696,7 +696,7 @@ function ensureProjectFunctionsDir(cwd: string, config: SupatypeProjectConfig):
696
696
  * The config's external URL and `.env`'s `DATABASE_URL` must be the same string.
697
697
  *
698
698
  * The CLI resolves the URL from config; Compose substitutes `.env` at up-time. If the two disagree,
699
- * `push` migrates one database while the services serve another which reads as data loss and
699
+ * `push` migrates one database while the services serve another, which reads as data loss and
700
700
  * isn't. It also makes the generated GoTrue DSN wrong, since whether to append `search_path` with
701
701
  * `?` or `&` is decided from the config URL's query string.
702
702
  */
@@ -731,14 +731,14 @@ function assertExternalUrlMatchesEnv(cwd: string, config: SupatypeProjectConfig)
731
731
  * A loopback host in the external URL cannot work from inside a container.
732
732
  *
733
733
  * `127.0.0.1` means "this container" to every service in the stack, so an external database on the
734
- * host machine is unreachable while the *CLI* reaches it fine, because the CLI runs on the host.
734
+ * host machine is unreachable, while the *CLI* reaches it fine, because the CLI runs on the host.
735
735
  * That asymmetry is the trap: `supatype db check` passes, `push` applies the schema, and then
736
736
  * storage, realtime and the server all die with ECONNREFUSED against their own loopback. Found by
737
737
  * rehearsing exactly that.
738
738
  *
739
739
  * Refused rather than rewritten. The compose file interpolates one `${DATABASE_URL}` for every
740
740
  * service, so silently substituting a different host would mean the CLI and the stack no longer
741
- * agree about which database they are talking to the thing every other check here exists to
741
+ * agree about which database they are talking to, the thing every other check here exists to
742
742
  * prevent.
743
743
  */
744
744
  export function loopbackExternalHost(config: SupatypeProjectConfig): string | undefined {
@@ -767,7 +767,7 @@ function assertExternalUrlReachableFromContainers(config: SupatypeProjectConfig)
767
767
  fatalError(
768
768
  `database.external.url points at ${host}, which no container can reach`,
769
769
  [
770
- "Inside a container, localhost is that container not the machine running Docker. Every",
770
+ "Inside a container, localhost is that container, not the machine running Docker. Every",
771
771
  "service in the stack would fail to connect, while the CLI succeeds because it runs on the host.",
772
772
  "",
773
773
  "Use a host the containers can resolve:",
@@ -902,7 +902,7 @@ export function runDockerCompose(
902
902
  return result.status ?? 1
903
903
  }
904
904
 
905
- /** Compose project name for a Supatype project isolates docker state per project. */
905
+ /** Compose project name for a Supatype project, isolates docker state per project. */
906
906
  export function composeProjectName(projectName: string): string {
907
907
  const slug = projectName.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "")
908
908
  return `supatype-${slug || "project"}`
@@ -2,7 +2,7 @@
2
2
  * Check that every name in `functions.serviceRole` is a function that exists.
3
3
  *
4
4
  * The grant fails **closed**: a typo, or a function that has since been renamed, means that function
5
- * quietly does not receive the service-role key. Nothing breaks loudly the handler simply reads
5
+ * quietly does not receive the service-role key. Nothing breaks loudly, the handler simply reads
6
6
  * `undefined` and whatever it does with the key stops working, at runtime, in a deploy that reported
7
7
  * success. So the name is checked where it is declared, against the directory it must match.
8
8
  *
@@ -77,7 +77,7 @@ export function checkServiceRoleRoutes(
77
77
  // Not an error: it was the documented form once, and the worker grants hooks whatever this says.
78
78
  // Still worth saying, because a reader would reasonably assume the line is what does the granting.
79
79
  warnings.push(
80
- ` "${name}" is not needed a hook receives the service-role key because only the API server ` +
80
+ ` "${name}" is not needed, a hook receives the service-role key because only the API server ` +
81
81
  `can reach it`,
82
82
  )
83
83
  continue
@@ -85,7 +85,7 @@ export function checkServiceRoleRoutes(
85
85
  if (!known.has(name)) {
86
86
  const where =
87
87
  searched.length > 1 ? ` (searched ${searched.join(", ")})` : ""
88
- errors.push(` "${name}" no ${primary}/${name}/index.ts${where}`)
88
+ errors.push(` "${name}": no ${primary}/${name}/index.ts${where}`)
89
89
  missing.push(name)
90
90
  }
91
91
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Provision storage buckets declared in a schema AST via the storage server API.
3
3
  *
4
- * The storage server is the authority on bucket existence going through the API
4
+ * The storage server is the authority on bucket existence, going through the API
5
5
  * ensures it creates any backing resources (directories, S3 buckets, etc.).
6
6
  * Buckets already registered return 409 Conflict, which is treated as success.
7
7
  */
@@ -76,10 +76,10 @@ export async function provisionBuckets(
76
76
  .catch(() => null)
77
77
 
78
78
  if (res === null) {
79
- console.warn(`[storage] Storage API unreachable skipped bucket "${bucket.id}"`)
79
+ console.warn(`[storage] Storage API unreachable, skipped bucket "${bucket.id}"`)
80
80
  continue
81
81
  }
82
- if (res.status === 409) continue // already exists fine
82
+ if (res.status === 409) continue // already exists, fine
83
83
  if (!res.ok) {
84
84
  const msg = await res.text().catch(() => res.statusText)
85
85
  console.warn(`[storage] Failed to provision bucket "${bucket.id}": ${msg}`)
@@ -20,7 +20,7 @@ export interface StudioDevServerOptions {
20
20
  * so fetches hit the Vite proxy (SUPATYPE_PROXY_TARGET) and avoid CORS.
21
21
  */
22
22
  viteSupatypeUrl: string
23
- /** Vite `base` `/studio/` when behind Kong at `/studio/`; `/` for native dev on :3002. */
23
+ /** Vite `base`: `/studio/` when behind Kong at `/studio/`; `/` for native dev on :3002. */
24
24
  basePath?: string
25
25
  }
26
26
 
package/src/systemd.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * systemd.ts generate systemd unit files for self-hosted deployments.
2
+ * systemd.ts: generate systemd unit files for self-hosted deployments.
3
3
  *
4
4
  * Usage:
5
5
  * generateUnits(config, outputDir)
@@ -115,7 +115,7 @@ export async function targetFetch<T>(
115
115
  !opts.authRefresh
116
116
  ) {
117
117
  throw new TargetApiError(
118
- `${message}. Session expired run: supatype login`,
118
+ `${message}. Session expired, run: supatype login`,
119
119
  result.status,
120
120
  result.json.code,
121
121
  )
package/src/tsx-runner.ts CHANGED
@@ -10,10 +10,11 @@ import { createRequire } from "node:module"
10
10
  import { fileURLToPath } from "node:url"
11
11
  import { writeFileSync, unlinkSync } from "node:fs"
12
12
  import { tmpdir } from "node:os"
13
+ import { isCompiledBinary } from "./cli-install-method.js"
13
14
 
14
15
  const _require = createRequire(import.meta.url)
15
16
 
16
- // The CLI's own source directory workspace packages are
17
+ // The CLI's own source directory, workspace packages are
17
18
  // resolvable from here. Eval snippets are written here so ESM resolution finds them.
18
19
  const CLI_SRC_DIR = dirname(fileURLToPath(import.meta.url))
19
20
 
@@ -51,7 +52,9 @@ export function runTsFile(
51
52
  filePath: string,
52
53
  opts: SpawnSyncOptions = {},
53
54
  ): RunResult {
54
- const result = spawnSync(process.execPath, [TSX_BIN, filePath], {
55
+ // Same split as importModuleAsJson: the binary interprets TypeScript itself, Node uses tsx.
56
+ const argv = isCompiledBinary() ? ["_run-ts", filePath] : [TSX_BIN, filePath]
57
+ const result = spawnSync(process.execPath, argv, {
55
58
  encoding: "utf8",
56
59
  maxBuffer: 50 * 1024 * 1024,
57
60
  ...opts,
@@ -87,3 +90,39 @@ export function evalTsSnippet(
87
90
  }
88
91
  }
89
92
  }
93
+
94
+ /**
95
+ * Import a module and return its default export as JSON text.
96
+ *
97
+ * Two interpreters, one contract. Under Node this writes a snippet and runs it through tsx, as
98
+ * it always has. As a compiled binary it re-executes itself, because there is no node_modules to
99
+ * resolve tsx from, no writable directory beside the executable, and on a `curl | sh` machine no
100
+ * Node either: the previous behaviour failed with
101
+ * `ENOENT: open '/$bunfs/root/supatype-eval-....mts'` and broke init, update, dev and push.
102
+ *
103
+ * Callers get the same stdout, stderr and exit code either way.
104
+ */
105
+ export function importModuleAsJson(
106
+ target: string,
107
+ opts: SpawnSyncOptions = {},
108
+ ): RunResult {
109
+ if (isCompiledBinary()) {
110
+ const result = spawnSync(process.execPath, ["_print-module", target], {
111
+ encoding: "utf8",
112
+ maxBuffer: 50 * 1024 * 1024,
113
+ ...opts,
114
+ })
115
+ return {
116
+ stdout: String(result.stdout ?? ""),
117
+ stderr: String(result.stderr ?? ""),
118
+ exitCode: result.status ?? 1,
119
+ }
120
+ }
121
+
122
+ const snippet = `
123
+ const mod = await import(${JSON.stringify(target)})
124
+ const config = mod.default ?? mod
125
+ process.stdout.write(JSON.stringify(config))
126
+ `
127
+ return evalTsSnippet(snippet, opts)
128
+ }
@@ -313,7 +313,7 @@ function mergeIntersectionParts(
313
313
  continue
314
314
  }
315
315
  }
316
- // Unresolvable parts are skipped the model still extracts with whatever fields were found
316
+ // Unresolvable parts are skipped, the model still extracts with whatever fields were found
317
317
  }
318
318
  if (allMembers.length === 0) return null
319
319
  return ts.factory.createTypeLiteralNode(allMembers)
@@ -910,7 +910,7 @@ function parseScalarType(
910
910
  return scalar("money")
911
911
  case "Decimal": {
912
912
  // `Decimal<10, 2>` names a precision and a scale, and the engine renders `NUMERIC(p, s)`
913
- // from them but nothing used to read the type arguments, so every Decimal became an
913
+ // from them: but nothing used to read the type arguments, so every Decimal became an
914
914
  // unbounded NUMERIC. Silently, which is the worst way to lose a constraint on a money column.
915
915
  const precision = parseNumericTypeArg(typeNode.typeArguments?.[0], sourceFile)
916
916
  const scale = parseNumericTypeArg(typeNode.typeArguments?.[1], sourceFile)
@@ -1453,7 +1453,7 @@ function looksLikeComputedTemplateLiteral(lit: string): boolean {
1453
1453
  return /\{truncate\s*\(/i.test(lit) || /\{[a-zA-Z_]\w*\}/g.test(lit)
1454
1454
  }
1455
1455
 
1456
- /** Resolves second type arg of `ComputedFrom<Value, Sources>` tuple concat, single field, or template literal. */
1456
+ /** Resolves second type arg of `ComputedFrom<Value, Sources>`, tuple concat, single field, or template literal. */
1457
1457
  function parseComputedFromSecondArg(
1458
1458
  sourcesArg: ts.TypeNode | undefined,
1459
1459
  sourceFile: ts.SourceFile,
@@ -1789,12 +1789,12 @@ function resolveIndexFieldName(fieldName: string, fields: Record<string, FieldAs
1789
1789
  * Resolve an `access:` annotation to its rule object.
1790
1790
  *
1791
1791
  * `access` may be written inline (`access: { read: Public }`) or factored into a
1792
- * shared type alias (`access: CmsPublicReadAdminWrite`) the latter is the
1792
+ * shared type alias (`access: CmsPublicReadAdminWrite`), the latter is the
1793
1793
  * natural way to reuse one policy set across many models, so it has to resolve
1794
1794
  * through aliases and intersections, not just literals.
1795
1795
  *
1796
1796
  * Anything unresolvable throws. Returning `{}` here means "no access rules",
1797
- * which the differ treats as "emit no RLS policies" so a typo or an
1797
+ * which the differ treats as "emit no RLS policies", so a typo or an
1798
1798
  * unsupported shape silently published a table with no row-level protection at
1799
1799
  * all. Failing the extract is the only safe outcome.
1800
1800
  */
@@ -1820,7 +1820,7 @@ function parseModelAccess(
1820
1820
  `\`${accessProp.type.getText(sourceFile)}\`.\n` +
1821
1821
  ` access must be an object type, or a type alias for one:\n` +
1822
1822
  ` export type PublicReadAdminWrite = { read: Public; create: Role<"admin"> }\n` +
1823
- ` A \`const … as const\` value cannot be used here access is read from types, and\n` +
1823
+ ` A \`const … as const\` value cannot be used here, access is read from types, and\n` +
1824
1824
  ` rule names like Public / Role are types, not values.\n` +
1825
1825
  ` Refusing to continue: an unresolved access block would publish this table with no RLS.`,
1826
1826
  )
@@ -1864,11 +1864,11 @@ function parseModelAccess(
1864
1864
  }
1865
1865
 
1866
1866
  /**
1867
- * `fields: { [column]: { read?, write? } }` per-column narrowing of the table rules.
1867
+ * `fields: { [column]: { read?, write? } }`, per-column narrowing of the table rules.
1868
1868
  *
1869
1869
  * Any rule the DSL can express is allowed. Enforcement is a query rewrite that
1870
1870
  * evaluates the rule per row with the caller's claims, so ownership, membership and
1871
- * application roles all work here none of which a column privilege could express.
1871
+ * application roles all work here, none of which a column privilege could express.
1872
1872
  */
1873
1873
  function parseFieldAccess(
1874
1874
  typeNode: ts.TypeNode,
@@ -1944,7 +1944,7 @@ function parseFieldAccess(
1944
1944
  *
1945
1945
  * An update policy has two halves: `USING` picks which existing rows may be
1946
1946
  * modified, `WITH CHECK` constrains what they may become. One rule for both is the
1947
- * right default and what every existing schema means but it makes "an editor may
1947
+ * right default and what every existing schema means, but it makes "an editor may
1948
1948
  * move a post between their own sites" inexpressible, because the row they are
1949
1949
  * changing and the row they are changing it into are judged by the same predicate.
1950
1950
  */
@@ -1974,11 +1974,11 @@ function parseUpdateSplit(
1974
1974
  }
1975
1975
  }
1976
1976
 
1977
- // Not the split form at all an object with neither key is some other shape.
1977
+ // Not the split form at all, an object with neither key is some other shape.
1978
1978
  if (!using && !check) return null
1979
1979
  if (!using) {
1980
1980
  throw new Error(
1981
- "`update: { check }` needs a `using` rule too without it no row is " +
1981
+ "`update: { check }` needs a `using` rule too, without it no row is " +
1982
1982
  "selectable for update, so the check can never apply.",
1983
1983
  )
1984
1984
  }
@@ -2028,7 +2028,7 @@ function resolveAccessLiteral(
2028
2028
  /**
2029
2029
  * `access` rules may be declared in a different file from the model (a shared
2030
2030
  * alias), and `getText(file)` reads the given file's text at the node's offsets
2031
- * so passing the model's file for a node owned by another one yielded garbage
2031
+ *- so passing the model's file for a node owned by another one yielded garbage
2032
2032
  * and every rule silently fell through to `private`. Always read a node's text
2033
2033
  * from the file that actually owns it.
2034
2034
  */
@@ -2056,7 +2056,7 @@ function parseAccessRule(
2056
2056
  if (!ts.isTypeReferenceNode(typeNode)) return { type: "private" }
2057
2057
 
2058
2058
  // `Rules.read` is a qualified name (namespace lookup), not a member of a type
2059
- // alias TypeScript rejects it, and it used to fall through to `private`,
2059
+ // alias: TypeScript rejects it, and it used to fall through to `private`,
2060
2060
  // silently denying an operation the author meant to grant.
2061
2061
  if (ts.isQualifiedName(typeNode.typeName)) {
2062
2062
  const text = ownerText(typeNode.typeName, sourceFile)
@@ -2113,7 +2113,7 @@ function parseAccessRule(
2113
2113
  )
2114
2114
  }
2115
2115
  // An empty list would compile to a policy that grants nothing while
2116
- // reading like a grant the exact silent-denial failure the unknown-rule
2116
+ // reading like a grant, the exact silent-denial failure the unknown-rule
2117
2117
  // branch below exists to prevent.
2118
2118
  if (listArg.elements.length === 0) {
2119
2119
  throw new Error(
@@ -2135,7 +2135,7 @@ function parseAccessRule(
2135
2135
  '`All<>` takes a tuple of rules, as in `All<[Role<"editor">, NotNull<"published_at">]>`.',
2136
2136
  )
2137
2137
  }
2138
- // Unlike `Any<[]>`, an empty `All` grants *everything* an empty AND is
2138
+ // Unlike `Any<[]>`, an empty `All` grants *everything*, an empty AND is
2139
2139
  // true. Reading as a restriction while imposing none is worse than an error.
2140
2140
  if (listArg.elements.length === 0) {
2141
2141
  throw new Error(
@@ -2209,7 +2209,7 @@ function parseAccessRule(
2209
2209
  const column = parseAccessOperand(args[0]!, sourceFile)
2210
2210
  if (column["kind"] !== "column") {
2211
2211
  throw new Error(
2212
- "`In<>`'s first argument must be a column name the membership test is " +
2212
+ "`In<>`'s first argument must be a column name, the membership test is " +
2213
2213
  "about a column of the row being checked.",
2214
2214
  )
2215
2215
  }
@@ -2220,7 +2220,7 @@ function parseAccessRule(
2220
2220
  }
2221
2221
  }
2222
2222
  default: {
2223
- // A named alias possibly parameterised standing for a rule. Expanded
2223
+ // A named alias: possibly parameterised, standing for a rule. Expanded
2224
2224
  // before giving up, so `SiteAccess<"site_id">` works.
2225
2225
  if (resolveCtx && depth < 16) {
2226
2226
  const expanded = resolveAccessAliasNode(typeNode, sourceFile, resolveCtx)
@@ -2228,7 +2228,7 @@ function parseAccessRule(
2228
2228
  }
2229
2229
 
2230
2230
  // Falling back to `private` here would silently deny an operation the
2231
- // author believed they had granted and with deny-by-default there is no
2231
+ // author believed they had granted, and with deny-by-default there is no
2232
2232
  // longer any need for a permissive guess. Name the offending rule instead.
2233
2233
  throw new Error(
2234
2234
  `Unknown access rule "${ref}". Supported: Public, Private, LoggedIn, ` +
@@ -2244,7 +2244,7 @@ function parseAccessRule(
2244
2244
  /**
2245
2245
  * Expands a named alias to the type it stands for.
2246
2246
  *
2247
- * This is what makes rules parameterisable the type-level equivalent of
2247
+ * This is what makes rules parameterisable, the type-level equivalent of
2248
2248
  * Payload's access-control factory:
2249
2249
  *
2250
2250
  * ```typescript
@@ -2252,8 +2252,8 @@ function parseAccessRule(
2252
2252
  * access: { update: SiteAccess<"site_id"> }
2253
2253
  * ```
2254
2254
  *
2255
- * Without it a rule had to be written inline at every use, and any alias even an
2256
- * unparameterised one was reported as an unknown rule.
2255
+ * Without it a rule had to be written inline at every use, and any alias, even an
2256
+ * unparameterised one: was reported as an unknown rule.
2257
2257
  */
2258
2258
  function resolveAccessAliasNode(
2259
2259
  typeNode: ts.TypeReferenceNode,
@@ -2274,7 +2274,7 @@ function resolveAccessAliasNode(
2274
2274
  * The set on the right of an `In<>`.
2275
2275
  *
2276
2276
  * Resolved through the same alias machinery as rules, so a shared
2277
- * `type MySites = Rows<…>` can be reused across models the parameterisation the
2277
+ * `type MySites = Rows<…>` can be reused across models, the parameterisation the
2278
2278
  * plan calls the type-level equivalent of Payload's access factory.
2279
2279
  */
2280
2280
  function parseMembershipSource(
@@ -2300,7 +2300,7 @@ function parseMembershipSource(
2300
2300
  const column = stringLiteralArg(args[1], "Rows", "column name")
2301
2301
  const source: Record<string, unknown> = { kind: "rows", table, column }
2302
2302
  // The third argument narrows the source rows. Absent means "every row",
2303
- // which is a lookup rather than a membership check allowed, but rarely
2303
+ // which is a lookup rather than a membership check, allowed, but rarely
2304
2304
  // what was meant, so it stays explicit rather than being defaulted.
2305
2305
  if (args[2]) {
2306
2306
  source["where"] = parseAccessRule(args[2], sourceFile, resolveCtx)
@@ -2318,7 +2318,7 @@ function parseMembershipSource(
2318
2318
  }
2319
2319
  // Not `parseAccessOperand`: there, a bare string is a *column*, which is
2320
2320
  // right for a comparison and wrong here. Inside a value list a string can
2321
- // only be a value, so it is read as one no `Literal<>` wrapper needed.
2321
+ // only be a value, so it is read as one, no `Literal<>` wrapper needed.
2322
2322
  return {
2323
2323
  kind: "literal",
2324
2324
  values: listArg.elements.map((element) => literalFromNode(element, sourceFile)),
@@ -2373,7 +2373,7 @@ function parseDurationOperand(
2373
2373
  const opposite = ref === "Ago" ? "FromNow" : "Ago"
2374
2374
 
2375
2375
  // A negative literal is a prefix-unary expression in the TypeScript AST, not a
2376
- // numeric literal, so it has to be recognised separately otherwise `Ago<-5, …>`
2376
+ // numeric literal, so it has to be recognised separately, otherwise `Ago<-5, …>`
2377
2377
  // is refused for the wrong reason and the message misses the real advice.
2378
2378
  if (
2379
2379
  ts.isLiteralTypeNode(amountNode) &&
@@ -2392,7 +2392,7 @@ function parseDurationOperand(
2392
2392
  const amount = Number(amountNode.literal.text)
2393
2393
  if (!Number.isInteger(amount)) {
2394
2394
  throw new Error(
2395
- `\`${ref}<${amount}, …>\` must be a whole number of units Postgres intervals ` +
2395
+ `\`${ref}<${amount}, …>\` must be a whole number of units, Postgres intervals ` +
2396
2396
  `take integers, so a fraction would be silently truncated or rejected.`,
2397
2397
  )
2398
2398
  }
@@ -2512,7 +2512,7 @@ function parseAccessOperand(
2512
2512
  // segment would silently look up a key that cannot exist.
2513
2513
  if (path === "" || path.split(".").some((segment) => segment.trim() === "")) {
2514
2514
  throw new Error(
2515
- `\`Claim<"${path}">\` is not a valid claim path use dotted segments, ` +
2515
+ `\`Claim<"${path}">\` is not a valid claim path, use dotted segments, ` +
2516
2516
  `as in \`Claim<"app_metadata.tier">\`.`,
2517
2517
  )
2518
2518
  }
@@ -295,7 +295,7 @@ function parseResolvedTypeText(typeText: string): ts.TypeNode {
295
295
  return decl.type
296
296
  }
297
297
 
298
- /** `T extends string ? Optional<T> : T` and similar pick the Optional branch for scalar args. */
298
+ /** `T extends string ? Optional<T> : T` and similar, pick the Optional branch for scalar args. */
299
299
  function tryEvaluateConditionalAlias(entry: AliasEntry, typeArgs: readonly ts.TypeNode[]): ts.TypeNode | null {
300
300
  const substituted = substituteAndParse(entry, typeArgs)
301
301
  if (!ts.isConditionalTypeNode(substituted)) return null
package/src/ui/README.md CHANGED
@@ -9,7 +9,7 @@ Shared Ink-based design system for the Supatype CLI.
9
9
  | `fatal.ts` | `fatalError`, `reportCliFatal` |
10
10
  | `confirm.ts` | Yes/no prompts (Ink overlay in dev, Ink flow in TTY) |
11
11
  | `progress.ts` | `withSpinner` + `runCommandChrome` for one-shot commands |
12
- | `runtime/command-chrome.ts` | Ink shell (logo, logs, spinner) applied globally via `wrapProgramActionsWithChrome` in `cli.ts` |
12
+ | `runtime/command-chrome.ts` | Ink shell (logo, logs, spinner), applied globally via `wrapProgramActionsWithChrome` in `cli.ts` |
13
13
  | `prompts.ts` | Logo, `promptText`, `promptPassword`, `ensureNotCancelled` |
14
14
  | `clack.ts` | Clack-compatible `p.*` API + `runClackFlow()` for wizards |
15
15
  | `flows/` | Ink flow shell + prompt fields |
package/src/ui/brand.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Shared ANSI styling for Supatype CLI output and the dev TUI.
3
- * @deprecated Prefer `theme.ts` for new code re-exports kept for dev-logo / task colors.
3
+ * @deprecated Prefer `theme.ts` for new code, re-exports kept for dev-logo / task colors.
4
4
  */
5
5
 
6
6
  export { BOLD, BRAND_COLOR, brandStyle, DIM, RESET } from "./theme.js"
@@ -15,7 +15,7 @@ export interface LogoWordmarkProps {
15
15
  tagline?: string
16
16
  }
17
17
 
18
- /** Figlet slant wordmark native Ink colours (no embedded ANSI). */
18
+ /** Figlet slant wordmark: native Ink colours (no embedded ANSI). */
19
19
  export function LogoWordmark({ maxWidth, tagline }: LogoWordmarkProps): React.ReactElement {
20
20
  const lines = layoutLogoBlock(pickLogoLines())
21
21
 
@@ -34,7 +34,7 @@ export function SelectField({
34
34
  })
35
35
 
36
36
  const items = options.map((opt) => ({
37
- label: opt.hint ? `${opt.label} ${opt.hint}` : opt.label,
37
+ label: opt.hint ? `${opt.label}, ${opt.hint}` : opt.label,
38
38
  value: opt.value,
39
39
  }))
40
40
 
package/src/ui/confirm.ts CHANGED
@@ -9,7 +9,7 @@ export interface ConfirmOptions {
9
9
  }
10
10
 
11
11
  /**
12
- * Yes/no confirmation Ink overlay in dev, Ink flow in TTY, default otherwise.
12
+ * Yes/no confirmation: Ink overlay in dev, Ink flow in TTY, default otherwise.
13
13
  */
14
14
  export async function confirm(message: string, opts: ConfirmOptions = {}): Promise<boolean> {
15
15
  const fallback = opts.nonInteractive ?? opts.default ?? false
package/src/ui/fatal.ts CHANGED
@@ -27,7 +27,7 @@ export function fatalError(message: string, hints: string[] = [], opts?: FatalOp
27
27
  process.exit(opts?.exitCode ?? 1)
28
28
  }
29
29
 
30
- /** Top-level CLI catch user-facing message without branding. */
30
+ /** Top-level CLI catch: user-facing message without branding. */
31
31
  export function reportCliFatal(err: unknown): void {
32
32
  const message = err instanceof Error ? err.message : String(err)
33
33
  error(message)
@@ -80,7 +80,7 @@ export function ConfirmPrompt({ spec, onSubmit }: ConfirmPromptProps): React.Rea
80
80
  ) : (
81
81
  <Text dimColor>No</Text>
82
82
  )}
83
- <Text dimColor> y/n, ←/→, enter</Text>
83
+ <Text dimColor>: y/n, ←/→, enter</Text>
84
84
  </Text>
85
85
  </Box>
86
86
  )
@@ -1,4 +1,4 @@
1
- /** True when stdin/stdout are TTYs interactive prompts and spinners are allowed. */
1
+ /** True when stdin/stdout are TTYs, interactive prompts and spinners are allowed. */
2
2
  export function isInteractive(): boolean {
3
3
  return Boolean(process.stdin.isTTY && process.stdout.isTTY)
4
4
  }