@supatype/cli 0.1.7 → 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 (404) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +128 -128
  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 +9 -1
  23. package/dist/cli-install-method.d.ts.map +1 -1
  24. package/dist/cli-install-method.js +22 -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 +1 -1
  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.js +9 -9
  53. package/dist/commands/db.js.map +1 -1
  54. package/dist/commands/deploy.d.ts +9 -9
  55. package/dist/commands/deploy.js +12 -12
  56. package/dist/commands/deploy.js.map +1 -1
  57. package/dist/commands/dev.d.ts +3 -3
  58. package/dist/commands/dev.js +17 -17
  59. package/dist/commands/dev.js.map +1 -1
  60. package/dist/commands/doctor.d.ts +1 -1
  61. package/dist/commands/doctor.js +3 -3
  62. package/dist/commands/doctor.js.map +1 -1
  63. package/dist/commands/engine.d.ts +1 -1
  64. package/dist/commands/engine.js +1 -1
  65. package/dist/commands/functions.js +5 -5
  66. package/dist/commands/functions.js.map +1 -1
  67. package/dist/commands/hooks.d.ts +2 -2
  68. package/dist/commands/hooks.js +4 -4
  69. package/dist/commands/hooks.js.map +1 -1
  70. package/dist/commands/init.js +28 -28
  71. package/dist/commands/init.js.map +1 -1
  72. package/dist/commands/login.d.ts +1 -1
  73. package/dist/commands/login.js +1 -1
  74. package/dist/commands/login.js.map +1 -1
  75. package/dist/commands/logs.d.ts +1 -1
  76. package/dist/commands/migrate.js +5 -5
  77. package/dist/commands/migrate.js.map +1 -1
  78. package/dist/commands/pg.d.ts +1 -1
  79. package/dist/commands/pg.js +1 -1
  80. package/dist/commands/plugins.js +1 -1
  81. package/dist/commands/plugins.js.map +1 -1
  82. package/dist/commands/pull.js +2 -2
  83. package/dist/commands/pull.js.map +1 -1
  84. package/dist/commands/push.js +3 -3
  85. package/dist/commands/push.js.map +1 -1
  86. package/dist/commands/self-host.d.ts +1 -1
  87. package/dist/commands/self-host.js +1 -1
  88. package/dist/commands/self-update.d.ts +2 -8
  89. package/dist/commands/self-update.d.ts.map +1 -1
  90. package/dist/commands/self-update.js +20 -12
  91. package/dist/commands/self-update.js.map +1 -1
  92. package/dist/commands/status.d.ts +1 -1
  93. package/dist/commands/update.d.ts +1 -1
  94. package/dist/commands/update.js +1 -1
  95. package/dist/config.d.ts +1 -1
  96. package/dist/config.d.ts.map +1 -1
  97. package/dist/config.js +3 -3
  98. package/dist/config.js.map +1 -1
  99. package/dist/db-preflight.d.ts +4 -4
  100. package/dist/db-preflight.js +14 -14
  101. package/dist/db-preflight.js.map +1 -1
  102. package/dist/dev-compose.d.ts +3 -3
  103. package/dist/dev-compose.js +27 -27
  104. package/dist/dev-compose.js.map +1 -1
  105. package/dist/dev-log-filter.d.ts +1 -1
  106. package/dist/dev-log-filter.d.ts.map +1 -1
  107. package/dist/dev-log-filter.js +1 -1
  108. package/dist/dev-log-filter.js.map +1 -1
  109. package/dist/dev-ports.d.ts +2 -2
  110. package/dist/dev-ports.d.ts.map +1 -1
  111. package/dist/dev-ports.js +2 -2
  112. package/dist/dev-ports.js.map +1 -1
  113. package/dist/dev-session.d.ts +5 -5
  114. package/dist/dev-session.d.ts.map +1 -1
  115. package/dist/dev-session.js +6 -6
  116. package/dist/dev-session.js.map +1 -1
  117. package/dist/dev-shutdown.d.ts +5 -5
  118. package/dist/dev-shutdown.d.ts.map +1 -1
  119. package/dist/dev-shutdown.js +7 -7
  120. package/dist/dev-shutdown.js.map +1 -1
  121. package/dist/dev-task-colors.d.ts +1 -1
  122. package/dist/dev-task-colors.d.ts.map +1 -1
  123. package/dist/dev-task-colors.js +1 -1
  124. package/dist/dev-task-colors.js.map +1 -1
  125. package/dist/docker-postgres.d.ts +5 -5
  126. package/dist/docker-postgres.d.ts.map +1 -1
  127. package/dist/docker-postgres.js +5 -5
  128. package/dist/docker-postgres.js.map +1 -1
  129. package/dist/docker-runtime.d.ts +2 -2
  130. package/dist/docker-runtime.d.ts.map +1 -1
  131. package/dist/docker-runtime.js +5 -5
  132. package/dist/docker-runtime.js.map +1 -1
  133. package/dist/engine-client.d.ts +1 -1
  134. package/dist/engine-client.js +3 -3
  135. package/dist/engine-client.js.map +1 -1
  136. package/dist/engine-push-output.js +1 -1
  137. package/dist/engine-push-output.js.map +1 -1
  138. package/dist/ensure-binary.d.ts.map +1 -1
  139. package/dist/ensure-binary.js +17 -0
  140. package/dist/ensure-binary.js.map +1 -1
  141. package/dist/ensure-component-binaries.js +1 -1
  142. package/dist/ensure-component-binaries.js.map +1 -1
  143. package/dist/env-file.d.ts +2 -2
  144. package/dist/env-file.d.ts.map +1 -1
  145. package/dist/env-file.js +1 -1
  146. package/dist/env-file.js.map +1 -1
  147. package/dist/field-masking-tier.d.ts +5 -5
  148. package/dist/field-masking-tier.d.ts.map +1 -1
  149. package/dist/field-masking-tier.js +6 -6
  150. package/dist/field-masking-tier.js.map +1 -1
  151. package/dist/functions-deno-types.d.ts +1 -1
  152. package/dist/functions-deno-types.d.ts.map +1 -1
  153. package/dist/functions-deno-types.js +3 -3
  154. package/dist/functions-deno-types.js.map +1 -1
  155. package/dist/functions-router-gen.js +1 -1
  156. package/dist/gitignore.d.ts +2 -2
  157. package/dist/gitignore.d.ts.map +1 -1
  158. package/dist/gitignore.js +3 -3
  159. package/dist/gitignore.js.map +1 -1
  160. package/dist/hook-upload.d.ts +1 -1
  161. package/dist/hook-upload.js +3 -3
  162. package/dist/hooks-generator.d.ts +1 -1
  163. package/dist/hooks-generator.js +9 -9
  164. package/dist/index.d.ts +1 -1
  165. package/dist/index.js +1 -1
  166. package/dist/init-project-detect.d.ts +1 -1
  167. package/dist/init-project-detect.d.ts.map +1 -1
  168. package/dist/init-project-detect.js +1 -1
  169. package/dist/init-project-detect.js.map +1 -1
  170. package/dist/link.d.ts +1 -1
  171. package/dist/link.d.ts.map +1 -1
  172. package/dist/local-secrets.d.ts +5 -5
  173. package/dist/local-secrets.js +5 -5
  174. package/dist/main.d.ts +2 -0
  175. package/dist/main.d.ts.map +1 -0
  176. package/dist/main.js +20 -0
  177. package/dist/main.js.map +1 -0
  178. package/dist/model-hooks.d.ts +3 -3
  179. package/dist/model-hooks.js +4 -4
  180. package/dist/pgbouncer-userlist.d.ts +1 -1
  181. package/dist/pgbouncer-userlist.d.ts.map +1 -1
  182. package/dist/pgbouncer-userlist.js +2 -2
  183. package/dist/pgbouncer-userlist.js.map +1 -1
  184. package/dist/postgres-ctl.d.ts +1 -1
  185. package/dist/postgres-ctl.js +4 -4
  186. package/dist/postgres-ctl.js.map +1 -1
  187. package/dist/process-manager.d.ts +2 -2
  188. package/dist/process-manager.d.ts.map +1 -1
  189. package/dist/process-manager.js +4 -4
  190. package/dist/process-manager.js.map +1 -1
  191. package/dist/project-config.d.ts +12 -12
  192. package/dist/project-config.d.ts.map +1 -1
  193. package/dist/project-config.js +9 -9
  194. package/dist/project-config.js.map +1 -1
  195. package/dist/pull-utils.d.ts +2 -2
  196. package/dist/pull-utils.d.ts.map +1 -1
  197. package/dist/pull-utils.js +4 -4
  198. package/dist/pull-utils.js.map +1 -1
  199. package/dist/realtime-launch.js +1 -1
  200. package/dist/realtime-launch.js.map +1 -1
  201. package/dist/release-pins.d.ts +1 -1
  202. package/dist/release-pins.js +2 -2
  203. package/dist/release-pins.js.map +1 -1
  204. package/dist/resolve-api-url.js +1 -1
  205. package/dist/resolve-api-url.js.map +1 -1
  206. package/dist/resolve-target.d.ts +1 -1
  207. package/dist/resolve-target.d.ts.map +1 -1
  208. package/dist/rest-cache-admin.js +2 -2
  209. package/dist/rest-cache-admin.js.map +1 -1
  210. package/dist/runtime-routes.d.ts +1 -1
  211. package/dist/runtime-routes.js +1 -1
  212. package/dist/schema-ast-v2.d.ts +3 -3
  213. package/dist/schema-ast-v2.d.ts.map +1 -1
  214. package/dist/schema-ast-v2.js +2 -2
  215. package/dist/schema-ast-v2.js.map +1 -1
  216. package/dist/schema-push-lock.js +3 -3
  217. package/dist/schema-push-lock.js.map +1 -1
  218. package/dist/scripts/postinstall.d.ts +1 -1
  219. package/dist/scripts/postinstall.js +1 -1
  220. package/dist/self-host-compose.d.ts +5 -5
  221. package/dist/self-host-compose.d.ts.map +1 -1
  222. package/dist/self-host-compose.js +24 -24
  223. package/dist/self-host-compose.js.map +1 -1
  224. package/dist/service-role-check.js +3 -3
  225. package/dist/service-role-check.js.map +1 -1
  226. package/dist/storage-provision.d.ts +1 -1
  227. package/dist/storage-provision.js +3 -3
  228. package/dist/storage-provision.js.map +1 -1
  229. package/dist/studio-dev-server.d.ts +1 -1
  230. package/dist/studio-dev-server.d.ts.map +1 -1
  231. package/dist/systemd.d.ts +1 -1
  232. package/dist/systemd.js +1 -1
  233. package/dist/target-client.js +1 -1
  234. package/dist/target-client.js.map +1 -1
  235. package/dist/tsx-runner.js +1 -1
  236. package/dist/tsx-runner.js.map +1 -1
  237. package/dist/type-extractor.js +27 -27
  238. package/dist/type-extractor.js.map +1 -1
  239. package/dist/type-resolver.js +1 -1
  240. package/dist/type-resolver.js.map +1 -1
  241. package/dist/ui/brand.d.ts +1 -1
  242. package/dist/ui/brand.js +1 -1
  243. package/dist/ui/components/LogoWordmark.d.ts +1 -1
  244. package/dist/ui/components/LogoWordmark.d.ts.map +1 -1
  245. package/dist/ui/components/LogoWordmark.js +1 -1
  246. package/dist/ui/components/LogoWordmark.js.map +1 -1
  247. package/dist/ui/components/SelectField.js +1 -1
  248. package/dist/ui/components/SelectField.js.map +1 -1
  249. package/dist/ui/confirm.d.ts +1 -1
  250. package/dist/ui/confirm.js +1 -1
  251. package/dist/ui/fatal.d.ts +1 -1
  252. package/dist/ui/fatal.d.ts.map +1 -1
  253. package/dist/ui/fatal.js +1 -1
  254. package/dist/ui/fatal.js.map +1 -1
  255. package/dist/ui/flows/prompt-fields.js +1 -1
  256. package/dist/ui/flows/prompt-fields.js.map +1 -1
  257. package/dist/ui/interactive.d.ts +1 -1
  258. package/dist/ui/interactive.d.ts.map +1 -1
  259. package/dist/ui/interactive.js +1 -1
  260. package/dist/ui/interactive.js.map +1 -1
  261. package/dist/ui/progress.d.ts +1 -1
  262. package/dist/ui/progress.js +1 -1
  263. package/dist/ui/runtime/command-chrome.js +1 -1
  264. package/dist/ui/runtime/command-chrome.js.map +1 -1
  265. package/dist/ui/runtime/run-clack-flow.js +1 -1
  266. package/dist/ui/runtime/run-clack-flow.js.map +1 -1
  267. package/dist/ui/runtime/stdin-after-ink.js +1 -1
  268. package/dist/ui/runtime/stdin-after-ink.js.map +1 -1
  269. package/dist/ui/theme.d.ts +1 -1
  270. package/dist/ui/theme.js +1 -1
  271. package/dist/valkey-sidecar.d.ts +1 -1
  272. package/dist/valkey-sidecar.d.ts.map +1 -1
  273. package/dist/valkey-sidecar.js +2 -2
  274. package/dist/valkey-sidecar.js.map +1 -1
  275. package/package.json +3 -2
  276. package/scripts/build-release-artifacts.sh +112 -0
  277. package/scripts/generate-homebrew-formula.mjs +47 -45
  278. package/scripts/mirror-deno-release.sh +1 -1
  279. package/src/TYPE-RESOLUTION.md +31 -31
  280. package/src/app/framework.ts +1 -1
  281. package/src/augmentation-generator.ts +3 -3
  282. package/src/binary-cache.ts +51 -36
  283. package/src/cache-pins.ts +2 -2
  284. package/src/cli-artifacts.ts +65 -0
  285. package/src/cli-install-method.ts +24 -4
  286. package/src/cli-package-version.ts +5 -1
  287. package/src/cli-standalone.ts +116 -34
  288. package/src/cli-version-embedded.ts +12 -0
  289. package/src/cli.ts +1 -1
  290. package/src/commands/add.ts +1 -1
  291. package/src/commands/admin.ts +6 -6
  292. package/src/commands/adopt.ts +1 -1
  293. package/src/commands/app.ts +2 -2
  294. package/src/commands/cache.ts +3 -3
  295. package/src/commands/db.ts +9 -9
  296. package/src/commands/deploy.ts +12 -12
  297. package/src/commands/dev.ts +19 -19
  298. package/src/commands/doctor.ts +3 -3
  299. package/src/commands/engine.ts +1 -1
  300. package/src/commands/functions.ts +5 -5
  301. package/src/commands/hooks.ts +6 -6
  302. package/src/commands/init.ts +28 -28
  303. package/src/commands/login.ts +2 -2
  304. package/src/commands/logs.ts +1 -1
  305. package/src/commands/migrate.ts +5 -5
  306. package/src/commands/pg.ts +1 -1
  307. package/src/commands/plugins.ts +1 -1
  308. package/src/commands/pull.ts +2 -2
  309. package/src/commands/push.ts +3 -3
  310. package/src/commands/self-host.ts +1 -1
  311. package/src/commands/self-update.ts +23 -73
  312. package/src/commands/status.ts +1 -1
  313. package/src/commands/update.ts +1 -1
  314. package/src/config.ts +3 -3
  315. package/src/db-preflight.ts +15 -15
  316. package/src/dev-compose.ts +27 -27
  317. package/src/dev-log-filter.ts +1 -1
  318. package/src/dev-ports.ts +3 -3
  319. package/src/dev-session.ts +6 -6
  320. package/src/dev-shutdown.ts +8 -8
  321. package/src/dev-task-colors.ts +1 -1
  322. package/src/docker-postgres.ts +6 -6
  323. package/src/docker-runtime.ts +5 -5
  324. package/src/engine-client.ts +3 -3
  325. package/src/engine-push-output.ts +1 -1
  326. package/src/ensure-binary.ts +20 -0
  327. package/src/ensure-component-binaries.ts +1 -1
  328. package/src/env-file.ts +2 -2
  329. package/src/field-masking-tier.ts +6 -6
  330. package/src/functions-deno-types.ts +3 -3
  331. package/src/functions-router-gen.ts +1 -1
  332. package/src/gitignore.ts +3 -3
  333. package/src/hook-upload.ts +3 -3
  334. package/src/hooks-generator.ts +9 -9
  335. package/src/index.ts +1 -1
  336. package/src/init-project-detect.ts +1 -1
  337. package/src/link.ts +1 -1
  338. package/src/local-secrets.ts +5 -5
  339. package/src/main.ts +20 -0
  340. package/src/model-hooks.ts +4 -4
  341. package/src/pgbouncer-userlist.ts +2 -2
  342. package/src/postgres-ctl.ts +4 -4
  343. package/src/process-manager.ts +4 -4
  344. package/src/project-config.ts +16 -16
  345. package/src/pull-utils.ts +4 -4
  346. package/src/realtime-launch.ts +1 -1
  347. package/src/release-pins.ts +2 -2
  348. package/src/resolve-api-url.ts +1 -1
  349. package/src/resolve-target.ts +1 -1
  350. package/src/rest-cache-admin.ts +2 -2
  351. package/src/runtime-routes.ts +2 -2
  352. package/src/schema-ast-v2.ts +4 -4
  353. package/src/schema-push-lock.ts +3 -3
  354. package/src/scripts/postinstall.ts +1 -1
  355. package/src/self-host-compose.ts +25 -25
  356. package/src/service-role-check.ts +3 -3
  357. package/src/storage-provision.ts +3 -3
  358. package/src/studio-dev-server.ts +1 -1
  359. package/src/systemd.ts +1 -1
  360. package/src/target-client.ts +1 -1
  361. package/src/tsx-runner.ts +1 -1
  362. package/src/type-extractor.ts +27 -27
  363. package/src/type-resolver.ts +1 -1
  364. package/src/ui/README.md +1 -1
  365. package/src/ui/brand.ts +1 -1
  366. package/src/ui/components/LogoWordmark.tsx +1 -1
  367. package/src/ui/components/SelectField.tsx +1 -1
  368. package/src/ui/confirm.ts +1 -1
  369. package/src/ui/fatal.ts +1 -1
  370. package/src/ui/flows/prompt-fields.tsx +1 -1
  371. package/src/ui/interactive.ts +1 -1
  372. package/src/ui/progress.ts +1 -1
  373. package/src/ui/runtime/command-chrome.ts +1 -1
  374. package/src/ui/runtime/run-clack-flow.tsx +1 -1
  375. package/src/ui/runtime/stdin-after-ink.ts +1 -1
  376. package/src/ui/theme.ts +1 -1
  377. package/src/valkey-sidecar.ts +2 -2
  378. package/tests/access-composition.test.ts +6 -6
  379. package/tests/admin-studio-membership.test.ts +1 -1
  380. package/tests/api-schemas.test.ts +1 -1
  381. package/tests/archive-name-alias.test.ts +1 -1
  382. package/tests/cli-help.test.ts +8 -2
  383. package/tests/db-preflight.test.ts +1 -1
  384. package/tests/doctor-render.test.ts +3 -3
  385. package/tests/doctor-service-role.test.ts +2 -2
  386. package/tests/engine-push-output.test.ts +1 -1
  387. package/tests/env-file.test.ts +3 -3
  388. package/tests/external-database-compose.test.ts +5 -5
  389. package/tests/external-database-config.test.ts +2 -2
  390. package/tests/field-masking-tier.test.ts +1 -1
  391. package/tests/homebrew-formula.test.ts +68 -26
  392. package/tests/hook-upload.test.ts +1 -1
  393. package/tests/hooks-generator.test.ts +1 -1
  394. package/tests/init.test.ts +2 -2
  395. package/tests/keys.test.ts +8 -2
  396. package/tests/local-secrets.test.ts +3 -3
  397. package/tests/model-hooks.test.ts +6 -6
  398. package/tests/runtime-contract.test.ts +2 -2
  399. package/tests/service-role-check.test.ts +3 -3
  400. package/tests/storage-provision.test.ts +1 -1
  401. package/tests/type-extractor.test.ts +2 -2
  402. package/tsconfig.tsbuildinfo +1 -1
  403. package/vitest.config.ts +7 -1
  404. package/scripts/build-release-bundle.mjs +0 -27
