@supatype/cli 0.1.0-alpha.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 (416) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test.log +221 -0
  3. package/.turbo/turbo-typecheck.log +4 -0
  4. package/assets/supatype-logo-wordmark.ascii.txt +6 -0
  5. package/bin/dev-entry.ts +2 -0
  6. package/bin/supatype.js +5 -0
  7. package/dist/app/framework.d.ts +44 -0
  8. package/dist/app/framework.d.ts.map +1 -0
  9. package/dist/app/framework.js +200 -0
  10. package/dist/app/framework.js.map +1 -0
  11. package/dist/app/proxy-dev-app.d.ts +13 -0
  12. package/dist/app/proxy-dev-app.d.ts.map +1 -0
  13. package/dist/app/proxy-dev-app.js +54 -0
  14. package/dist/app/proxy-dev-app.js.map +1 -0
  15. package/dist/app-config.d.ts +7 -0
  16. package/dist/app-config.d.ts.map +1 -0
  17. package/dist/app-config.js +113 -0
  18. package/dist/app-config.js.map +1 -0
  19. package/dist/assets/supatype-logo-wordmark.ascii.txt +6 -0
  20. package/dist/augmentation-generator.d.ts +2 -0
  21. package/dist/augmentation-generator.d.ts.map +1 -0
  22. package/dist/augmentation-generator.js +111 -0
  23. package/dist/augmentation-generator.js.map +1 -0
  24. package/dist/binary-cache.d.ts +98 -0
  25. package/dist/binary-cache.d.ts.map +1 -0
  26. package/dist/binary-cache.js +687 -0
  27. package/dist/binary-cache.js.map +1 -0
  28. package/dist/cli.d.ts +2 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +61 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/commands/admin.d.ts +4 -0
  33. package/dist/commands/admin.d.ts.map +1 -0
  34. package/dist/commands/admin.js +271 -0
  35. package/dist/commands/admin.js.map +1 -0
  36. package/dist/commands/app.d.ts +3 -0
  37. package/dist/commands/app.d.ts.map +1 -0
  38. package/dist/commands/app.js +82 -0
  39. package/dist/commands/app.js.map +1 -0
  40. package/dist/commands/cache.d.ts +6 -0
  41. package/dist/commands/cache.d.ts.map +1 -0
  42. package/dist/commands/cache.js +105 -0
  43. package/dist/commands/cache.js.map +1 -0
  44. package/dist/commands/cloud.d.ts +23 -0
  45. package/dist/commands/cloud.d.ts.map +1 -0
  46. package/dist/commands/cloud.js +254 -0
  47. package/dist/commands/cloud.js.map +1 -0
  48. package/dist/commands/db.d.ts +8 -0
  49. package/dist/commands/db.d.ts.map +1 -0
  50. package/dist/commands/db.js +116 -0
  51. package/dist/commands/db.js.map +1 -0
  52. package/dist/commands/deploy-types.d.ts +14 -0
  53. package/dist/commands/deploy-types.d.ts.map +1 -0
  54. package/dist/commands/deploy-types.js +38 -0
  55. package/dist/commands/deploy-types.js.map +1 -0
  56. package/dist/commands/deploy.d.ts +15 -0
  57. package/dist/commands/deploy.d.ts.map +1 -0
  58. package/dist/commands/deploy.js +322 -0
  59. package/dist/commands/deploy.js.map +1 -0
  60. package/dist/commands/dev.d.ts +14 -0
  61. package/dist/commands/dev.d.ts.map +1 -0
  62. package/dist/commands/dev.js +806 -0
  63. package/dist/commands/dev.js.map +1 -0
  64. package/dist/commands/diff.d.ts +3 -0
  65. package/dist/commands/diff.d.ts.map +1 -0
  66. package/dist/commands/diff.js +54 -0
  67. package/dist/commands/diff.js.map +1 -0
  68. package/dist/commands/engine.d.ts +7 -0
  69. package/dist/commands/engine.d.ts.map +1 -0
  70. package/dist/commands/engine.js +27 -0
  71. package/dist/commands/engine.js.map +1 -0
  72. package/dist/commands/functions.d.ts +3 -0
  73. package/dist/commands/functions.d.ts.map +1 -0
  74. package/dist/commands/functions.js +749 -0
  75. package/dist/commands/functions.js.map +1 -0
  76. package/dist/commands/generate.d.ts +3 -0
  77. package/dist/commands/generate.d.ts.map +1 -0
  78. package/dist/commands/generate.js +38 -0
  79. package/dist/commands/generate.js.map +1 -0
  80. package/dist/commands/init.d.ts +7 -0
  81. package/dist/commands/init.d.ts.map +1 -0
  82. package/dist/commands/init.js +228 -0
  83. package/dist/commands/init.js.map +1 -0
  84. package/dist/commands/keys.d.ts +4 -0
  85. package/dist/commands/keys.d.ts.map +1 -0
  86. package/dist/commands/keys.js +57 -0
  87. package/dist/commands/keys.js.map +1 -0
  88. package/dist/commands/logs.d.ts +6 -0
  89. package/dist/commands/logs.d.ts.map +1 -0
  90. package/dist/commands/logs.js +52 -0
  91. package/dist/commands/logs.js.map +1 -0
  92. package/dist/commands/migrate-from-v1.d.ts +5 -0
  93. package/dist/commands/migrate-from-v1.d.ts.map +1 -0
  94. package/dist/commands/migrate-from-v1.js +125 -0
  95. package/dist/commands/migrate-from-v1.js.map +1 -0
  96. package/dist/commands/migrate.d.ts +3 -0
  97. package/dist/commands/migrate.d.ts.map +1 -0
  98. package/dist/commands/migrate.js +75 -0
  99. package/dist/commands/migrate.js.map +1 -0
  100. package/dist/commands/pg.d.ts +8 -0
  101. package/dist/commands/pg.d.ts.map +1 -0
  102. package/dist/commands/pg.js +102 -0
  103. package/dist/commands/pg.js.map +1 -0
  104. package/dist/commands/plugins.d.ts +3 -0
  105. package/dist/commands/plugins.d.ts.map +1 -0
  106. package/dist/commands/plugins.js +431 -0
  107. package/dist/commands/plugins.js.map +1 -0
  108. package/dist/commands/pull.d.ts +3 -0
  109. package/dist/commands/pull.d.ts.map +1 -0
  110. package/dist/commands/pull.js +12 -0
  111. package/dist/commands/pull.js.map +1 -0
  112. package/dist/commands/push.d.ts +3 -0
  113. package/dist/commands/push.d.ts.map +1 -0
  114. package/dist/commands/push.js +179 -0
  115. package/dist/commands/push.js.map +1 -0
  116. package/dist/commands/seed.d.ts +5 -0
  117. package/dist/commands/seed.d.ts.map +1 -0
  118. package/dist/commands/seed.js +55 -0
  119. package/dist/commands/seed.js.map +1 -0
  120. package/dist/commands/self-host.d.ts +9 -0
  121. package/dist/commands/self-host.d.ts.map +1 -0
  122. package/dist/commands/self-host.js +310 -0
  123. package/dist/commands/self-host.js.map +1 -0
  124. package/dist/commands/self-update.d.ts +9 -0
  125. package/dist/commands/self-update.d.ts.map +1 -0
  126. package/dist/commands/self-update.js +33 -0
  127. package/dist/commands/self-update.js.map +1 -0
  128. package/dist/commands/status.d.ts +6 -0
  129. package/dist/commands/status.d.ts.map +1 -0
  130. package/dist/commands/status.js +70 -0
  131. package/dist/commands/status.js.map +1 -0
  132. package/dist/commands/types.d.ts +3 -0
  133. package/dist/commands/types.d.ts.map +1 -0
  134. package/dist/commands/types.js +62 -0
  135. package/dist/commands/types.js.map +1 -0
  136. package/dist/commands/update.d.ts +7 -0
  137. package/dist/commands/update.d.ts.map +1 -0
  138. package/dist/commands/update.js +118 -0
  139. package/dist/commands/update.js.map +1 -0
  140. package/dist/components.d.ts +5 -0
  141. package/dist/components.d.ts.map +1 -0
  142. package/dist/components.js +3 -0
  143. package/dist/components.js.map +1 -0
  144. package/dist/config.d.ts +65 -0
  145. package/dist/config.d.ts.map +1 -0
  146. package/dist/config.js +134 -0
  147. package/dist/config.js.map +1 -0
  148. package/dist/dev-compose.d.ts +19 -0
  149. package/dist/dev-compose.d.ts.map +1 -0
  150. package/dist/dev-compose.js +468 -0
  151. package/dist/dev-compose.js.map +1 -0
  152. package/dist/dev-log-bus.d.ts +30 -0
  153. package/dist/dev-log-bus.d.ts.map +1 -0
  154. package/dist/dev-log-bus.js +87 -0
  155. package/dist/dev-log-bus.js.map +1 -0
  156. package/dist/dev-log-filter.d.ts +10 -0
  157. package/dist/dev-log-filter.d.ts.map +1 -0
  158. package/dist/dev-log-filter.js +36 -0
  159. package/dist/dev-log-filter.js.map +1 -0
  160. package/dist/dev-logo.d.ts +12 -0
  161. package/dist/dev-logo.d.ts.map +1 -0
  162. package/dist/dev-logo.js +57 -0
  163. package/dist/dev-logo.js.map +1 -0
  164. package/dist/dev-session.d.ts +26 -0
  165. package/dist/dev-session.d.ts.map +1 -0
  166. package/dist/dev-session.js +106 -0
  167. package/dist/dev-session.js.map +1 -0
  168. package/dist/dev-shutdown.d.ts +9 -0
  169. package/dist/dev-shutdown.d.ts.map +1 -0
  170. package/dist/dev-shutdown.js +50 -0
  171. package/dist/dev-shutdown.js.map +1 -0
  172. package/dist/dev-task-colors.d.ts +14 -0
  173. package/dist/dev-task-colors.d.ts.map +1 -0
  174. package/dist/dev-task-colors.js +44 -0
  175. package/dist/dev-task-colors.js.map +1 -0
  176. package/dist/dev-tui.d.ts +24 -0
  177. package/dist/dev-tui.d.ts.map +1 -0
  178. package/dist/dev-tui.js +188 -0
  179. package/dist/dev-tui.js.map +1 -0
  180. package/dist/diff-output.d.ts +4 -0
  181. package/dist/diff-output.d.ts.map +1 -0
  182. package/dist/diff-output.js +12 -0
  183. package/dist/diff-output.js.map +1 -0
  184. package/dist/docker-postgres.d.ts +57 -0
  185. package/dist/docker-postgres.d.ts.map +1 -0
  186. package/dist/docker-postgres.js +208 -0
  187. package/dist/docker-postgres.js.map +1 -0
  188. package/dist/engine-client.d.ts +69 -0
  189. package/dist/engine-client.d.ts.map +1 -0
  190. package/dist/engine-client.js +157 -0
  191. package/dist/engine-client.js.map +1 -0
  192. package/dist/engine-push-output.d.ts +16 -0
  193. package/dist/engine-push-output.d.ts.map +1 -0
  194. package/dist/engine-push-output.js +61 -0
  195. package/dist/engine-push-output.js.map +1 -0
  196. package/dist/ensure-binary.d.ts +7 -0
  197. package/dist/ensure-binary.d.ts.map +1 -0
  198. package/dist/ensure-binary.js +17 -0
  199. package/dist/ensure-binary.js.map +1 -0
  200. package/dist/functions-router-gen.d.ts +14 -0
  201. package/dist/functions-router-gen.d.ts.map +1 -0
  202. package/dist/functions-router-gen.js +199 -0
  203. package/dist/functions-router-gen.js.map +1 -0
  204. package/dist/index.d.ts +11 -0
  205. package/dist/index.d.ts.map +1 -0
  206. package/dist/index.js +9 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/jwt.d.ts +3 -0
  209. package/dist/jwt.d.ts.map +1 -0
  210. package/dist/jwt.js +13 -0
  211. package/dist/jwt.js.map +1 -0
  212. package/dist/kong-config.d.ts +25 -0
  213. package/dist/kong-config.d.ts.map +1 -0
  214. package/dist/kong-config.js +71 -0
  215. package/dist/kong-config.js.map +1 -0
  216. package/dist/local-gateway.d.ts +7 -0
  217. package/dist/local-gateway.d.ts.map +1 -0
  218. package/dist/local-gateway.js +9 -0
  219. package/dist/local-gateway.js.map +1 -0
  220. package/dist/local-storage.d.ts +8 -0
  221. package/dist/local-storage.d.ts.map +1 -0
  222. package/dist/local-storage.js +14 -0
  223. package/dist/local-storage.js.map +1 -0
  224. package/dist/pgbouncer-userlist.d.ts +5 -0
  225. package/dist/pgbouncer-userlist.d.ts.map +1 -0
  226. package/dist/pgbouncer-userlist.js +14 -0
  227. package/dist/pgbouncer-userlist.js.map +1 -0
  228. package/dist/postgres-ctl.d.ts +44 -0
  229. package/dist/postgres-ctl.d.ts.map +1 -0
  230. package/dist/postgres-ctl.js +137 -0
  231. package/dist/postgres-ctl.js.map +1 -0
  232. package/dist/process-manager.d.ts +49 -0
  233. package/dist/process-manager.d.ts.map +1 -0
  234. package/dist/process-manager.js +177 -0
  235. package/dist/process-manager.js.map +1 -0
  236. package/dist/project-config.d.ts +238 -0
  237. package/dist/project-config.d.ts.map +1 -0
  238. package/dist/project-config.js +159 -0
  239. package/dist/project-config.js.map +1 -0
  240. package/dist/pull-utils.d.ts +31 -0
  241. package/dist/pull-utils.d.ts.map +1 -0
  242. package/dist/pull-utils.js +77 -0
  243. package/dist/pull-utils.js.map +1 -0
  244. package/dist/release-pins.d.ts +7 -0
  245. package/dist/release-pins.d.ts.map +1 -0
  246. package/dist/release-pins.js +27 -0
  247. package/dist/release-pins.js.map +1 -0
  248. package/dist/release-public-key.d.ts +8 -0
  249. package/dist/release-public-key.d.ts.map +1 -0
  250. package/dist/release-public-key.js +13 -0
  251. package/dist/release-public-key.js.map +1 -0
  252. package/dist/restore-system-relation-targets.d.ts +3 -0
  253. package/dist/restore-system-relation-targets.d.ts.map +1 -0
  254. package/dist/restore-system-relation-targets.js +45 -0
  255. package/dist/restore-system-relation-targets.js.map +1 -0
  256. package/dist/runtime-routes.d.ts +34 -0
  257. package/dist/runtime-routes.d.ts.map +1 -0
  258. package/dist/runtime-routes.js +252 -0
  259. package/dist/runtime-routes.js.map +1 -0
  260. package/dist/schema-ast-v2.d.ts +127 -0
  261. package/dist/schema-ast-v2.d.ts.map +1 -0
  262. package/dist/schema-ast-v2.js +226 -0
  263. package/dist/schema-ast-v2.js.map +1 -0
  264. package/dist/scripts/postinstall.d.ts +11 -0
  265. package/dist/scripts/postinstall.d.ts.map +1 -0
  266. package/dist/scripts/postinstall.js +47 -0
  267. package/dist/scripts/postinstall.js.map +1 -0
  268. package/dist/seed.d.ts +8 -0
  269. package/dist/seed.d.ts.map +1 -0
  270. package/dist/seed.js +32 -0
  271. package/dist/seed.js.map +1 -0
  272. package/dist/self-host-compose.d.ts +43 -0
  273. package/dist/self-host-compose.d.ts.map +1 -0
  274. package/dist/self-host-compose.js +400 -0
  275. package/dist/self-host-compose.js.map +1 -0
  276. package/dist/storage-provision.d.ts +24 -0
  277. package/dist/storage-provision.d.ts.map +1 -0
  278. package/dist/storage-provision.js +44 -0
  279. package/dist/storage-provision.js.map +1 -0
  280. package/dist/studio-admin-roles.d.ts +7 -0
  281. package/dist/studio-admin-roles.d.ts.map +1 -0
  282. package/dist/studio-admin-roles.js +14 -0
  283. package/dist/studio-admin-roles.js.map +1 -0
  284. package/dist/studio-dev-server.d.ts +22 -0
  285. package/dist/studio-dev-server.d.ts.map +1 -0
  286. package/dist/studio-dev-server.js +28 -0
  287. package/dist/studio-dev-server.js.map +1 -0
  288. package/dist/supatype-eval-1781522769253.d.mts +2 -0
  289. package/dist/supatype-eval-1781522769253.d.mts.map +1 -0
  290. package/dist/supatype-eval-1781522769253.mjs +3 -0
  291. package/dist/supatype-eval-1781522769253.mjs.map +1 -0
  292. package/dist/systemd.d.ts +26 -0
  293. package/dist/systemd.d.ts.map +1 -0
  294. package/dist/systemd.js +102 -0
  295. package/dist/systemd.js.map +1 -0
  296. package/dist/tsx-runner.d.ts +18 -0
  297. package/dist/tsx-runner.d.ts.map +1 -0
  298. package/dist/tsx-runner.js +69 -0
  299. package/dist/tsx-runner.js.map +1 -0
  300. package/dist/type-extractor.d.ts +4 -0
  301. package/dist/type-extractor.d.ts.map +1 -0
  302. package/dist/type-extractor.js +1213 -0
  303. package/dist/type-extractor.js.map +1 -0
  304. package/dist/type-resolver.d.ts +33 -0
  305. package/dist/type-resolver.d.ts.map +1 -0
  306. package/dist/type-resolver.js +338 -0
  307. package/dist/type-resolver.js.map +1 -0
  308. package/package.json +41 -0
  309. package/releases/deno/VERSION +1 -0
  310. package/scripts/mirror-deno-release.sh +76 -0
  311. package/src/TYPE-RESOLUTION.md +294 -0
  312. package/src/app/framework.ts +249 -0
  313. package/src/app/proxy-dev-app.ts +68 -0
  314. package/src/app-config.ts +128 -0
  315. package/src/augmentation-generator.ts +126 -0
  316. package/src/binary-cache.ts +845 -0
  317. package/src/cli.ts +63 -0
  318. package/src/commands/admin.ts +372 -0
  319. package/src/commands/app.ts +97 -0
  320. package/src/commands/cache.ts +117 -0
  321. package/src/commands/cloud.ts +325 -0
  322. package/src/commands/db.ts +136 -0
  323. package/src/commands/deploy-types.ts +49 -0
  324. package/src/commands/deploy.ts +400 -0
  325. package/src/commands/dev.ts +1009 -0
  326. package/src/commands/diff.ts +63 -0
  327. package/src/commands/engine.ts +30 -0
  328. package/src/commands/functions.ts +901 -0
  329. package/src/commands/generate.ts +44 -0
  330. package/src/commands/init.ts +253 -0
  331. package/src/commands/keys.ts +66 -0
  332. package/src/commands/logs.ts +58 -0
  333. package/src/commands/migrate-from-v1.ts +131 -0
  334. package/src/commands/migrate.ts +87 -0
  335. package/src/commands/pg.ts +133 -0
  336. package/src/commands/plugins.ts +508 -0
  337. package/src/commands/pull.ts +17 -0
  338. package/src/commands/push.ts +226 -0
  339. package/src/commands/seed.ts +68 -0
  340. package/src/commands/self-host.ts +364 -0
  341. package/src/commands/self-update.ts +45 -0
  342. package/src/commands/status.ts +84 -0
  343. package/src/commands/types.ts +76 -0
  344. package/src/commands/update.ts +136 -0
  345. package/src/components.ts +6 -0
  346. package/src/config.ts +223 -0
  347. package/src/dev-compose.ts +583 -0
  348. package/src/dev-log-bus.ts +101 -0
  349. package/src/dev-log-filter.ts +32 -0
  350. package/src/dev-logo.ts +62 -0
  351. package/src/dev-session.ts +130 -0
  352. package/src/dev-shutdown.ts +54 -0
  353. package/src/dev-task-colors.ts +47 -0
  354. package/src/dev-tui.ts +232 -0
  355. package/src/diff-output.ts +12 -0
  356. package/src/docker-postgres.ts +295 -0
  357. package/src/engine-client.ts +236 -0
  358. package/src/engine-push-output.ts +71 -0
  359. package/src/ensure-binary.ts +28 -0
  360. package/src/functions-router-gen.ts +224 -0
  361. package/src/index.ts +11 -0
  362. package/src/jwt.ts +14 -0
  363. package/src/kong-config.ts +93 -0
  364. package/src/local-gateway.ts +9 -0
  365. package/src/local-storage.ts +14 -0
  366. package/src/pgbouncer-userlist.ts +15 -0
  367. package/src/postgres-ctl.ts +171 -0
  368. package/src/process-manager.ts +220 -0
  369. package/src/project-config.ts +388 -0
  370. package/src/pull-utils.ts +81 -0
  371. package/src/release-pins.ts +31 -0
  372. package/src/release-public-key.ts +12 -0
  373. package/src/restore-system-relation-targets.ts +45 -0
  374. package/src/runtime-routes.ts +291 -0
  375. package/src/schema-ast-v2.ts +324 -0
  376. package/src/scripts/postinstall.ts +51 -0
  377. package/src/seed.ts +43 -0
  378. package/src/self-host-compose.ts +452 -0
  379. package/src/storage-provision.ts +58 -0
  380. package/src/studio-admin-roles.ts +16 -0
  381. package/src/studio-dev-server.ts +53 -0
  382. package/src/supatype-eval-1781522769253.mts +1 -0
  383. package/src/systemd.ts +137 -0
  384. package/src/tsx-runner.ts +89 -0
  385. package/src/type-extractor.ts +1479 -0
  386. package/src/type-resolver.ts +457 -0
  387. package/tests/app-command.test.ts +54 -0
  388. package/tests/augmentation-generator.test.ts +59 -0
  389. package/tests/binary-cache-cloud-overrides.test.ts +123 -0
  390. package/tests/cached-artifact-format.test.ts +84 -0
  391. package/tests/cli-help.test.ts +133 -0
  392. package/tests/config.test.ts +252 -0
  393. package/tests/dev-ui.test.ts +139 -0
  394. package/tests/docker-postgres.test.ts +39 -0
  395. package/tests/engine-distribution.test.ts +418 -0
  396. package/tests/engine-push-output.test.ts +67 -0
  397. package/tests/ensure-binary.test.ts +59 -0
  398. package/tests/init.test.ts +127 -0
  399. package/tests/keys.test.ts +160 -0
  400. package/tests/migrate-from-v1.test.ts +29 -0
  401. package/tests/normalize-admin-config.test.ts +48 -0
  402. package/tests/pg-spawn-env.test.ts +18 -0
  403. package/tests/postgres-archive-tag.test.ts +9 -0
  404. package/tests/proxy-dev-app.test.ts +33 -0
  405. package/tests/pull-utils.test.ts +150 -0
  406. package/tests/release-pins.test.ts +28 -0
  407. package/tests/runtime-contract.test.ts +370 -0
  408. package/tests/seed-discover.test.ts +31 -0
  409. package/tests/studio-admin-roles.test.ts +27 -0
  410. package/tests/tsconfig.json +9 -0
  411. package/tests/tsx-runner.test.ts +66 -0
  412. package/tests/type-extractor.test.ts +985 -0
  413. package/tests/type-resolver.test.ts +59 -0
  414. package/tsconfig.json +10 -0
  415. package/tsconfig.tsbuildinfo +1 -0
  416. package/vitest.config.ts +12 -0