@@ -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
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Progress UI for one-shot commands Ink spinner inside command chrome.
2
+ * Progress UI for one-shot commands, Ink spinner inside command chrome.
3
3
  */
4
4
 
5
5
  import { getActiveFlowApi } from "./runtime/flow-session.js"
@@ -89,7 +89,7 @@ export function isCommandChromeActive(): boolean {
89
89
  return getActiveFlowApi() !== null
90
90
  }
91
91
 
92
- /** Commands that mount their own Ink UI do not wrap with command chrome. */
92
+ /** Commands that mount their own Ink UI, do not wrap with command chrome. */
93
93
  const WIZARD_COMMAND_PATHS = new Set(["dev", "init", "link", "login", "_postinstall"])
94
94
 
95
95
  /** Prefixes for subcommands that call `runClackFlow` internally. */
@@ -55,7 +55,7 @@ function teardownInk(instance: Instance): void {
55
55
  try {
56
56
  instance.clear()
57
57
  } catch {
58
- // ignore terminal may already be reset
58
+ // ignore: terminal may already be reset
59
59
  }
60
60
  instance.unmount()
61
61
  instance.cleanup()
@@ -10,7 +10,7 @@ export function restoreStdinAfterInk(): void {
10
10
  try {
11
11
  if (stdin.isRaw) stdin.setRawMode?.(false)
12
12
  } catch {
13
- // ignore stdin may already be restored
13
+ // ignore: stdin may already be restored
14
14
  }
15
15
 
16
16
  // Pause so one-shot Ink flows (cache list, keys, …) can exit; resume() would keep the
package/src/ui/theme.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Supatype terminal design tokens shared by Ink components and plain CI output.
2
+ * Supatype terminal design tokens, shared by Ink components and plain CI output.
3
3
  */
4
4
 
5
5
  export const RESET = "\x1b[0m"
@@ -100,7 +100,7 @@ export function ensureValkeySidecar(projectName: string): ValkeySidecarResult {
100
100
  sleepMs(100)
101
101
  }
102
102
 
103
- console.warn("[supatype] ⚠ Valkey sidecar started but not reachable yet cache may bypass initially.")
103
+ console.warn("[supatype] ⚠ Valkey sidecar started but not reachable yet, cache may bypass initially.")
104
104
  return { addr, containerName: name, started: true }
105
105
  }
106
106
 
@@ -109,7 +109,7 @@ export function stopValkeySidecar(containerName: string | null): void {
109
109
  spawnSync("docker", ["rm", "-f", containerName], { stdio: "ignore" })
110
110
  }
111
111
 
112
- /** @internal Test helper probe without subprocess. */
112
+ /** @internal Test helper: probe without subprocess. */
113
113
  export function probeTcp(host: string, port: number): Promise<boolean> {
114
114
  return new Promise((resolve) => {
115
115
  const s = createConnection({ host, port })
@@ -24,7 +24,7 @@ function access(model: ModelAstV2 | undefined): Record<string, unknown> {
24
24
  }
25
25
 
26
26
  // Without OR-composition the rule set is a closed list of single shapes, and the
27
- // commonest real requirement "an admin, or the owner" cannot be written at all.
27
+ // commonest real requirement: "an admin, or the owner", cannot be written at all.
28
28
  describe("Any<[…]>", () => {
29
29
  it("composes rules into an OR-join", () => {
30
30
  const post = extract(
@@ -81,7 +81,7 @@ export type Post = Model<{
81
81
  })
82
82
 
83
83
  // An empty list reads like a grant and compiles to a policy that grants
84
- // nothing exactly the silent denial the unknown-rule error exists to prevent.
84
+ // nothing: exactly the silent denial the unknown-rule error exists to prevent.
85
85
  it("rejects an empty list", () => {
86
86
  expect(() =>
87
87
  extract(
@@ -350,7 +350,7 @@ export type Post = Model<{ id: UUID }, { access: { read: In<"a", Rows<"a b; drop
350
350
  })
351
351
 
352
352
  // The plan's headline parameterisation: the type-level equivalent of Payload's
353
- // access-control factory. Before this, any named alias even unparameterised
353
+ // access-control factory. Before this, any named alias, even unparameterised,
354
354
  // was reported as an unknown rule and had to be written inline at every use.
355
355
  describe("parameterised rule aliases", () => {
356
356
  it("expands a generic alias at the point of use", () => {
@@ -480,7 +480,7 @@ export type Post = Model<{ id: UUID }, { access: { update: { using: Public; wat:
480
480
  })
481
481
 
482
482
 
483
- // "Publish at 09:00 next Tuesday" is *data* the row carries `published_at` and the
483
+ // "Publish at 09:00 next Tuesday" is *data*, the row carries `published_at` and the
484
484
  // rule is the same for every row. There is deliberately no literal-timestamp
485
485
  // operand; the policy re-evaluates per query, so the row starts matching at 09:00
486
486
  // with no cron and no publish worker.
@@ -589,7 +589,7 @@ export type Post = Model<{ id: UUID }, { access: { read: Gte<"a", Ago<${n}, "day
589
589
  `
590
590
  expect(() => extract(bad("0.5"), "ago-frac")).toThrow(/whole number/)
591
591
  // A negative literal is a prefix-unary expression, not a numeric literal, so it
592
- // needs its own branch otherwise the message misses the real advice.
592
+ // needs its own branch, otherwise the message misses the real advice.
593
593
  expect(() => extract(bad("-5"), "ago-neg")).toThrow(/does not take a negative amount/)
594
594
  })
595
595
 
@@ -619,7 +619,7 @@ export type Post = Model<{ id: UUID }, { access: { read: Gte<"a", StartOf<"fortn
619
619
  })
620
620
 
621
621
  // `In<>` asks "is this row's value in the set". Payload's site-access rule guards on
622
- // `user.sites?.length > 0` first without that, an editor with no sites still
622
+ // `user.sites?.length > 0` first, without that, an editor with no sites still
623
623
  // matches the unassigned-rows branch.
624
624
  describe("Exists<> non-empty guard", () => {
625
625
  it("expresses the Payload site-access rule in full", () => {
@@ -68,7 +68,7 @@ async function seedFirstAdmin(): Promise<Recorded[]> {
68
68
 
69
69
  // Capability checks refuse a role they do not recognise, so the CLI's set has to
70
70
  // match the server's (`studioRolePermissions`) and the control plane's
71
- // (`STUDIO_ROLE_PERMISSIONS`) exactly a role only this side knows about creates
71
+ // (`STUDIO_ROLE_PERMISSIONS`) exactly: a role only this side knows about creates
72
72
  // a user who is locked out of the panel they were made for.
73
73
  describe("STUDIO_ROLES", () => {
74
74
  it("matches the roles the servers understand", () => {
@@ -42,7 +42,7 @@ describe("apiSchemas", () => {
42
42
 
43
43
  it("leads with the managed schema when pg_schema moves", () => {
44
44
  // First entry is what PostgREST serves as the default profile, so the managed schema has to
45
- // lead otherwise unprefixed requests would resolve against `supatype`.
45
+ // lead: otherwise unprefixed requests would resolve against `supatype`.
46
46
  expect(apiSchemaList(project({ pg_schema: "app" }))).toBe(
47
47
  "app, supatype, graphql_public, auth",
48
48
  )
@@ -4,7 +4,7 @@ import { archiveNameCandidates } from "../src/binary-cache.js"
4
4
 
5
5
  /**
6
6
  * `supatype-postgres` published the Intel macOS archive as `darwin-x86_64` while the CLI asks for
7
- * `darwin-amd64` the spelling it derives from `process.arch === "x64"` on every platform. So
7
+ * `darwin-amd64`: the spelling it derives from `process.arch === "x64"` on every platform. So
8
8
  * `supatype dev` on an Intel Mac failed with "Checksum not found", and had done for as long as both
9
9
  * sides existed: CI could not run Docker on a macOS runner, so the path was never exercised.
10
10
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Subprocess tests spawn the compiled CLI binary and verify commands are
2
+ * Subprocess tests: spawn the compiled CLI binary and verify commands are
3
3
  * registered. Requires `pnpm build` to have run first (turbo handles this).
4
4
  */
5
5
  import { describe, it, expect } from "vitest"
@@ -17,8 +17,14 @@ const PACKAGE_VERSION = (
17
17
  function runCli(args: string[]): { stdout: string; stderr: string; exitCode: number } {
18
18
  const result = spawnSync(process.execPath, [CLI_BIN, ...args], {
19
19
  encoding: "utf8",
20
- timeout: 10_000,
20
+ timeout: 60_000,
21
21
  })
22
+ if (result.signal) {
23
+ throw new Error(
24
+ `CLI subprocess killed by ${result.signal} after the spawn timeout. `
25
+ + `Args: ${args.join(" ")}. This is usually machine contention, not a CLI fault.`,
26
+ )
27
+ }
22
28
  return {
23
29
  stdout: String(result.stdout ?? ""),
24
30
  stderr: String(result.stderr ?? ""),
@@ -44,7 +44,7 @@ describe("splitting remedies", () => {
44
44
 
45
45
  describe("the authenticator password guard", () => {
46
46
  // The credential is the operator's by decision. Executing the placeholder would create a role
47
- // with a password from our source code worse than refusing, and harder to notice.
47
+ // with a password from our source code, worse than refusing, and harder to notice.
48
48
  it("detects a remedy that would execute the placeholder", () => {
49
49
  const remedies = [
50
50
  result({ remedy: `CREATE ROLE authenticator LOGIN NOINHERIT PASSWORD '${PASSWORD_PLACEHOLDER}';` }),
@@ -5,7 +5,7 @@ import { printSection } from "../src/commands/doctor.js"
5
5
  * How a drift item reads to the operator.
6
6
  *
7
7
  * Items are keyed `table` + `name`, which for an index or constraint are different things and for a
8
- * *table* are the same so the natural `table.name` form printed "widget.widget". Tables only
8
+ * *table* are the same, so the natural `table.name` form printed "widget.widget". Tables only
9
9
  * started appearing in this report when the ownership gate got its reporting (E17), and a report an
10
10
  * operator distrusts is worse than no report.
11
11
  */
@@ -30,7 +30,7 @@ describe("printSection", () => {
30
30
  table: "widget",
31
31
  name: "widget",
32
32
  fields: [],
33
- message: "Unmanaged table widget push will not drop; manual decision required",
33
+ message: "Unmanaged table widget, push will not drop; manual decision required",
34
34
  },
35
35
  ])
36
36
  const text = captured.join("\n")
@@ -48,7 +48,7 @@ describe("printSection", () => {
48
48
  table: "widget",
49
49
  name: "widget_name_idx",
50
50
  fields: ["name"],
51
- message: "Unmanaged index widget_name_idx on widget push will not drop",
51
+ message: "Unmanaged index widget_name_idx on widget, push will not drop",
52
52
  },
53
53
  ])
54
54
  expect(captured.join("\n")).toContain("• widget.widget_name_idx (name)")
@@ -36,7 +36,7 @@ describe("printServiceRoleGrants", () => {
36
36
 
37
37
  it("marks a grant that matches no function", () => {
38
38
  printServiceRoleGrants(
39
- { ...empty, errors: [' "send-emial" no functions/send-emial/index.ts'], missing: ["send-emial"] },
39
+ { ...empty, errors: [' "send-emial", no functions/send-emial/index.ts'], missing: ["send-emial"] },
40
40
  ["send-emial", "audit"],
41
41
  )
42
42
  const out = lines.join("\n")
@@ -47,7 +47,7 @@ describe("printServiceRoleGrants", () => {
47
47
 
48
48
  it("passes a redundant-entry warning through", () => {
49
49
  printServiceRoleGrants(
50
- { ...empty, warnings: [' "hooks/x" is not needed a hook receives the key'] },
50
+ { ...empty, warnings: [' "hooks/x" is not needed, a hook receives the key'] },
51
51
  ["hooks/x"],
52
52
  )
53
53
  expect(lines.join("\n")).toContain("is not needed")
@@ -38,7 +38,7 @@ describe("formatEnginePushMessage()", () => {
38
38
  it("formats up_to_date with admin refresh", () => {
39
39
  expect(
40
40
  formatEnginePushMessage({ status: "up_to_date", operations: 0, admin_refreshed: true }),
41
- ).toBe("Schema up to date Studio metadata synced.")
41
+ ).toBe("Schema up to date, Studio metadata synced.")
42
42
  })
43
43
 
44
44
  it("formats up_to_date without admin refresh", () => {
@@ -10,7 +10,7 @@ import { MANAGED_MARKER, readEnvFile, upsertEnvFile } from "../src/env-file.js"
10
10
  * Two defects motivated this: the rewrite rebuilt the file from its assignments alone, so every
11
11
  * comment and blank line vanished; and the image keys derivable from `versions` were deleted
12
12
  * unconditionally, so `SUPATYPE_REALTIME_IMAGE` could be overridden from `.env` and
13
- * `SUPATYPE_SERVER_IMAGE` could not. Same file, same shape, different rules which is how an hour
13
+ * `SUPATYPE_SERVER_IMAGE` could not. Same file, same shape, different rules, which is how an hour
14
14
  * goes into wondering why a locally built image is ignored.
15
15
  */
16
16
  let dir: string
@@ -63,7 +63,7 @@ JWT_SECRET=abc
63
63
 
64
64
  it("does clean up a value it wrote itself", () => {
65
65
  // Otherwise removing a pin from config leaves a stale image reference that silently keeps
66
- // running the old version the reason the deletion existed at all.
66
+ // running the old version, the reason the deletion existed at all.
67
67
  upsertEnvFile(
68
68
  dir,
69
69
  { SUPATYPE_SERVER_IMAGE: "supatype/server:v1.2.3" },
@@ -112,7 +112,7 @@ JWT_SECRET=abc
112
112
  })
113
113
 
114
114
  it("does not treat a commented-out assignment as a value", () => {
115
- // `# FOO=bar` is a note, not a setting the old parser kept it as a key called "# FOO".
115
+ // `# FOO=bar` is a note, not a setting, the old parser kept it as a key called "# FOO".
116
116
  write("# FOO=bar\nREAL=1\n")
117
117
  upsertEnvFile(dir, { REAL: "2" })
118
118
  expect(read()).toContain("# FOO=bar")
@@ -30,7 +30,7 @@ const project = (database: unknown): SupatypeProjectConfig =>
30
30
  const external = (url = EXTERNAL_URL) => project({ external: { url } })
31
31
  const managed = () => project({ provider: "docker" })
32
32
 
33
- describe("external database compose", () => {
33
+ describe("external database: compose", () => {
34
34
  it("omits the db service and says why", () => {
35
35
  const compose = renderSelfHostCompose(external())
36
36
  expect(compose).not.toMatch(/^ {2}db:$/m)
@@ -88,12 +88,12 @@ describe("external database — compose", () => {
88
88
  it("appends GoTrue's search_path with the right separator", () => {
89
89
  // A URL that already has a query string needs `&`; a second `?` produces a DSN that fails to
90
90
  // parse, and GoTrue would exit rather than run its auth migrations.
91
- expect(renderSelfHostCompose(external())).toContain('${DATABASE_URL:?DATABASE_URL is missing from .env required by database.external}?search_path=auth"')
91
+ expect(renderSelfHostCompose(external())).toContain('${DATABASE_URL:?DATABASE_URL is missing from .env, required by database.external}?search_path=auth"')
92
92
  expect(
93
93
  renderSelfHostCompose(
94
94
  external("postgres://owner:secret@db.example.com:5432/app?sslmode=require"),
95
95
  ),
96
- ).toContain('${DATABASE_URL:?DATABASE_URL is missing from .env required by database.external}&search_path=auth"')
96
+ ).toContain('${DATABASE_URL:?DATABASE_URL is missing from .env, required by database.external}&search_path=auth"')
97
97
  })
98
98
 
99
99
  it("omits realtime entirely when the project turns it off", () => {
@@ -109,7 +109,7 @@ describe("external database — compose", () => {
109
109
  })
110
110
 
111
111
  it("keeps realtime when the flag is unset", () => {
112
- // Unset means "probe it", not "assume it is broken" the service reports its own capability.
112
+ // Unset means "probe it", not "assume it is broken", the service reports its own capability.
113
113
  const compose = renderSelfHostCompose(external())
114
114
  expect(compose).toMatch(/^ {2}realtime:$/m)
115
115
  expect(compose).toContain("SUPATYPE_REALTIME_URL: http://realtime:4000")
@@ -157,7 +157,7 @@ describe("external database — compose", () => {
157
157
 
158
158
  describe("a loopback external URL", () => {
159
159
  // Found by rehearsing a push against a real external Postgres: `db check` passed and `push`
160
- // applied the schema, because the CLI runs on the host then storage, realtime and the server all
160
+ // applied the schema, because the CLI runs on the host, then storage, realtime and the server all
161
161
  // died with ECONNREFUSED against their own loopback, because inside a container `127.0.0.1` is
162
162
  // that container. A retry loop would only have hidden it.
163
163
  it("is detected, whatever form it takes", () => {
@@ -28,7 +28,7 @@ const raw = (database: unknown, rest: Record<string, unknown> = {}): unknown =>
28
28
  const validate = (database: unknown, rest?: Record<string, unknown>) =>
29
29
  validateProjectConfig(raw(database, rest), "supatype.config.ts")
30
30
 
31
- describe("database.external accepted", () => {
31
+ describe("database.external: accepted", () => {
32
32
  it("accepts a url on its own, with no database.provider", () => {
33
33
  const cfg = validate({ external: { url: EXTERNAL_URL } })
34
34
  expect(externalDatabaseUrl(cfg)).toBe(EXTERNAL_URL)
@@ -52,7 +52,7 @@ describe("database.external — accepted", () => {
52
52
  })
53
53
  })
54
54
 
55
- describe("database.external rejected", () => {
55
+ describe("database.external: rejected", () => {
56
56
  it("rejects a missing url", () => {
57
57
  expect(() => validate({ external: {} })).toThrow(/database\.external\.url is required/)
58
58
  expect(() => validate({ external: { url: " " } })).toThrow(