@@ -0,0 +1,133 @@
1
+ /**
2
+ * supatype pg — manage the native Postgres instance for a project.
3
+ *
4
+ * Commands: start, stop, reset, psql
5
+ */
6
+
7
+ import type { Command } from "commander"
8
+ import { spawnSync } from "node:child_process"
9
+ import { existsSync, mkdirSync, rmSync } from "node:fs"
10
+ import { homedir } from "node:os"
11
+ import { join } from "node:path"
12
+ import { loadConfig } from "../config.js"
13
+ import { resolveBinary } from "../binary-cache.js"
14
+ import {
15
+ initdb,
16
+ start as pgStart,
17
+ stop as pgStop,
18
+ waitReady,
19
+ } from "../postgres-ctl.js"
20
+
21
+ export function registerPg(program: Command): void {
22
+ const pg = program
23
+ .command("pg")
24
+ .description("Manage the native Postgres instance for the current project")
25
+
26
+ // ── start ────────────────────────────────────────────────────────────────
27
+ pg.command("start")
28
+ .description("Start Postgres for the current project")
29
+ .action(async () => {
30
+ const config = loadConfig()
31
+ const opts = await pgOpts(config)
32
+ initdb(opts)
33
+ pgStart(opts)
34
+ await waitReady(opts, 10_000)
35
+ console.log(
36
+ `[supatype] Postgres started on port ${opts.port} (data: ${opts.dataDir})`,
37
+ )
38
+ })
39
+
40
+ // ── stop ─────────────────────────────────────────────────────────────────
41
+ pg.command("stop")
42
+ .description("Stop Postgres for the current project")
43
+ .action(async () => {
44
+ const config = loadConfig()
45
+ const opts = await pgOpts(config)
46
+ pgStop(opts)
47
+ console.log("[supatype] Postgres stopped.")
48
+ })
49
+
50
+ // ── reset ─────────────────────────────────────────────────────────────────
51
+ pg.command("reset")
52
+ .description("Stop Postgres, wipe the data directory, and re-initialise")
53
+ .option("--force", "Skip confirmation prompt")
54
+ .action(async (opts: { force: boolean }) => {
55
+ const config = loadConfig()
56
+ const pgOpts_ = await pgOpts(config)
57
+
58
+ if (!opts.force) {
59
+ const readline = await import("node:readline")
60
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
61
+ const answer = await new Promise<string>((resolve) =>
62
+ rl.question(
63
+ `This will DELETE all data in ${pgOpts_.dataDir}. Continue? [y/N] `,
64
+ resolve,
65
+ ),
66
+ )
67
+ rl.close()
68
+ if (answer.toLowerCase() !== "y") {
69
+ console.log("Aborted.")
70
+ return
71
+ }
72
+ }
73
+
74
+ pgStop(pgOpts_)
75
+ if (existsSync(pgOpts_.dataDir)) {
76
+ rmSync(pgOpts_.dataDir, { recursive: true, force: true })
77
+ console.log(`[supatype] Data directory removed: ${pgOpts_.dataDir}`)
78
+ }
79
+ mkdirSync(pgOpts_.dataDir, { recursive: true })
80
+ initdb(pgOpts_)
81
+ pgStart(pgOpts_)
82
+ await waitReady(pgOpts_, 10_000)
83
+ console.log("[supatype] Postgres reset and started.")
84
+ })
85
+
86
+ // ── psql ─────────────────────────────────────────────────────────────────
87
+ pg.command("psql [dbname]")
88
+ .description("Open a psql shell connected to the project database")
89
+ .action(async (dbname?: string) => {
90
+ const config = loadConfig()
91
+ const opts = await pgOpts(config)
92
+ const db = dbname ?? config.project.name
93
+ const psql = join(opts.pgBinDir, "psql")
94
+
95
+ const result = spawnSync(
96
+ psql,
97
+ ["-h", "127.0.0.1", "-p", String(opts.port), "-U", "postgres", db],
98
+ { stdio: "inherit" },
99
+ )
100
+ process.exit(result.status ?? 0)
101
+ })
102
+ }
103
+
104
+ // ---------------------------------------------------------------------------
105
+ // Helper: build PgOptions from config
106
+ // ---------------------------------------------------------------------------
107
+
108
+ async function pgOpts(
109
+ config: ReturnType<typeof loadConfig>,
110
+ ): Promise<import("../postgres-ctl.js").PgOptions> {
111
+ const projectName = config.project.name
112
+ const stateRoot = join(homedir(), ".supatype", "projects", projectName)
113
+ const dataDir = config.database.data_dir ?? join(stateRoot, "data")
114
+ const logsDir = join(stateRoot, "logs")
115
+ mkdirSync(logsDir, { recursive: true })
116
+
117
+ // Resolve pg binary dir.
118
+ const pgCacheDir = await (async () => {
119
+ const override = config.overrides?.postgres_dir
120
+ if (override) return join(override, "bin")
121
+ const { cachePath, currentPlatform, resolveVersionFor } = await import("../binary-cache.js")
122
+ const platform = currentPlatform()
123
+ const version = await resolveVersionFor("postgres", config)
124
+ return join(cachePath("postgres", version), `pg-${version}`, "bin")
125
+ })()
126
+
127
+ return {
128
+ pgBinDir: pgCacheDir,
129
+ dataDir,
130
+ port: 5432,
131
+ logPath: join(logsDir, "postgres.log"),
132
+ }
133
+ }
@@ -0,0 +1,508 @@
1
+ import type { Command } from "commander"
2
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from "node:fs"
3
+ import { resolve, join } from "node:path"
4
+ import { spawnSync } from "node:child_process"
5
+
6
+ // ─── Registration ────────────────────────────────────────────────────────────
7
+
8
+ export function registerPlugins(program: Command): void {
9
+ const cmd = program
10
+ .command("plugins")
11
+ .description("Manage Supatype plugins (field types, composites, providers, widgets)")
12
+
13
+ cmd
14
+ .command("list")
15
+ .description("Show all installed and active plugins")
16
+ .action(() => {
17
+ listPlugins(process.cwd())
18
+ })
19
+
20
+ cmd
21
+ .command("search <query>")
22
+ .description("Search npm registry for Supatype plugins")
23
+ .action(async (query: string) => {
24
+ await searchPlugins(query)
25
+ })
26
+
27
+ cmd
28
+ .command("add <package>")
29
+ .description("Install a plugin package and register it")
30
+ .action((pkg: string) => {
31
+ addPlugin(process.cwd(), pkg)
32
+ })
33
+
34
+ cmd
35
+ .command("remove <package>")
36
+ .description("Uninstall and deregister a plugin")
37
+ .action((pkg: string) => {
38
+ removePlugin(process.cwd(), pkg)
39
+ })
40
+
41
+ cmd
42
+ .command("create")
43
+ .description("Scaffold a new plugin project")
44
+ .option("--type <type>", "Plugin type: field, composite, provider, or widget", "field")
45
+ .option("--name <name>", "Plugin name")
46
+ .action((opts: { type: string; name?: string }) => {
47
+ createPlugin(process.cwd(), opts)
48
+ })
49
+
50
+ cmd
51
+ .command("validate")
52
+ .description("Validate installed plugins for compatibility and correctness")
53
+ .action(() => {
54
+ validatePlugins(process.cwd())
55
+ })
56
+ }
57
+
58
+ // ─── List ────────────────────────────────────────────────────────────────────
59
+
60
+ function listPlugins(cwd: string): void {
61
+ const plugins = discoverInstalledPlugins(cwd)
62
+
63
+ if (plugins.length === 0) {
64
+ console.log("No Supatype plugins installed.")
65
+ console.log("\nSearch for plugins: npx supatype plugins search <query>")
66
+ console.log("Create a plugin: npx supatype plugins create")
67
+ return
68
+ }
69
+
70
+ console.log("Installed plugins:\n")
71
+ console.log(` ${"Name".padEnd(35)} ${"Type".padEnd(14)} ${"Version".padEnd(12)} Status`)
72
+ console.log(` ${"─".repeat(35)} ${"─".repeat(14)} ${"─".repeat(12)} ${"─".repeat(15)}`)
73
+
74
+ for (const p of plugins) {
75
+ const types = p.supatype?.types?.join(", ") ?? "unknown"
76
+ const status = p.compatible ? "active" : "incompatible"
77
+ console.log(` ${p.name.padEnd(35)} ${types.padEnd(14)} ${p.version.padEnd(12)} ${status}`)
78
+ }
79
+ }
80
+
81
+ // ─── Search ──────────────────────────────────────────────────────────────────
82
+
83
+ async function searchPlugins(query: string): Promise<void> {
84
+ console.log(`Searching npm for "${query}" supatype plugins...\n`)
85
+
86
+ try {
87
+ const searchUrl = `https://registry.npmjs.org/-/v1/search?text=supatype-plugin+${encodeURIComponent(query)}&size=20`
88
+ const res = await fetch(searchUrl, {
89
+ signal: AbortSignal.timeout(10_000),
90
+ })
91
+
92
+ if (!res.ok) {
93
+ console.error(`Search failed: ${res.statusText}`)
94
+ return
95
+ }
96
+
97
+ const data = await res.json() as {
98
+ objects: Array<{
99
+ package: {
100
+ name: string
101
+ version: string
102
+ description: string
103
+ keywords: string[]
104
+ }
105
+ score: { final: number }
106
+ }>
107
+ }
108
+
109
+ if (data.objects.length === 0) {
110
+ console.log("No plugins found.")
111
+ console.log("\nTry a different search term, or create your own plugin:")
112
+ console.log(" npx supatype plugins create")
113
+ return
114
+ }
115
+
116
+ console.log(` ${"Package".padEnd(40)} ${"Version".padEnd(12)} Description`)
117
+ console.log(` ${"─".repeat(40)} ${"─".repeat(12)} ${"─".repeat(40)}`)
118
+
119
+ for (const obj of data.objects) {
120
+ const pkg = obj.package
121
+ const desc = (pkg.description ?? "").slice(0, 50)
122
+ console.log(` ${pkg.name.padEnd(40)} ${pkg.version.padEnd(12)} ${desc}`)
123
+ }
124
+
125
+ console.log(`\nInstall: npx supatype plugins add <package-name>`)
126
+ } catch (err) {
127
+ console.error(`Error: ${err instanceof Error ? err.message : "unknown"}`)
128
+ }
129
+ }
130
+
131
+ // ─── Add ─────────────────────────────────────────────────────────────────────
132
+
133
+ function addPlugin(cwd: string, pkg: string): void {
134
+ console.log(`Installing ${pkg}...`)
135
+
136
+ // Detect package manager
137
+ const pm = detectPackageManager(cwd)
138
+ const installCmd = pm === "pnpm" ? ["pnpm", "add", pkg]
139
+ : pm === "yarn" ? ["yarn", "add", pkg]
140
+ : ["npm", "install", pkg]
141
+
142
+ const result = spawnSync(installCmd[0]!, installCmd.slice(1), {
143
+ stdio: "inherit",
144
+ cwd,
145
+ })
146
+
147
+ if (result.status !== 0) {
148
+ console.error(`Failed to install ${pkg}`)
149
+ process.exit(1)
150
+ }
151
+
152
+ // Check compatibility
153
+ const pluginPkgPath = resolvePackageJson(cwd, pkg)
154
+ if (pluginPkgPath) {
155
+ const pkgJson = JSON.parse(readFileSync(pluginPkgPath, "utf8")) as Record<string, unknown>
156
+ const supatype = pkgJson["supatype"] as Record<string, unknown> | undefined
157
+
158
+ if (supatype?.["pluginApi"] !== undefined) {
159
+ const pluginApi = supatype["pluginApi"] as number
160
+ if (pluginApi !== 1) {
161
+ console.warn(`\nWarning: ${pkg} targets plugin API v${pluginApi}, current is v1.`)
162
+ console.warn("The plugin may not work correctly.")
163
+ }
164
+ }
165
+ }
166
+
167
+ console.log(`\n${pkg} installed and registered.`)
168
+ console.log("Run 'npx supatype plugins list' to see active plugins.")
169
+ }
170
+
171
+ // ─── Remove ──────────────────────────────────────────────────────────────────
172
+
173
+ function removePlugin(cwd: string, pkg: string): void {
174
+ // Check if the plugin is referenced in the schema
175
+ // This is a best-effort check
176
+ const schemaFiles = findSchemaFiles(cwd)
177
+ for (const file of schemaFiles) {
178
+ const content = readFileSync(file, "utf8")
179
+ if (content.includes(pkg)) {
180
+ console.warn(`Warning: ${pkg} appears to be referenced in ${file}`)
181
+ console.warn("Removing it may break your schema. Proceed with caution.\n")
182
+ }
183
+ }
184
+
185
+ console.log(`Removing ${pkg}...`)
186
+
187
+ const pm = detectPackageManager(cwd)
188
+ const removeCmd = pm === "pnpm" ? ["pnpm", "remove", pkg]
189
+ : pm === "yarn" ? ["yarn", "remove", pkg]
190
+ : ["npm", "uninstall", pkg]
191
+
192
+ const result = spawnSync(removeCmd[0]!, removeCmd.slice(1), {
193
+ stdio: "inherit",
194
+ cwd,
195
+ })
196
+
197
+ if (result.status !== 0) {
198
+ console.error(`Failed to remove ${pkg}`)
199
+ process.exit(1)
200
+ }
201
+
202
+ console.log(`${pkg} removed.`)
203
+ }
204
+
205
+ // ─── Create ──────────────────────────────────────────────────────────────────
206
+
207
+ function createPlugin(cwd: string, opts: { type: string; name?: string }): void {
208
+ const validTypes = ["field", "composite", "provider", "widget"]
209
+ if (!validTypes.includes(opts.type)) {
210
+ console.error(`Invalid plugin type "${opts.type}". Must be one of: ${validTypes.join(", ")}`)
211
+ process.exit(1)
212
+ }
213
+
214
+ const name = opts.name ?? `supatype-plugin-my-${opts.type}`
215
+ const pluginDir = resolve(cwd, name)
216
+
217
+ if (existsSync(pluginDir)) {
218
+ console.error(`Directory "${name}" already exists.`)
219
+ process.exit(1)
220
+ }
221
+
222
+ mkdirSync(pluginDir, { recursive: true })
223
+ mkdirSync(join(pluginDir, "src"), { recursive: true })
224
+
225
+ // package.json
226
+ writeFileSync(join(pluginDir, "package.json"), JSON.stringify({
227
+ name,
228
+ version: "0.1.0",
229
+ description: `Supatype ${opts.type} plugin`,
230
+ type: "module",
231
+ main: "./dist/index.js",
232
+ types: "./dist/index.d.ts",
233
+ exports: {
234
+ ".": {
235
+ import: "./dist/index.js",
236
+ types: "./dist/index.d.ts",
237
+ },
238
+ },
239
+ keywords: ["supatype", "supatype-plugin"],
240
+ supatype: {
241
+ pluginApi: 1,
242
+ types: [opts.type],
243
+ },
244
+ scripts: {
245
+ build: "tsc",
246
+ typecheck: "tsc --noEmit",
247
+ },
248
+ dependencies: {
249
+ "@supatype/plugin-sdk": "^0.1.0",
250
+ },
251
+ devDependencies: {
252
+ typescript: "^5",
253
+ },
254
+ }, null, 2) + "\n", "utf8")
255
+
256
+ // tsconfig.json
257
+ writeFileSync(join(pluginDir, "tsconfig.json"), JSON.stringify({
258
+ compilerOptions: {
259
+ target: "ES2022",
260
+ module: "Node16",
261
+ moduleResolution: "Node16",
262
+ outDir: "dist",
263
+ rootDir: "src",
264
+ declaration: true,
265
+ strict: true,
266
+ esModuleInterop: true,
267
+ skipLibCheck: true,
268
+ },
269
+ include: ["src"],
270
+ }, null, 2) + "\n", "utf8")
271
+
272
+ // Source file based on type
273
+ const sourceContent = generatePluginTemplate(opts.type, name)
274
+ writeFileSync(join(pluginDir, "src/index.ts"), sourceContent, "utf8")
275
+
276
+ console.log(`\nCreated plugin project: ${name}/\n`)
277
+ console.log(" Files:")
278
+ console.log(` ${name}/package.json`)
279
+ console.log(` ${name}/tsconfig.json`)
280
+ console.log(` ${name}/src/index.ts`)
281
+ console.log(`\n Next steps:`)
282
+ console.log(` cd ${name}`)
283
+ console.log(` npm install`)
284
+ console.log(` npm run build`)
285
+ console.log(` npx supatype plugins validate`)
286
+ }
287
+
288
+ function generatePluginTemplate(type: string, name: string): string {
289
+ switch (type) {
290
+ case "field":
291
+ return `import { defineFieldType } from "@supatype/plugin-sdk"
292
+
293
+ export default defineFieldType({
294
+ name: "${name.replace(/.*plugin-/, "")}",
295
+ pgType: "TEXT",
296
+ tsType: "string",
297
+
298
+ validate(value) {
299
+ if (typeof value !== "string") return "Must be a string"
300
+ return null
301
+ },
302
+
303
+ serialise(value: string) {
304
+ return value
305
+ },
306
+
307
+ deserialise(raw) {
308
+ return String(raw)
309
+ },
310
+
311
+ filterOperators: ["eq", "neq", "in", "like"],
312
+ // widgetPath: "./src/Widget.tsx",
313
+ })
314
+ `
315
+ case "composite":
316
+ return `import { defineComposite } from "@supatype/plugin-sdk"
317
+
318
+ export default defineComposite({
319
+ name: "${name.replace(/.*plugin-/, "")}",
320
+ label: "${name.replace(/.*plugin-/, "").replace(/-/g, " ").replace(/\b\w/g, l => l.toUpperCase())}",
321
+ fields: [
322
+ { name: "example_field", type: "text", required: false },
323
+ ],
324
+ adminGroup: {
325
+ collapsible: true,
326
+ defaultCollapsed: false,
327
+ },
328
+ })
329
+ `
330
+ case "provider":
331
+ return `import { defineProvider, type EmailProvider } from "@supatype/plugin-sdk"
332
+
333
+ interface MyProviderConfig {
334
+ apiKey: string
335
+ region?: string
336
+ }
337
+
338
+ export default defineProvider<MyProviderConfig>({
339
+ name: "${name.replace(/.*plugin-/, "")}",
340
+ category: "email",
341
+ label: "${name.replace(/.*plugin-/, "").replace(/-/g, " ").replace(/\b\w/g, l => l.toUpperCase())}",
342
+ configSchema: {
343
+ apiKey: { type: "string", label: "API Key", required: true, secret: true },
344
+ region: { type: "select", label: "Region", options: ["us-east-1", "eu-west-1"] },
345
+ },
346
+ create(config): EmailProvider {
347
+ return {
348
+ async send(params) {
349
+ // Implement email sending using config.apiKey
350
+ console.log("Sending email to", params.to)
351
+ return { messageId: "msg_" + Date.now() }
352
+ },
353
+ }
354
+ },
355
+ })
356
+ `
357
+ case "widget":
358
+ return `import { defineWidget } from "@supatype/plugin-sdk"
359
+
360
+ export default defineWidget({
361
+ name: "${name.replace(/.*plugin-/, "")}",
362
+ label: "${name.replace(/.*plugin-/, "").replace(/-/g, " ").replace(/\b\w/g, l => l.toUpperCase())}",
363
+ compatibleTypes: ["text", "varchar"],
364
+ componentPath: "./src/Widget.tsx",
365
+ })
366
+ `
367
+ default:
368
+ return `// Unknown plugin type: ${type}\n`
369
+ }
370
+ }
371
+
372
+ // ─── Validate ────────────────────────────────────────────────────────────────
373
+
374
+ function validatePlugins(cwd: string): void {
375
+ const plugins = discoverInstalledPlugins(cwd)
376
+
377
+ if (plugins.length === 0) {
378
+ console.log("No plugins to validate.")
379
+ return
380
+ }
381
+
382
+ let hasErrors = false
383
+
384
+ for (const p of plugins) {
385
+ const issues: string[] = []
386
+
387
+ if (!p.supatype) {
388
+ issues.push("Missing 'supatype' field in package.json")
389
+ } else {
390
+ if (!p.supatype.pluginApi) {
391
+ issues.push("Missing supatype.pluginApi version")
392
+ } else if (p.supatype.pluginApi !== 1) {
393
+ issues.push(`Targets plugin API v${p.supatype.pluginApi}, current is v1`)
394
+ }
395
+ if (!p.supatype.types || p.supatype.types.length === 0) {
396
+ issues.push("Missing supatype.types array")
397
+ }
398
+ }
399
+
400
+ if (issues.length === 0) {
401
+ console.log(` ✓ ${p.name} — valid`)
402
+ } else {
403
+ hasErrors = true
404
+ console.log(` ✗ ${p.name}`)
405
+ for (const issue of issues) {
406
+ console.log(` - ${issue}`)
407
+ }
408
+ }
409
+ }
410
+
411
+ if (hasErrors) {
412
+ console.log("\nSome plugins have issues. Fix them before deploying.")
413
+ process.exit(1)
414
+ } else {
415
+ console.log("\nAll plugins are valid.")
416
+ }
417
+ }
418
+
419
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
420
+
421
+ interface DiscoveredPlugin {
422
+ name: string
423
+ version: string
424
+ supatype?: {
425
+ pluginApi?: number | undefined
426
+ types?: string[] | undefined
427
+ } | undefined
428
+ compatible: boolean
429
+ }
430
+
431
+ function discoverInstalledPlugins(cwd: string): DiscoveredPlugin[] {
432
+ const nodeModulesDir = resolve(cwd, "node_modules")
433
+ if (!existsSync(nodeModulesDir)) return []
434
+
435
+ const plugins: DiscoveredPlugin[] = []
436
+
437
+ // Read package.json to find dependencies
438
+ const pkgJsonPath = resolve(cwd, "package.json")
439
+ if (!existsSync(pkgJsonPath)) return []
440
+
441
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf8")) as Record<string, Record<string, string>>
442
+ const deps = {
443
+ ...pkgJson["dependencies"],
444
+ ...pkgJson["devDependencies"],
445
+ }
446
+
447
+ for (const depName of Object.keys(deps)) {
448
+ const depPkgPath = resolvePackageJson(cwd, depName)
449
+ if (!depPkgPath) continue
450
+
451
+ try {
452
+ const depPkg = JSON.parse(readFileSync(depPkgPath, "utf8")) as Record<string, unknown>
453
+
454
+ // Check if it's a Supatype plugin
455
+ const keywords = (depPkg["keywords"] as string[] | undefined) ?? []
456
+ const supatype = depPkg["supatype"] as Record<string, unknown> | undefined
457
+
458
+ if (keywords.includes("supatype-plugin") || supatype) {
459
+ plugins.push({
460
+ name: depName,
461
+ version: (depPkg["version"] as string) ?? "unknown",
462
+ supatype: supatype ? {
463
+ pluginApi: supatype["pluginApi"] as number | undefined,
464
+ types: supatype["types"] as string[] | undefined,
465
+ } : undefined,
466
+ compatible: !supatype?.["pluginApi"] || supatype["pluginApi"] === 1,
467
+ })
468
+ }
469
+ } catch {
470
+ // Skip packages we can't read
471
+ }
472
+ }
473
+
474
+ return plugins
475
+ }
476
+
477
+ function resolvePackageJson(cwd: string, packageName: string): string | null {
478
+ // Handle scoped packages
479
+ const parts = packageName.startsWith("@") ? packageName.split("/") : [packageName]
480
+ const pkgPath = resolve(cwd, "node_modules", ...parts, "package.json")
481
+ return existsSync(pkgPath) ? pkgPath : null
482
+ }
483
+
484
+ function detectPackageManager(cwd: string): "pnpm" | "yarn" | "npm" {
485
+ if (existsSync(resolve(cwd, "pnpm-lock.yaml"))) return "pnpm"
486
+ if (existsSync(resolve(cwd, "yarn.lock"))) return "yarn"
487
+ return "npm"
488
+ }
489
+
490
+ function findSchemaFiles(cwd: string): string[] {
491
+ const schemaDir = resolve(cwd, "supatype/schema")
492
+ if (!existsSync(schemaDir)) return []
493
+
494
+ const files: string[] = []
495
+ try {
496
+ const { readdirSync, statSync } = require("node:fs") as typeof import("node:fs")
497
+ const entries = readdirSync(schemaDir)
498
+ for (const entry of entries) {
499
+ const fullPath = join(schemaDir, entry)
500
+ if (statSync(fullPath).isFile() && entry.endsWith(".ts")) {
501
+ files.push(fullPath)
502
+ }
503
+ }
504
+ } catch {
505
+ // Ignore errors
506
+ }
507
+ return files
508
+ }
@@ -0,0 +1,17 @@
1
+ import type { Command } from "commander"
2
+ import { ensureEngine } from "../engine-client.js"
3
+
4
+ export function registerPull(program: Command): void {
5
+ program
6
+ .command("pull")
7
+ .description(
8
+ "Introspect an existing Postgres database (deprecated in type-first mode)",
9
+ )
10
+ .action(async () => {
11
+ await ensureEngine()
12
+ throw new Error(
13
+ "The legacy `supatype pull` schema generator has been removed.\n" +
14
+ "Use type-based models with @supatype/types and run `supatype generate`.",
15
+ )
16
+ })
17
+ }